Recently a coworker of mine told me he was happy with SVN, and had been for years. Why should he and his team switch to git if they were productive and happy? I posted this to our internal message board, but I think the answer is broad enough to merit posting here on my blog. Enjoy. Which vcs do you use, and why do you like it? Are there any ex-git users out there who prefer something else?
Just my $0.02, but I hear this concern from satisfied svn users a lot. I used to be one myself. There is a compelling answer, but unfortunately I don’t know how to articulate it. Almost without exception, every svn user I have seen switch to git has slapped their forehead and said, “My goodness, why didn’t you tell me the world wasn’t flat?!?”
I think the problem is threefold. First, git was very hard to use when it first came out, which turned a lot of people off. Second, it was kind of a hipster trendy thing, which turned even more people off. But most importantly, every advantage that git provides over svn is something that svn users have learned to live without, and so when you say “git can do this”, svn users say “Yeah, but we don’t need or use that.”
You need those things. They will make you happy. Take it on faith until you begin to enjoy the fruits yourself. :-) Git offers a ton of incredible things over svn. I’ll mention just my top three favorites.
First, you can branch in git, and you don’t do that in svn. I know what you’re thinking: you CAN branch in svn. That’s not what I said. I said you DON’T. Because it’s such a pain to do and merging is such a nightmare, I’ve only ever met one team that used branching heavily in svn. They were a company with 500+ developers, however, and had IT staff on hand full-time to enforce the engineering discipline to keep their branches under control, and once a week the dev team stopped and had a “merge day” when branches were folded back into the mainline. In contrast, git’s merging tools are so freakishly powerful that branching becomes nearly a zero-cost operation. In the past week, I have created or worked in not less than ten different branches across three projects. Each feature, each bugfix, isolated in its own branch. All of the code is changed and updated, and pushed up to the server. Some of the branches were merged immediately, some are still awaiting QA testing before it can be deployed. So that’s feature number one: Git makes branching and merging so easy that you’ll use it all the time.
Second, and this is a huge implication, because branching and merging are so easy, you no longer have this problem where everybody is syncing and merging with trunk, where every feature change gets deployed to production as soon as you finish it. You might be tempted to lump this in with my first point, but as somebody who occasionally gets dragged back into svn from git, this is totally a separate concern. You can’t do exploratory branches easily, so you don’t do them. With git, you can fork a branch, make some changes, forget about the branch, go back and work in master (git’s word for “trunk”) for a month, then come back to your exploratory branch and type “rebase” and it will MOVE your changes forward in time, updating the trunk and then “playing your changes back” over the new trunk, making it as though you had forked yesterday instead of a month ago. If you’ve ever made a bugfix and then had to hold off pushing your commit because QA was still testing trunk for a deploy, you need to switch to git.
Thirdly, git is distributed. Everybody gets the obvious implication of this, that you could be pushing your code to multiple servers. And big deal, right? You could be backing up your svn repo just as easily. But everybody misses the subtle implications of this, which are earth-shattering: one, what you call your sandbox, git consider to be just another repo. Which means you can be on a plane with no internet access, and you can checkout old revisions, commit code to a feature branch, fix a bug in master, and start two new exploratory branches, all without being connected to the main repo. What svn calls a commit, git calls a push, and it syncs your “local” repo with the remote one. (What git calls a commit is just storing a change from your sandbox to your local repo database to be pushed later.) And two, because you have a full copy of the local repo in your sandbox, you can play amazing games with the commit history. Checked in a file you shouldn’t have? Go back into your repo’s history and remove it from the commit stream before you push it to the server. Wrote the wrong bug number on your checkin? Amend your commit message. Pulled down latest code only to discover that 12 files are in conflict and you just want the version from two days ago? You can jump over to that commit and grab them.
That’s my $0.02, which I guess on a per-word basis appears to be quite the bargain. Sorry. TL;DR: git takes your version control game to a whole new level that you didn’t even know existed. If you’re happy with svn, you don’t NEED to use git. But if you want to STAY happy with svn, trust me: don’t ever switch. You WON’T be able to go back.
(Well, actually, you will. git has a svn emulation module that lets you have a git repo locally and push commits to a svn server. It still has the problem of “the dev team are all committing to trunk”, but features 1 and 3, of branching and distributing, still shine through. It makes working with subversion… bearable.)