
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.