Fraser Speirs Cocoa and Photos

Posted
9 July 2008 @ 3pm

Tagged
Programming, Tech

Add:     

On Switching to Git

Yes, I switched all my source control to git. I don’t have a lot of insight to share so far, but I doubt I’m going to change back.

I work solo, only moving between a desktop and a laptop, so I’m not making huge use of the distributed capability. My previous writing on Git was occasionally mildly criticised for “ignoring” that aspect of Git. I’m not ignoring it, but I lack an understanding of how it really helps me. No, what’s great about Git so far is the power of the tools for everyday operations. I’ll mention the three that come to mind immediately:

git add -i

Interactive adding is a feature that, once tasted, I could never again live without. Clean-as-you-go is an important part of programming any large system which will inevitably have some crusty corners or old code that needs updated. Without the ability to selectively commit diff hunks, cleaning code as you go leaves you with the Tangled Working Copy Problem when you want to commit.

With Git, I work on a feature and feel free to tidy comments, whitespace and adopt the dot accessor as I go. Later, I can go through the file and pick out the feature hunks, commit those, then commit the rest of the tidying-up work.

git bisect

Bisect is an unbelievably useful tool. It helps you to isolate the commit that introduced a bug. You give it a known-good commit, a known-bad commit and it searches through the commits in between, repeatedly checking out versions for you which you then test and tell Git whether that commit was good or bad. I’ve isolated several bugs with this already. It’s fantastic.

git log

The tools that Git gives you to manipulate, search and output the commit logs are very powerful. There are too many options to discuss each here, but I find the ability to format the output with very fine control is particularly useful. With a little care in writing the first line of commit messages, I can use git log to produce a rough set of release notes (I don’t have the exact command line on this machine to copy and paste right now).

speed, etc.

Performance is a feature, and Git is blazingly fast (unless you want to check in very large files). I don’t know if it’s the new-toy effect, or that I’ve been working like crazy, or that interactive commit makes it easier, but I find that I’ve made many more commits than I usually do. This really helps for the odd time that one might, er, accidentally introduce a bug.

What’s Been Hard?

The first thing that was hard was pushing my converted SVN repositories to Github. Not that there was anything wrong with Github, but Git just wanted to eat all my RAM and then some more. This was with the FlickrExport repository of ~1000 commits. It turned out that Git was attempting to repack the repository before transmitting it. It appears that Git does this with no concern for the RAM requirements of doing so (sorry, Git fans, I don’t have a better explanation right now). In the end, I had to run git gc --window-memory=200m by hand to limit RAM usage, and then push it to Github.

With any change comes some unlearning. One of the biggest things is that you do everything in Git in one directory. If I had branches in Subversion, I was used to having them in different paths. In Git, you’re always in the same place. Sometimes, I forgot which branch I was working on. Fortunately, Jon Maddox posted some really useful bash-fu to put the current Git branch in the shell prompt. Problem solved.

I’m slowly getting used to git stash but, this morning, I sat down to my machine and, well, where was all the code I wrote last night? It seemed to be gone! Twenty minutes of poking around later, I remembered that I had done git stash the previous night in order to build a specific tag and had not un-stashed it. Again, problem solved but not without a little panic.

So, in summary, Git’s a great tool. It’s about way more than just being distributed, though. There’s a quieter evolution going on in the more mundane parts of SCM too.


8 Comments

Posted by
Tom Armitage
9 July 2008 @ 4pm

No, I’ve noticed I’m doing more commits.

I think it’s because git makes it much easier to make genuinely atomic commits, thanks to the interactive addition mode (or git add --patch, which is what I usually use).

I tend to branch to add a feature, work on that feature, commiting almost every atomic change as a single commit on my local repo… and once the whole feature is complete, I checkout master, merge in the branch, and then push.

So I’m pushing fairly infrequently - only when I have a complete feature - but I’m commiting more often than normal, because I want the granularity in my local repo.

I’m working with another developer on git, so the granular-commit-versus-infrequent-push pattern works really well… but I think it’s just how the tool wants to be used.

I also commit more often because it’s faster than svn. When things are quick, you do them more. Cf: speeding up unit testing so it’s something you choose not to skip.


Posted by
Michael Dales
9 July 2008 @ 4pm

To follow on from Tom, there’s not only the insentive to check in more frequently, but sometimes you don’t want to push all your minor checks to a central shared repository. With rebase you can coalesce commits too, so you don’t end up spamming everyone with your obsessive commits habit if you don’t want to.


Posted by
Markus Prinz
9 July 2008 @ 5pm

Just FYI: There’s also “git add -p”, which gets you directly into the hunk selection without the menu and everything else. I usually use this more than “add -i”.

You should also take a look at rebasing with the “–interactive” flag. This allows you to reorder, squash or delete commits as you see fit, and can be a very useful tool on occasion. However, this does rewrite the history, so you have to be careful with regards to changes that have already been pushed elsewhere.

Finally, “git cherry-pick” allows you to pick certain commits from another branch and merges them into your current branch. Not sure if you actually need this, but it’s very handy sometimes when you work with other people.

Bonus: You can add aliases to git with “git config –global alias. <the command(s) you want aliased”. So you can, for example, create an alias to see all the changes you’ve staged in the index with “git config –global alias.staged ‘diff –cached’”


Posted by
Markus Prinz
9 July 2008 @ 5pm

Erm. that should be “hyphen hyphen interactive” and “hyphen hyphen global”.


Posted by
Christopher Bowns
9 July 2008 @ 6pm

The Tangled Working Copy Problem has been my primary link sent to developers I know that use SVN. They come back minutes later, going, “Oh my god. That’s incredible.”

CPU History was developed start-to-finish in git, partially as an experiment, and partially to force me to really give it a try. It went quite well for me, I think, and even though I was mostly working on the app by myself, in WiFi-aware locations, not worrying about commits to a central server was fantastic.

git rebase –interactive is a saviour when only a few changes from an experimental branch or commit work out. The Tangled Working Copy Problem did it justice: “…a bit like git commit –amend hopped up on acid and holding a chainsaw”. So much fun to use, and worth learning.


Posted by
Graeme Mathieson
10 July 2008 @ 10am

Following on from the most-frequent-commits, I had an epiphany of sorts in the shower this morning.

In the past, with subversion, I’d tend to create a commit message which contained a summary and a list of bullet points describing those changes. Now, in git, I create a branch named after the summary of what I intend to do, and what would have been each bullet point gets its own commit.

It so happens that, when you git merge back to master, the merge message is virtually identical to the monolithic commit message I used to create. Hence the ‘epiphany’ this morning. :-)


Posted by
Tom Armitage
10 July 2008 @ 11am

In the past, with subversion, I’d tend to create a commit message which contained a summary and a list of bullet points describing those changes. Now, in git, I create a branch named after the summary of what I intend to do, and what would have been each bullet point gets its own commit.

Snap. Glad to know that other people feel the same.


Posted by
Oskar Lissheim-Boethius
17 July 2008 @ 10pm

Snap snap. Git is jist gitting bittir iviry day.