Migrating to Git

This weekend our development team migrated to Git. As any other migration this migration introduced some friction at the very beginning. But all in all I think it went rather smooth.

Disclaimer

This post is mainly thought as a self documentation for our own internal use. As we are in a very early adoption phase we do not consider these findings as final and/or recommendations to you. We are looking forward to tweak one or the other setting in our infrastructure as well as change our workflows if needed. I am looking forward to get some feedback from you and I invite you to share your own experiences by leaving a comment.

Self-hosting Git

Previous to Git we were using SVN that was hosted on a Windows 2003 Server machine. Access to this central SVN repository was provided via an Apache Web server. After evaluating a couple of options we decided to leverage the existing infrastructure and self-hosting Git on this very same server and access Git using the HTTP protocol. The advantage being that

  • we do not need to “fumble around” with SSH keys.
  • we already have Apache installed and configured

It turns out that this installation is also speedy enough for our purposes. To e.g. clone a 1.5 GB repository takes less than a minute on our internal network.

On the server we use Git on cygwin. A first attempt with msysgit failed and we were not able to resolve the problem in a timely manner.

Converting the SVN Repository

Our SVN repository had about 30’000 commits. When we tried to convert this repo to Git directly on the server we had to stop this process after about 20 hours or so. Only after moving the whole SVN repo to a fast workstation with loads of RAM and converting it there we managed to do the job in less than 10 hours.

Now we have our full history transferred to GIT which is great.

Git on the Client

On each developer workstation we installed msysgit (currently at version 1.7.0.2). You can download it from here. During the installation we kept all the default settings.

One problem we faced was finding the “correct” the cr/lf setting. The recommended setting with core.autocrlf set to true did cause us problems. As an example:

From a clean master branch we create a story branch and do some changes on it using VS2010. We commit those changes to the story branch and switch back to master. Now git status is telling us that some files have changed. If we analyze those files using e.g. gitk we find that they only differ in a missing end of line character at the end of each file.

As a result we decided to all turn auto cr/lf off with the following command

git config core.autocrlf false

This seems to work for us.

Workflow

The workflow completely changes when migrating from SVN to Git. Based on various posts of Jason Meridth and also his presentation at Code Camp Austin 2010 as well as on the various posts of Derrick Bailey we came up with the following workflow for our team.

  1. To start working with a git repository open a bash shell in the directory where you want to clone the repo to (in Explorer right click on the folder and select “Git Bash here”)

    git clone http://yourname@servername:56789/git/projects/te6.git targetdir

    put your own login name at the place of “yourname”,  and choose your own target directory name at the place of “targetdir”. Also use the correct server name and port where the Apache Webserver is listening.

  2. change into your target directory

    git status

    should now tell you that your repo is clean…

  3. create a branch and checkout to that branch. Name the branch like the story or defect you are working on e.g. story2054

    git branch story2054
    git checkout story2054

    or shorter with only one command

    git checkout –b story2054

  4. start working on the code (e.g. in Visual Studio)
  5. commit your changes into the (local) story branch

    git add –A
    git commit –m “… some commit message …”

  6. continue working…(repeat steps 4 and 5) until you’re done and your code is stable and can be published…
  7. when ready to push your changes switch to your master branch

    git checkout master

  8. and update your local master branch with the latest changes from the server

    git pull origin master:master        (or shorter:   git pull)

  9. switch to the story branch again and rebase the story branch on top of the newest version of master

    git checkout story2054
    git rebase master

  10. merge your story branch into your local master

    git checkout master
    git merge story2054

  11. push changes in your local master to the server

    git push

  12. delete your story branch (since you’re done!!!)

    git branch -d story2054

Backup our daily work

When working with a distributed SCM system like Git developers only push features or fix defects to the origin when they are complete. Thus it can happen that a developer works and commits his changes only locally for days. But what happens in case of e.g. a hard disk crash on his machine? The work of several days would be lost.

