Tag Archives: git

Keeping the Git directory and the working tree separate

When you clone/init a repo, the .git directory is created inside your working tree. This colleague of mine wanted to check-in the source code to a legacy versioning system other than git. Normally the .git directory gets pushed as well, since it’s inside the working tree.

Normal structure

But he didn’t want to push the .git dir as well. He wanted something like this:

Required structure

If you look at the git-clone man page, there’s this option called --separate-git-dir which lets you assign a custom directory as the .git dir. The syntax is:

git clone git://path.to.repo newdir --separate-git-dir=somedir

But in this case, my colleague didn’t want to clone again. He had local branches galore and all. So I tried out the git-clone mentioned above and checked what really happens. It turns out that git creates a file called .git inside the working tree that looks like this:

gitdir: /home/thameera/path/to/git/dir

Gotcha! Now what we need to do is move my friend’s .git directory to a separate location and create a file called .git that has the path to the git dir as above. It works!

ShortcutFoo

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.

githug

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.