How to migrate code from SVN to GIT without losing commits history?

60,597

Solution 1

Eric Raymond (esr) has created reposurgeon, “a command interpreter for performing tricky editing operations on version-control histories.” The tool includes scripts for various purposes, including cleaning up the results of VCS conversions. Check it out from https://gitlab.com/esr/reposurgeon.

As of version 2.0 it includes support for reading SVN dumpfiles for complete and idiomatic translation to Git, Mercurial, etc.; see http://esr.ibiblio.org/?p=4071 for details. Reposurgeon has been used to convert several large projects to Git, including Emacs whose repository, ESR says, “is large, complex in branch structure, and old enough to have begun life as a CVS repo. That last part matters because some of the ugliest translation problems lurking in the back history of Subversion projects are strange Subversion operation sequences (including combinations of branch copy operations) generated by cvs2svn.”

(The git-svn tool included with Git will handle many Subversion repositories, including branches. It’s pretty commonly used, especially by teams that are in the process of doing a conversion, since it allows Git to behave as a Subversion client. But see ESR’s Don’t do svn-to-git repository conversions with git-svn!, where he discusses the drawbacks to git-svn as a conversion tool.)

Regarding your second question, it isn’t branching where the power of Git is so helpful (though Git is at least as powerful as Subversion in this regard); it’s when it comes to merging those branches that Git shines. Read through the Git Community Book, especially the section in chapter 3 titled “Basic Branching and Merging” and the section in chapter 7 titled “Advanced Merging”.

Solution 2

Since there are already lots of people working with git-svn, I'd say it's very much possible. The following command is pretty well known:

git svn clone -s http://svn/repo

According to the manual (verified locally), this will keep the "trunk, tags and branches".

Solution 3

Update Apr 2014

There is a tool called Svn2Git that does a pretty good job of making this process a bit easier. The documentation on the Github project is pretty good. (Ruby required)

It's worth noting that while git-svn defaults to pulling from just the path you specify, not branches, tags and trunk. Svn2git is the opposite. It will default to looking for a trunk, branches and tags under the path and you should use --nobranches or --notags to tell it not to search for those (though this may nullify the advantages of svn2git).


Once you move to Git, I suggest you move everyone and stay using Git. It's more complicated but the transition will be worth it. Github.com supports accessing the repo using an Subversion client (but you may loose the power of Git branching) and that might be a good stop-gap.

Can I keep my Subversion repo?

When you use the below method to move, all the current commits will remain in the Subversion repo. You may be able to do a one-way sync from the Subversion repo to the Git repo, but going the other way gets very complicated very fast. I would not recommend trying to sync either way and just move everyone one-time.

What's powerful about Git?

Git branching is powerful but it's not all there is to Git. Having a complete history locally means you can do everything you can do with Subversion, but without having to contact the server. Reviewing and searching the history, undoing changes, committing locally, branching locally become immensely faster. Git also compresses it's data, so a Subversion checkout (that includes only the latest revision) ends up being about the same size as a Git checkout (that includes the full history). Also, because data is compressed when transferred, pushing and pulling are much faster as well. Don't just push Git branches, put everything about Git.

How to move a repo using the git svn method.

First, clone the Subversion repo. This might take a while.

git svn clone http://www.example.com/svn-repo/projectA/trunk/

Where http://www.example.com/svn-repo/ is the URL to the Subversion repo and projectA/trunk/ is the path you want to copy into Git.

If you have a standard layout such as projectA/trunk, projectA/branches/ and projectA/tags/ than you can add --stdlayout and clone from a directory up like this

git svn clone --stdlayout http://www.example.com/svn-repo/projectA/  projectA.git-svn

And, if you have a trunk, branches and tags folder named differently then above, you an give git svn clone custom names for each.

git svn clone --trunk my-trunk --branches my-branches --tags my-tags http://www.example.com/svn-repo/projectA/  projectA.git-svn

Once that completes all you have to do is push to the remote git repo with --mirror.

cd projectA.git-svn
git push --mirror [email protected]:Account/projectA.git

At this point you should make your Subversion repo read-only to keep people from trying to commit to an out dated location.

Solution 4

The repo could be converted fully, including tags and all branches using git svn clone.

There's some tweaking neccesary to get the tags correct, see this link for more information.

This topic has been covered here at SO at least once before:
How to import svn branches and tags into git-svn?

Solution 5

Safe and smooth migration approach from Svn to Git is to use SubGit - server-side Git/Svn synchronization tool. One may install SubGit into Subversion repository and continue to use both Subversion and Git simultaneously as long as migration process lasts.

Disclaimer: I'm SubGit developer who happily uses SubGit for half a year already.

Share:
60,597
simo
Author by

simo

I am a software architect, and I like to work on simulation projects, I have worked long time on developing educational applications.

Updated on July 05, 2022

Comments

  • simo
    simo almost 2 years

    I would like to know the recommended way to move our code from a SVN repository to a GIT repository, so that we transition our developers team & start using GIT.

    Can we do the transition and keep all the commits done in the SVN repository ?

    Also, our team is happy with SVN currently, but, they don't know that branching in GIT is much easier than SVN, where can I find a practical example that proves power of GIT in branching ?

  • matbrgz
    matbrgz about 12 years
    Will this approach keep all branches, tags and history? Or just for the checked out branch?
  • aerobiotic
    aerobiotic over 9 years
    The above command is talked about here in detail, including changing tags and branches from svn into git tags and branches: git-scm.com/book/be/v2/Git-and-Other-Systems-Migrating-to-Gi‌​t
  • Admin
    Admin almost 8 years
    Please do not suggest that Atlassian one, it has a lot of issues. It does not work with every layout.
  • pebbles
    pebbles over 7 years
    the documentation says ruby is needed :(
  • Nate
    Nate over 7 years
    Correct. It's a ruby project. I added a note to the answer.
  • crazii
    crazii over 7 years
    the "-s" won't work for me, it just init the repo and fetch nothing. manually fetching does the same. remove "-s" and it rolls.