From Git SCM Wiki
Revision as of 19:58, 31 May 2010 by Andrew-sayers (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Table of contents:


Moving an organisation from SVN to git involves convincing people to unlearn a lot of SVN stuff they're comfortable with, then learn a lot of new git stuff they don't understand. It takes several months of advocacy and education to move even a small team, and productivity will probably go down before it comes back up. This page presents some tools and tips to help migrate an organisation from SVN to git. If you just want to migrate yourself, you might prefer the crash course.

At present, this page concentrates on command-line SVN and git users - contributions are welcome from people that have made the switch in a GUI environment.


A move to git generally starts with advocating it to the rest of your team. Directly recommending git to other people will usually meet with resistance until people are convinced that it will make them happier and more productive. The first step in migrating to git is politely demonstrating how you are happier and more productive using git as an SVN client.

This stage is as much about promoting a healthy level of envy as it is about making a logical argument. Saying "you should get git-svn and bisect that bug" won't have much effect even if you're right, whereas "I bisected your bug over lunch - turns out Tony introduced it in revision 1234" will impress people even if it's no help in that instance.

An SVN user will usually look at almost all of git's features with confusion or disinterest, except for the one thing they immediately identify as their killer app. You should publicly use as many git features as possible, without making a big deal about them, so people will find their own killer app and ignore the rest. People that like git add -p will say so if they spot you using it, and people that like git commit --amend will ask when they hear you talk about uncommitting things. This dumb approach works better than trying to argue why people ought to envy your favourite features because the things people react to are almost never the things you would guess.

Git as an SVN client

It's recommended to move people one at a time to git as an SVN client before you think about git on the server. As well as ensuring you're never overrun by a whole team making newbie errors, git-svn lets you defer decisions about your git architecture until you have a better feel for how git works with your particular team.

Warn people not to use git rebase, because it isn't compatible with git-svn (git svn rebase is fine). For similar reasons, you should also ensure people always use the --squash option to git-merge. Unfortunately, git merge --squash doesn't set a useful commit message, so you have to manually add something like "Merged branch '<from>' to <to>".

You might also want to set the rerere.enabled option in git-config for everyone. When people use git merge without --squash, they can undo it by immediately typing git reset --hard HEAD@{1}, and rerere means that any resolutions they made will be automatically reused when they re-merge with --squash.

You will need to think a lot about how much you should modify your git environment to suit your team, and how much you should educate your team about git. New migraters have no preconceptions about git, so are quite willing to accept that things are different than they were with SVN. But new migraters are also overwhelmed by the little differences (like why their commit numbers are hidden in the body of the commit), and it'll be weeks or months before they're ready to start learning some of git's deeper differences. Consider adding aliases, enabling bash completion for git, and handing out a git-svn cheatsheet (.doc). Many excellent guides are also available for people that prefer to learn by reading.

Git on the server

Once your team has largely migrated to git-svn, you've developed a migration plan for all your scripts, and you've developed workarounds for the people that really don't want to switch, you can move to git on the server. This is the last chance for your team to unlearn old SVN stuff - e.g. to remove SVN-compatibility aliases created during the move to git-svn.

Most of the issues you face during this stage will be specific to your team - do you host your code on GitHub or roll your own with gitosis? Do you try to keep all your old post-commit hooks, or convert them to post-receive hooks? A general guide such as this can't help much with these issues.

Philosophical differences

One of the hardest issues in migrating from SVN to git is as subtle as it is pervasive: the change of focus from the lines in your commit graph to the points.

SVN users focus on branches as the centre of their development history, and see commits as these funny little things that punctuate the progress of their branches. But git users focus on commits (or even trees) as the centre of their history, and see branches as just one of many handy labels to track them.

The distinction is subtle, but it affects a lot of the expectations people have. For example, SVN users like to think of a commit as being "on a branch", meaning that it marks an event in the lifetime of one SVN directory. Whereas git users would say a commit is "reachable from the tip of zero or more branches", meaning that it informs you about the state of various other commits.

It's very hard to make SVN users grok this change of emphasis. It can help to explain how git internally stores whole trees instead of just deltas (so you can e.g. diff two arbitrary commits without examining the ones in between). It can also help to describe SVN as using "directory-based branches", compared to git's "label-based branches". Using different names makes it easier to explain that you can do everything with a label-branch that you could do with a directory-branch, but that you can also do other things like making commits that aren't labelled by any branch. This will still only get you part of the way - if you find something better, please contribute to this guide!

See also

This page was originally based on a thread on the git mailing list.

Personal tools