How to git clone an SVN repository where all branc

2019-05-30 00:40发布

问题:

My SVN structure is like this:

/
|-- Branch1
|-- Branch2
|-- Branch3
...

How can I clone this into a git repository preserving the branches (i.e. not flat history)?

Bonus question: How to clone only a subset of the SVN branches into a new git repository?

回答1:

I believe that in SVN branches are just folders, its just a convention. Git actually works with branches. With this the approach becomes easier.

As you need to fetch the data from SVN repository you will need to create remote for it. From the structure I see that you need to create Branch 1 to 3 in your git repository.

Create Git repository.

git init
git config --local --add user.name <Username>
git config --local --add user.email <email>
echo "MASTER" > master
git add master
git commit -m "Dummy commit"

Create Remote of your SVN branch.

git config --add svn-remote.<BranchName>.url <SVN URL>
git config --add svn-remote.<BranchName>.fetch :refs/remotes/<RemoteName>

for Branch1:

git config --add svn-remote.branch1.url https://svnhost/svn/MyRepo/Branch1
git config --add svn-remote.branch1.fetch :refs/remotes/branch1_remote

Fetch SVN data of branch1:

git svn fetch branch1

Repeat this for other two branches Branch2 and Branch3.

You can stop right here if you are only trying to clone You need not proceed further unless you want to work with Git repository. Google on git subtree to know why this could be correct solution in your case.

To Create Subtree:

Find last commit id:
git checkout remotes/branch1_remote
git svn log -n 1 --show-commit --oneline
Output: 734713bc047d87bf7eac9674765ae793478c50d3 (This is yout LastCommitId value)

Create subtree in mainline master branch:
git checkout master
git subtree add --prefix=Branch1 <LastCommitId>

For you bonus question: Try this

git svn clone https://svnhost/svn/MyRepo/Branch2

This one is simple, the other way is to follow the above steps and instead of creating three remotes in same repository create new repository everytime and then add your branch's remote. Based on your requirement you could google out different ways.



回答2:

Clone just the first few revisions of only trunk before any branches were created. I'm assuming that your branches were not created before revision 5. I'm also assuming that your trunk folder is named trunk. Adjust accordingly. Hopefully you have already created an authors file as well. This will set up the local repository.

$ git svn clone https://svn.example.com/myrepo --authors-file=authors.txt -T trunk -r 1:5 myrepo

Next, add branches lines in myrepo/.git/config similar to this:

[svn-remote "svn"]
    url = https://svn.example.com/myrepo
    fetch = trunk:refs/remotes/origin/trunk
    branches = branches/Branch1:refs/remotes/origin/*
    branches = branches/Branch2:refs/remotes/origin/*
    branches = branches/Branch3:refs/remotes/origin/*

If your branches follow a naming convention that can be matched with a pattern like in your example, you could do this:

[svn-remote "svn"]
    url = https://svn.example.com/myrepo
    fetch = trunk:refs/remotes/origin/trunk
    branches = branches/Branch*:refs/remotes/origin/*

Some people recommend deleting myrepo/.git/svn/.metadata after making these edits. I don't know if that is necessary or not.

Now you just fetch the remaining revisions. Git svn will work out the branch structure and do the right thing. Any branches that don't match one of the branches lines will be ignored.

$ cd myrepo
$ git svn fetch

Once it is complete, you can check that the branches were created with this command.

$ git branch -r
  origin/Branch1
  origin/Branch2
  origin/Branch3
  origin/trunk