For the last week I have been experimenting with Git. Git is a relatively new source code management tool that is set apart from the SCM’s you are likely to be familiar with because it is distributed rather than centralised. I’m not going to sit here and harp on about all the reasons why this approach has merit when there are plenty of resources available that will do a much better job:
Nor am I going to teach you the fundamentals of how git works and how to use it, again for similar reasons:
Today I just want to talk about what I had to do to start using Git effectively for my work on Fluent NHibernate (which is hosted in Subversion on Google Code). Basically, I wanted a local repository for Fluent NH. I wanted to be able to commit smaller chunks of work to the local repository and then commit to SVN once I was happy with it. I also wanted to be able to branch, rollback, view history, etc all without touching the SVN repository. Git gave me these capabilities.
Here are the steps I followed to get up and running with Git and a Google Code hosted project:
- Installed msysgit. I installed version 1.5.5 because I heard that the later versions had problems with git-svn (the tool for bridging Git and Subversion). I have no idea if this is actually the case. When installing, I chose the option that added git to my path environment variable. This allowed me to use Git in the windows command line, but there was a hitch. Every time I ran git from the windows command line, it would close the command line. I followed the fix here here to solve it.
- Configure git. I set up a SSH key and my details, as described here. I also set the autocrlf option to false – this seems to minimise problems with line endings. To do so I used the command:
git config –global core.autocrlf false
- Used git-svn to create a local clone. Initially I ran into some difficulty because I pulled the repository down using http – this caused problems later when I tried to commit and could not authenticate properly. Using https when cloning the repository fixed the problem. Another issue to be aware of when using git-svn is that unlike the rest of Git, git-svn is very slow. I had to leave git-svn working away for over 20 minutes when I first pulled down my branch of Fluent NHibernate. Later I learned that you can tell git-svn to clone a revision rather than the entire repository, so I used this functionality when I pulled the second time (using https instead of http). The command I used was:
git svn clone https://fluent-nhibernate.googlecode.com/svn/branches/pb-rewrite --username "paul.batum" –r234
My Google Code username is “paul.batum”. I was prompted for my password the first time, but then Git seemed to remember it from then on. The –r234 switch specified a particular revision to get. If I was prepared to wait, I would have omitted the flag and pulled the entire history into my local repository, but patience got the better of me.
- Added a .gitignore file to specify which types of files should not be tracked by Git. I grabbed the .gitignore file from an a .NET project hosted in GitHub called Machine. I then made a few modifications, copied into my new repository and checked it in:
git add .gitignore
git commit –m “Added ignore file”
You can view my ignore file here.
- Worked with the local repository. My git repository was ready to use. I worked on the Fluent NH code for a while, using the git gui (run simply by using the git gui command) to make small commits.
- Rebased my local repository against the SVN repository. Before I commit back to the SVN repository, I need to merge any changes that have been made since I cloned the repository. Git offers merge functionality, but it also offers something slightly different called a rebase. In a nutshell, the difference between a merge and a rebase is that a merge will interleave your changes with everyone else’s changes. A rebase will take each of your changes, and apply them all sequentially after everyone else’s changes. You can read a better explanation here. The rebase command was straightforward:
git svn rebase
- Checked the state of my repository. I wanted to see what my repository looked like after the rebase. A commit viewer called gitk is installed as part of msysgit, to run it with all branches displayed the command is:
- Commited my changes to the SVN repository. With the rebase complete, my local commits were ready to be pushed to the main repository on Google Code. To commit my changes back to SVN, I ran the following command:
git svn dcommit –-username paul.batum
The dcommit command pushes my commits to the SVN repository one at a time. This means that the rich history that was created locally by my small commits is preserved in the SVN history. There are some options for “squashing” all of the local changes so that they are all represented by a single commit, but I am yet to explore those.
I am still a total Git newbie. But hopefully this guide will save some hair pulling for other windows developers that decide to learn git by using it locally for their SVN hosted projects.