My Site

Moving over to Git

So you've seen that Rails/Capistrano now natively supports Git? You've bearing hearing all the hype about it but don't really know what it is, how to use it, or how to install it. But like most, you know it was invented by that Linus guy that invented Linux, so it can't be all bad. Well then come jump on board!

What is Git?

Git is a distributed version control system (you can skip this bit if you've used mercurial). If you can imagine SVN, but without the need to check back to a central server you're probably about half way there. Without the concept of a central server, it means I can check out code and develop until my heart is content on my laptop, while in transit, without an internet connection. While SVN wouldn't stop me from doing this it did prevent me from committing any check-ins during this period. That's problematic if I've a particularly long trip (on a plane) as I then end up checking in a large chunk of functionality in one single big commit and I wont be able to undo just a portion of it. It's particularly good with a distributed team (which often happens these days with coders all around the world) as I can check out, check in, and not fear that I'm occasionally breaking someone else's code until it comes time to bundle up all my work and submit it to the core code base. I get all the benefits of tiny atomic commits so that I can easily undo just a small change, and none of the failings of running your own SVN repository as a silo.

That's because, while there is no dependency on a central server, you can commit and checkout to and from a central Git server whenever you like. Even better, you can commit and checkout directly with a colleague or any other user who has pulled a copy of the code and bypass the server altogether (e.g., two remote developers working on the same code who don't want to disrupt the central repo just yet).

Installing Git on linux

If you're on a linux distro you may very well find you already have Git installed. If you don't, it should be available as a package:

sudo yum install git-core

Installing Git on Mac OS X (or installing Git from source)

For the Mac OS X users out there it will probably be easiest to install it from source. The following commands should get you there:

tar xjvf git-1.5.4.tar.bz2
cd git-1.5.4
sudo make install
cd ..
sudo tar xjvf git-manpages-1.5.4.tar.bz2 -C /usr/local/share/man

If you're so inclined, now would probably be a good time to change to default settings to get coloured output and a whole host of nifty shortcuts and improvements. Check out this git quickstart guide for a list of them

Using Git

If you've used mercurial before this should all seem like second nature. If you're used to SVN, then there is only a minor learning curve. The thing you need to keep in mind is that your local working copy of the checkout, is also a server. So when you do a commit, you are really only saving it to your local machine. Likewise, if you did a checkout, you're doing it on the local machine. If you want to update your local copy from a remote server like you would in SVN you need to pull, to send your updates somewhere else you need to push. Let's quickly go through how you'd checkout a working copy, and make some changes to it. Firstly, you need to create a local clone of the repository:

git clone git:// my_local_dir

This will create a new directory called mylocaldir and pull in a copy of the the repository from the remote server. Next you make some changes locally to the files and try to check them in:

cd my_local_dir
git commit -a

This will commit all local changes, to your local server. Now it's time to push those changes back upstream:

git push

But what if we want to check if there are any changes from the remote server? Well we just pull them in:

git pull

Creating a remote Git repository

That's all well and good if you've got a repository already setup to check out from. But what if you want to create your own. Well you can go with a hosted option from providers like GitHub or Gitorious or if you are the DIY type, host your own. Go to the remote server location where you want to have your repo and:

mkdir myrepo.git
cd myrepo.git
git --bare init

Now obviously we've created a directory and initialised a new Git repository within it here. What the bare option does is inform Git that this won't be a working copy. We don't need to waste disk with the actual files here, we just need to version control information and the changes (delta) between files.

You've probably got a local codebase that you now want to check into your brand new remote repo so you can code away, check in, remotely back it up, and have others contribute. So locally:

cd myapp
git init
git add .
git commit -m "Initial check in"

What we've done here is initialise the local Git repository in our myapp directory, add all the files in, and then commit the new files. All that is left to do is let this repository know about a remote host, and then push our changes there:

git remote add origin ssh://
git push origin master

This lets the local repository know to treat the remote server as the origin of the source, followed by a command to push our local master copy up to the origin server. From now on, you can send any changes to the server with a simple:

git push

And that's it! Following shortly, how to port your existing SVN projects over and/or peacefully let Git and SVN projects co-exist.

Glenn Gillen

I'm an advisor to, and investor in, early-stage tech startups. Beyond that I'm an incredibly fortunate husband and father. I'm currently a Product Manager at HashiCorp. Previously at AWS and Heroku.

Working on a developer-facing tool or service? Thinking about starting one? Email me and let me know