Tag Archives: git


As you may have guessed from the name, ShortcutFoo lets you master keyboard shortcuts in various apps including Vim, Emacs, Eclipse, Git, Excel, Visual Studio and many more. It first lets you learn the shortcuts, then presents drills and a practice mode to master them. So you actually use the shortcuts, instead of just memorizing them. Clever idea.

The downside is, only a few shortcut bundles in each app is free. To unlock the rest, you’ll have to pay a one-time fee of $8.99. That’s too high. I may subscribe one day if I happened to learn Emacs or some crazy text editor other than Vim. But no thanks for now.

Why the ‘Foo’ anyway? Shouldn’t it have been ‘Fu’?

Gmail with Thunderbird

I’d been dealing with my work-related mail with Mozilla’s Thunderbird for a few weeks. For the personal Gmail account, it was the good old webapp. For a change I hooked the Gmail account with Thunderbird to see how things would go. It had trouble authenticating the Google account, but then remembered about the 2-step verification so created an application-specific password to make it work.

The experience is better than I’d imagined. It’s quite handy being able to open mail in tabs. There are hundreds of add-ons to choose from. Especially, the Conversations add-on is a must. It’s smarter than Gmail’s conversation view. For example, if you get code broken into separate git patches like [PATCH 1/7], [PATCH 2/7] etc, they appear as separate threads in gmail. But this add-on groups all related patches to a single tree of conversation with branches. Clever! Guess I’d be sticking with this for the foreseeable future.

The probability of SHA-1 collisions

Git uses SHA-1 hashes to identify its objects (commits, refs, blobs, etc). It assumes that if the SHA-1 hashes of two objects are equal, then the two objects themselves are equal, hence there’s no need to store both in the repo. In other words, if the hashes of two different objects turned out to be equal at some point, Git wouldn’t be able to handle that!

But what are the chance of such a SHA-1 collision? This was discussed in the Git mailing list today and a recent analysis on this problem was shed into light. This analysis has used the famous Birthday Paradox and come up with a formula to determine the probability. It quotes,

“Applying the formula for 160bit SHA-1 you need 1.7e23 objects to get a 1% chance of collision. The current Linus kernel repository has 2.7 million objects. So to get a collision you’d need a repository that’s 6e16 times larger. That should be plenty.

For some wacky perspective that’s 10 million kernel sized contributions for every man woman and child on earth together in a single repository. It would seem git will reach plenty of other bottlenecks before SHA-1 becomes a problem…”

The probability is, of course, still non-zero. But don’t ever expect to witness such a collision before you die.

New levels to githug

Githug is an interactive text-based game (or a series of challenges, if ‘game’ isn’t the word), that helps you learn git. It has a series of levels, each of which requires the knowledge of some git commands to solve. Two more levels were added today on checking out tags and solving merge conflicts. You can install the latest version with,

gem install githug

It’ll work on any operating system, given ruby gems is installed. Currently githug consists of 41 levels of increasing difficulty, and more will be added soon.


Some of the first levels in githug (click on the pic to zoom)

Boundary commits [Git]

There was this question in Stackoverflow today about a leading caret (^) in the SHA of a commit. This is easily reecreatable as follows:

As the answer to the question explains, this is how boundary commits are represented in Git. A boundary commit is a commit that does not fall into the time-frame on which a command is executed. For example, if you use a parameter like –since=3.weeks, the commits before three weeks are considered as boundary commits. In the above scenario, it’s the root commit. According to the git-blame man page, you can use the –root option to not treat root commits as boundaries.

Linus Torvalds on Linux and Git

Typical programmer has had an interview with Linus on Linux and Git.

Git has taken over where Linux left off separating the geeks into know-nothings and know-it-alls. I didn’t really expect anyone to use it because it’s so hard to use, but that turns out to be its big appeal.

Of course the interview is imaginary, but it’s worth a read 🙂

On cherry-picking [Git]

This friend asked me on twitter to write about cherry-picking. In essence, cherry-picking a basic git concept which lets you create a copy of any commit and apply it on top of your current HEAD.

For example, say your repository has branches for different versions of the app. If you make a bug fix on one branch v2.0 and you want to apply that bug fix to v3.0 as well, you can cherry-pick the commit with the fix in v2.0 to v3.0. Checkout v3.0 and type

git cherry-pick <SHA-of-bug-fix-commit>

If you’re lucky there will be no merge conflicts and you’re done. If you get any conflicts, resolve them and type git cherry-pick –continue. You can also cherry-pick several commits at once as well. Some useful options to cherry-pick command include -e (edit – which lets you edit the commit message prior to committing) and -n (no commit, which applies the changes but does not make a commit). You can also use the merge strategies you use in git merge.

That’s just cherry-pick in a few words. Do checkout the man pages. Think-like-a-git has a good visual explanation of the concept.

Finding the commit a file was introduced in [Git]

Was going through the git log man page and noticed that there is a –reverse option. Guess what cool thing this could be used for? To find the commit in which a certain file was introduced in!

git log --reverse -- somefile.c

The commit on top is the first commit in which somefile.c appeared.

Ignoring the right way [Git]

Do you commit your .gitignore files? (Do you even use a .gitignore file? (Do you even use git? (Do you even write code?))) IMO, the best practice is to add a set of commonly ignored files to .gitignore and commit it. Saves time for everyone. If anyone using the repo needs his private list of ignores, he can use the .git/info/exclude file, which won’t affect even those who fetch straight from your local repository.

Gentlemen don’t have untracked files in their repos. Find some tips about ignoring files in git here.

Who was my first parent? [Git]

A co-worker of mine had the following tree structure in his git repository and he wanted to get rid of the 2abaf35 and 607f016 commits. The solution is a simple

git reset --hard e5e67d0

But, for the sake of fun, I wanted to do it without referring to a SHA value. The HEAD commit has two parents e5e67d0 and 2abaf35. HEAD^ will refer to the first parent and HEAD^2 will refer to the second parent. But how do we know which parent is the first?

According to charon at #git on freenode, HEAD at the time of invoking the merge will always be the first parent. This is the left-most (straight line) branch. The remaining commits will be the remaining parents, in the order you specify. So, in this case,

git reset --hard HEAD^

would have achieved the same feat.