Git seems to be all the rage these days, and, while I was quite reluctant at first, I am here to tell you that I definitely see what all the fuss is about.
As a bit of intro, these are just a few of the reasons I am loving git:
- It’s FAST. Basically 100% local operation, optimized file compares, it’s just plain fast.
- Cheap local branching. Branches are easy to create, and even easier to merge or throw away.
- git-stash. The stash is awesome. It’s basically a local shelf where you can store some changes temporarily, automatically rolling back the working copy to the last commit, and then reapply what’s in the stash at any time. It’s not something I use every day, but it’s cool.
- Truly distributed. Star-schema commit structure supported but not required. History is local, operations are local, and with merging being so easy, working disconnected has never been easier.
- git actually watches your file store. So if you rename/add/modify/delete/move files, it knows, and tracks. No need for IDE integration to solve this headache, and no forgetting to add that new file to svn before breaking the build.
Ok, that’s my short list about how I learned to stop worrying and love git. Now I’ll talk about something that should be of help to a lot of you out there who, like me, already have your projects under svn and want to get more comfortable with git before switching your whole organization to it en masse.
The good news is during your learning/transition time, you can keep your team on svn and use git with the git-svn bridge. Git-svn gives you local git operations with the ability to interact with the master svn repository, merging commit history for you and being almost completely transparent to the rest of the team still using svn.
Without further ado, I present the getting up and running guide to git-svn.
First, clone your svn repo locally (this is the same as svn checkout) with the command: git svn clone -s http://repourl/trunk. This gives you a local git repo with a master branch that has the svn trunk in it. The -s param is telling git that the standard trunk/branches/tags convention is followed.
Yeah, that’s it for setup. Couldn’t be easier. May take some time so sit back and relax, but it’s still WAY faster than a fresh checkout with Tortoise, I guarantee.
Okay, now that we are set up, on to day to day operations. You do work. You commit locally with git commit -m “commit message”. You add new files to git with git add [file] or to add all git add . (period). You do this as often as you like. One of the nicer things about git is that it supports a tight iterative workflow by allowing you these local “micro-commits” without the hassle of integrating each commit.
When you’re ready to get latest from svn you do git svn fetch which will get the current trunk from the server, and then git svn rebase to merge your branch and the latest. You can also do a git merge but I have read that it can cause history problems, and that git svn rebase is the way to go. When you are ready to push your local changes to the central svn repo, you hit git svn dcommit and you’re done.
- create local git repo: git svn clone -s http://svnrepo
- get latest from svn: git svn fetch then git svn rebase
- make local changes: git add and git commit -m “message”
- push to svn: git svn dcommit
repeating steps 2-4 as necessary.
That’s it. Easy as pie.
Many thanks to the community, and especially Aaron Jensen, the .net world’s chief git evangelist, for all the help they’ve given me with git.