As a programmer I've used all kinds of source control management solutions. From Microsoft Visual Sourcesafe, to CVS, to Subversion (SVN). I even wrote a 60 page whitepaper detailing the use of Apache, ColdFusion, and Subversion in a development environment. And I've been known to blog about source control from time to time.
Recently I began reviewing the Git source control system for the startup I'm working with. It was a good opportunity to investigate solutions beyond Subversion since there wasn't any previous repositories or "code baggage" to worry about. I began my review by talking with Russ Johnson, the first person to ever recommend Git to me. Russ highly recommends Git and was more than willing to answer my dumb questions and discuss what he saw as advantages when using Git over Subversion. For my thoughts on Git continue reading after the break. Or, if you want to go ahead and download my Git cheat sheet click, here.
The distributed nature of Git
One of Russ' favorite features of Git was its distributed nature. Unlike with Subversion you don't have to create and manage a master Subversion server. You can certainly set up your Git solution to work with a master server - Git calls this the origin server - but it's not a requirement. I highly underestimated the coolness of this feature. Having installed Git on three MacBook Pro's and one Ubuntu (Karmic) origin server, I've had the chance to test the "remoteness" of Git. Wow, it is one of my favorite features too. I like how I can fetch updates from the origin server and merge those updates into my local repository on my own time. Imagine you're at the office on Friday afternoon and your awesome boss says it's time to go home. You - being an equally awesome employee - are going to do some programming over the weekend. So you fetch the latest updates from your team via the origin server and you promptly pack up your stuff and go home. On Saturday you open your laptop and merge the origin changes into your local system and you start programming. Too cool. Other situations where Git's distributed nature come in handy include travel. Most airlines don't have Wi-Fi on their planes yet so you're about as "offine" as it gets when you're in the air. With Git, that doesn't matter. You can still get your work done. You write your code or work on documents, whatever you are tracking with Git. You even commit all your changes to your local Git repository so you can synch them later with the remote Git server.
Branching and merging is easier
With Git, branching and merging is easier. Creating branches and merging code is a matter of running a few simple commands. Sure Subversion has similar commands but Subversion branches feel more weighty. I always felt beholden to Subversion branches and never quite enjoyed the process of merging changes from one branch to another. Git makes this super easy. In fact, Git users are encouraged to create branches for the smallest changes! Another interesting bit about Git is everything is considered a branch. There's no exact concept of a trunk in Git like there is in Subversion. Git does have the master branch which serves the same general purpose, but it doesn't feel the same as a Subversion trunk. Switching between branches is also very easy and an inexpensive task. All in all Git branching and merging feels more polished.
Other cool features
Three other cool features are patching (hunking), stashing, and bisecting. Patching allows you to choose which specific changes in a single file you want to commit. As I code I often find small things I want to fix that aren't related to the larger task I'm taking care of. Wouldn't it be nice if you could commit only related changes together? It makes reviewing code problems and communicating with other developers (through the Git log) much more productive. In Git, the git add -p command allows you to do this. To accomplish the same thing in Subversion you had to remove unrelated changes and perform your commit. Then you had to read the changes you removed and perform another commit. It was tedious.
Stashing is another great git feature. Pretend you're working on a branch called "version2." You're well into the development of version 2 and you have a bunch of changes that haven't been committed to branch version2. Meanwhile a user finds a bug with version 1 and you need to fix it fast. In the Subversion world many developers would simply check their version 2 work into the version2 branch and switch to the trunk to start fixing the bug in version 1. But doing this sucks as you've munged your commit tree with a commit that wasn't really intended. Subversion does have a few things to address this scenario but they feel like workarounds. In Git, you can simply stash all the uncommitted work you've done and save it for later. When you run the git stash save command Git saves your uncommitted work and reverts the branch you're in to the latest commit. Now that you have a clean version2 branch you can safely switch to your master branch and knock out that bug. When you're done fixing the bug you can switch back to the version2 branch and issue the git stash pop command to replay all your changes. You're now right back where you started. Sweet!
The last cool feature I want to discuss is bisecting. This is way cool. In Git, bisecting a repository allows you to find where a bad commit was made. Say you have a bug in your code but you're not sure where the bug originated and which commit introduced it. You can begin a bisecting session and Git will progressively check out bisected commits from your repository. Your working copy changes with the bisection allowing you to test your site or app. If you find the bug present in the commit Git checked out you go back to Git and answer "yes," this commit has my bug. If it doesn't you answer no. Git will bisect your commit tree again and you go and check your site or app again. After a few iterations of this process Git will tell you which commit it believes introduced your bug. You then switch to that commit and begin to audit your code. I've only used this feature in simulations but I can see how it could be a lifesaver.
It's all gravy now
I've become a big fan of Git. It simply fits into my workflow like a nice pair of shoes. But Git is still new to me and I have a lot more to learn. Likewise I forget some commands from time to time so I created a Git cheat sheet to use as a reference. If you'd like to download my Git cheat sheet (PDF) - which includes most of the common, everyday commands, just click here. I also recommend checking out this other cheat sheet that's more fancy than mine. Finally, if you have questions about how Git works or you'd like to let others know why you like Git feel free to post a comment. I'd love to hear from you.
1 related blog entries
- Git Workflows: Archiving Old Branches (June 7, 2011)