Acclimating to Git

Bookmark and Share

I’ve been watching git with interest for a while now, because the concept of a distributed version control system — one where you don’t need to contact a central server to make a record of your recent changes — would go pretty well with a lot of the things I use version control for. (Not just source code, but managing homework and papers that I type up in LaTeX) I’ve been stuck on Subversion for a while, mostly because I have a nifty GUI for Subversion for which no worthy equivalent exists for Git, but lately I realize I’ve been using the standard command-line client most of the time. So why not take the opportunity to switch over to git? (Plus, I wanted to get a nifty new toy to play with ;-)

One thing about git which took a couple days to really figure out is the idea of having a repository in every working copy. They say this in all the documentation but somehow I never quite got it until trying it, so I’ll repeat: a git working copy is like an SVN working copy with its own built-in, private repository. In SVN, when you commit, your changes got to a remote server (or somewhere else on the filesystem); in git, when you commit, your changes go to the .git subdirectory of your working copy. When you think about it like that, git is kind of like a version of SVN that just makes it really easy to keep several repositories in sync.

In a centralized VCS (version control system) like Subversion, the repository really fills two roles: it keeps track of the “official” history of your work, and (if you make it public) it also provides an outlet to share that work (and its history) with the world. Git, on the other hand, separates those two functions: the repository that lives in your working copy is what keeps track of your history, and a centralized repository on some server is nothing more than a mirror that the public can access. This means that if you don’t need to or don’t want to share your work with anyone else, there’s no need to have a repository on a remote server at all.

One thing I really like about git is the ease of branching. To some extent, this is a consequence of the local-repository idea, because branching becomes just an operation on the working copy — actually, on the local repository within the working copy — still, the fact is that running VCS commands that modify the working copy is way easier than running commands that modify a remote repository, which is what you have to do in SVN to create a versioned branch. When I was on Subversion, creating a branch was a pain in the butt (doubly so because my internet access was pretty flaky back then), so I rarely ever did it, but in git I can just run

git checkout -b happybranching

and presto, a branch. It’s no problem to create different branches, switch between them, and incorporate the changes back into the master branch if I decide I like them, all without anything going off-computer.

Another thing I like is the tagging philosophy, in which a tag is basically just a nice-looking name for a particular revision. In retrospect, the tagging model in Subversion, in which tags were just folders in the repository, wasn’t so great because, again, you had modify the repository directly to do it. Not to mention, you could easily modify the contents of a tag folder in Subversion, which doesn’t make sense. Actually, I guess it could, but I don’t feel like I’m missing anything by not being able to modify the contents of a tag.

These days, of course, a lot of people (including myself) do work on multiple computers. When you do this, it’s really nice if you can keep those computers in sync with each other easily. This is one point where I think Subversion, or at least the centralized philosophy of Subversion, has the advantage over git. Having one centralized server gives you one single place where you can always expect to find the most current copy of your work. Keeping everything in sync is just a matter of syncing your computer to the server,

svn update

every time you start working, and syncing the server to your computer

svn commit

every time you finish working on that computer. Then when you switch to another computer, another svn update gets you ready to pick up right where you left off; no need to, say, remember which other computer’s local repository had the latest copy of your work. Of course, git can do this too, typically using a bare repository. Still, the power of distributed version control is sort of wasted when you’re the only person working on a project and you’re doing it on multiple computers.

All things considered (or at least, all things I can consider after about 3 days), I like git. It can basically do what Subversion does, but it can also do things differently than Subversion, and I can definitely see myself using different workflows for different projects. Besides, git is able to interoperate with Subversion; using the git svn commands, git can check out from and commit to a Subversion repository, so I can get used to the git client and workflow without abandoning Subversion entirely, just so it’s easy to switch back if I want to.