Clone … What could possibly go wrong?
If you’re a coder, you’ve already heard about distributed version control systems (DVCS) and git in particular. I was content, almost complacent, in my usage of subversion to manage my source code, both for personal projects and at work. Subversion was intended as a “compelling” upgrade for CVS, and the next version control system (VCS) I used had to be equally as compelling. I think git has cemented itself as the preferred DVCS within the Open Source community. No doubt services like github have helped popularize it over bzr and mercurial. I’ve switched over to git over the course of the last month, these are some of my motivations and a record of what I learned along the way.
Why not stick with Subversion?
Subversion, since it has been around longer, enjoys better support in text editors, IDEs, and GUI front ends . It’s easy to setup a repository that you can share with a collaborator, or sign up for a hosted repository. It’s killer feature is the ability to fetch parts of a remote repository via the svn:externals feature. I’d used that extensively to organize projects and track 3rd party software such as Pressflow or Zend Framework. Git does not have an alternative as straightforward as svn:externals.
Over the last year I noticed that I wasn’t committing code as often as I should be, resulting in a lot of conflicts when I did try to do an inevitably large commit. Ideally, I would want to have a lot of frequent and small commits. When I tried to use branching and merging in Subversion, it was tedious and felt that one misstep would result in lost work or a bad merge. Even though merge tracking was added to subversion in version 1.5, my early exposure to it has caused me to avoid it like the plague. That’s a shame, because branching and merging is very useful for keeping new features from mixing in with mainline development until it is ready. Finally, at work we’d moved to a repo hosted on assembla.com and lost some useful pre-commit hooks for keeping PHP syntax errors and debugging code from being committed. A year later, it seems our group is the only ones still using this repo so I’ve been contemplating moving back to one under our control.
I know one option would be to use git-svn to use git locally and somehow push changes to the subversion repo, but I preferred to ditch the latter wholesale and not worry about having two systems in place. There’s enough to keep track of as it is and version control should simplify things, not complicate it.
Git has quite a learning curve
Understanding the terminology of git is confusing, particularly if you’re used to working with subversion. It’s not just your working copy and the repository anymore – now there’s a stash, the index where your commits are staged, the local repository, and the remote (or origin) repository. A good front-end can really help, if you are on a Mac I’d recommend using one of the active forks of GitX. This interactive cheat sheet also helped me to figure out git and what some of its commands do (Hint: click on the colored boxes). I think you’d be better off if you could somehow forget everything you ever learned about subversion.
You’re work flow has to change too, since you now have to remember to push, that is send, your commits to a shared repository, and also fetch and merge (or pull) the commits that your colleagues have pushed to a shared repository. A good front-end or first-class support in your editor/IDE of choice really helps here.
Git is useful once muscle memory kicks in
Once we initialized our repository and started committing changes, it didn’t take more than a day to get comfortable with using git. There were a couple instances where I was jumping to my co-workers cubicle to figure out how to send my changes to him, or to learn about the difference between git’s fetch and pull commands. Google and StackOverflow were most helpful in finding answers to our questions and explaining the commands we needed to invoke.
I’ve found myself committing again quite frequently, after finishing small and discrete fixes and features. In the long run, having a more fine-grained record of changes will be useful. As promised, git also makes branching and merging extraordinarily easy. Its trivial to be working on a new feature branch, switch to the mainline development branch to commit a minor fix, the switch back to your branch and merge in the fixes you just committed. It takes just a handful of commands and you don’t need to worry about version numbers or direction, it just happens. I’ve found myself doing that 2 or 3 times during the day without worrying that I was one command line switch away from total devastation. Another cool feature we found in git, via the GitX front end, is the ability to stage and commit just some of the changes within a file.
If you’ve recently switched, or are contemplating a switch, to using git, please share your thoughts and experiences below. In the near future, I’ll be sharing the details of the work flow we’ve established and how to take advantage of git’s hooks to do useful things before and after commits.