We came up with the following solution: each developer receives space on our internal SAN in the form of a network folder. He then maps his g-drive to this personal git network folder.

  1. Switch to the parent folder of the local git repository

    cd ..

  2. clone the local repository to the network folder using the –mirror switch

    git clone –mirror te6 g:/te6Backup.git

    this creates an empty (bare) repository in the target network folder and then clones the local repository into it.

  3. Go back into the local git repository

    cd te6

  4. Add the repository on the backup network folder as a remote (for easier handling)

    git remote add backup g:/te6Backup.git –mirror

  5. continue working… and at the end of the day (or more often if you wish) push your changes to the backup

    git push backup

What to do if

Here I give some possible answers to questions that surfaced in our team during usage

Problem: I want to switch braches without first committing my changes

Solution: Use the stash command

   1: git checkout story2054

   2: //... do some changes

   3: git stash

   4: git checkout master

   5: //... do whatever you want to do

   6: //... and finally go back to the story branch

   7: git checkout story2054

   8: git stash pop

The stash command saves the changes since the last commit and then removes it from the current branch. Later on these changes can be re-applied to the branch by using git stash pop.

Problem: I did some changes (did not yet commit them though) and then realized that I am in the wrong branch

Solution: Use the stash command

   1: //... forgot to switch (e.g. from master) to the story branch

   2: //

   3: //... do some changes ... and realize I'm in the wrong branch

   4: git stash

   5: git checkout story2054

   6: git stash pop

That is: first save the changes you did in the wrong branch. Switch to the correct branch and then apply the saved changes to the current/correct branch.

Helpful References

The superb free eBook http://progit.org/book/

Git cheat sheet of DZone Refcardz

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Gabriel Schenker

Gabriel N. Schenker started his career as a physicist. Following his passion and interest in stars and the universe he chose to write his Ph.D. thesis in astrophysics. Soon after this he dedicated all his time to his second passion, writing and architecting software. Gabriel has since been working for over 12 years as an independent consultant, trainer, and mentor mainly on the .NET platform. He is currently working as chief software architect in a mid-size US company based in Austin TX providing software and services to the pharmaceutical industry as well as to many well-known hospitals and universities throughout the US and in many other countries around the world. Gabriel is passionate about software development and tries to make the life of developers easier by providing guidelines and frameworks to reduce friction in the software development process. Gabriel is married and father of four children and during his spare time likes hiking in the mountains, cooking and reading.
This entry was posted in Git, Workflow. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Henning Anderssen

    Awesome!! Just what I needed.

    Now, only if my company would migrate from TFS to Git

  • Louis Salin

    Henning, I feel for you. Unfortunately, there is a psychological barrier for switching from a $20,000 TFS license to a free Git system…

  • Henning Anderssen

    Louis,

    Because of the way MS if restructuring its partner program, we’re actually looking at Git. We’re losing our Gold partner status as of october because of those changes, and won’t be able to reapply for the new program until next year.
    That means we have to pay for the licenses we already have, which would hopefully make it easier to introduce Git. We’d have to pay probably upwards of 100-200 000 USD for all our licenses, which is gonna suck.
    Reducing that cost by using Git would be great .

  • Bindiya Mansharamani

    I really like the article but I wish you would add more examples for merging and resolving conflicts. Also how do you update to a particular revision number (since they are all guids?)

  • http://erikzaadi.com Erik

    Hey, great article as usual..

    You mentioned that you host the git over http, how did you set up the http inteface? gitosis? gitorious?

    Thanks,

    Erik

  • Doug

    I second the call for info on your HTTP implementation please

  • http://www.lostechies.com/members/gnschenker/default.aspx Gabriel N. Schenker

    @Erik, Doug: I will write another post shortly about this specific topic where I will provide more details.

  • http://kearon.blogspot.com Sean Kearon

    Henning

    Just interested in how much you’re paying for TFS licences? I thought that the server was only about 3000 USD and that CALs were included with MSDN. Is that not the case?

    Cheers

    Sean

  • http://twitter.com/mck_sw mck ☠

    Checkout FINN.no’s story of migrating to Git http://tech.finn.no/given-the-git/

    A number of similarities, and in addition it covers GitHub Flow, maintaining externals forks, and Atlassian Stash.