10

I've been working on moving our 9 projects in one SVN repo over to 9 separate git repos, managed on a server by gitolite then shutting down SVN. Seven of them were easy as they had no branches or tags so on my workstation I was able to do a simple:

git svn clone --stdlayout --no-metadata -A svnauthors.txt svn+ssh://user@host/var/subversion/project tempProject

Then pushed from my workstation to the gitolite sever via:

 git remote add origin ssh://gitolite@host/project
 git push -u origin master

and they have all been working great. Now the final two projects are more difficult, having about 30 tags/branches each. After running the 'git svn clone' as above on one of those projects I see:

$ git branch -a
* master
  remotes/BatchUpload
  remotes/clarify_breadcrumb
  remotes/contact_type
  remotes/contact_upload_improvements
  remotes/file_cabinet
  remotes/mobile
  remotes/summary_tiles
  remotes/summary_updates
  remotes/tags/release-2.1.2
  remotes/tags/release-3.0.1
  remotes/tags/release-3.0.2
  remotes/tags/release-3.0.2c
  remotes/tags/release-3.1.1
  remotes/tags/release-3.1.3
  remotes/tags/release-3.1.4
  remotes/tags/release-3.1.5
  remotes/tags/release-3.1.5.UPDT
  remotes/tags/release-3.2
  remotes/tags/release-3.2.1
  remotes/tags/release-3.2.2.1
  remotes/tags/release-3.2.3
  remotes/tags/release-3.2.4
  remotes/tags/release-3.2.6
  remotes/tags/release-3.2.7
  remotes/tags/release-3.2.7.1
  remotes/trunk
  remotes/user_man_batch_upload
  remotes/user_management

Now how do I go about getting all those tags/branches downloaded to my local workstation so I can push them through gitolite and shutdown the SVN server permanently? Is what I need to do in this guide, doing a 'git checkout -b' for each branch and tag? Should I be using svn2git or some other tool for this?

4 Answers 4

16

A helpful person in #git on freenode irc wrote me a little command to get my tags and branches copied over to Git from SVN:

Push branches:

printf "git push origin "; git show-ref | grep refs/remotes | grep -v '@' | grep -v remotes/tags | perl -ne 'print "refs/remotes/$1:refs/heads/$1 " if m!refs/remotes/(.*)!'; echo

Run command which that prints out

Push tags:

printf "git push origin "; git show-ref | grep refs/remotes/tags | grep -v '@' | perl -ne 'print "refs/remotes/tags/$1:refs/tags/$1 " if m!refs/remotes/tags/(.*)!'; echo

Run command which that prints out

4
  • Oh its output is a command.. thanks i had lot of branches that make me confused... Commented Mar 10, 2014 at 7:37
  • It works for me. But why is there no ootb git command for it? Or, why does git push --all fail for git svn branches?
    – Christian
    Commented Nov 23, 2016 at 14:35
  • There is. See zionyx answer.
    – Christian
    Commented Mar 12, 2018 at 15:46
  • Add a ` (backtick) at the ending and the beginning and the command will just run instead of printing.
    – Brent
    Commented Oct 7, 2021 at 21:55
8

You can list all remote references created when migrating from svn to git: git show-ref (available from git 1.8.2.2). Then decide to push them to origin.

To push all references as branches to origin:

git push origin refs/remotes/*:refs/heads/*

To push tags to origin:

git push origin refs/tags/*:refs/tags/*
-or-
git push origin --tags

You may need to clean up these branches, or perhaps convert some branches to tags before / after the push.

0

They already are on your local workstation. What you see is only references to commits and you can check out local branches tracking them whenever you like.

git branch -a

Show information that's in your local repo, not fetching any data from the remote repository. You got all that information when you did the clone.

So now that we have everything local you only need to push the data to the remote. You can push all your tags to the remote server with:

git push --tags

For each branch you can push it to the repo with:

git push origin remotes/BatchUpload:BatchUpload
3
  • running 'git push --tags' responds with "Everything up to date" and no other output, same with running 'git push origin remotes/*:refs/heads/*' which is supposedly the same thing you listed above? However it doesn't look like any branches or tags exist on the server after running those commands.
    – xref
    Commented Mar 7, 2012 at 23:26
  • Hmm ok, then you probably have to convert them into tags manually or with a script. If you check out for example remotes/tags/release-2.1.2 with "git checkout remotes/tags/release-2.1.2" do you get a detached HEAD? Commented Mar 7, 2012 at 23:29
  • It seems the conversion from svn to git creates the tags as remote references (but with a weird naming), so you probably have to do e.g. "git checkout remotes/tags/xyz; git tag xyz;" for all files xyz in the .git/remotes/tags folder. Once that is done, git push --tags should push them to the remote. And you have to do the same with the branch references, git checkout -b xyz remotes/xyz (or simply git branch xyz remotes/xyz) and git push origin xyz for all files xyz in the .git/remotes folder. When you're done, you can delete the files. Commented Mar 7, 2012 at 23:37
0

Use svn2git. This converts the tags into git annotated tags and these are then pushed properly using git push --tags

1
  • 1
    Can you please elaborate on how to use svn2git to solve OPs specific problem? Commented Feb 16, 2013 at 12:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.