Daily Shaarli

All links of one day in a single page.

August 20, 2013

Five Useful Git Tips - adit.io
  1. Autocorrect

    git config --global help.autocorrect 1

  2. Tab-completion

Or you can let bash complete commands for you!

Download this file to your home directory and name it .git-completion.bash.

Add this to your .bash_profile: source ~/.git-completion.bash
  1. And my pickaxe!

So you can grep through your code base. But what if the code you’re grepping for lives in history? Git allows you to grep through your entire project history quickly and easily using git pickaxe:

git log -S[search term]
git log -Saws_secret_key # did this repo ever have an aws_secret_key?

That will show you all the commits including aws_secret_key. You can see the diff of each commit too by passing the -p flag:

git log -Saws_secret_key -p

  1. Stripping whitespace

Hey! Don’t you hate when you check in code with trailing whitespace? And then your co-workers stab you to death?

You can have git strip whitespace for you automatically.

First, make a .gitattributes file in your project root with these contents:

  • filter=trimWhitespace

This says every file will go through the trimWhitespace filter. You could apply it to ruby files only like this:

*.rb filter=trimWhitespace

Now define the filter:

$ git config filter.trimWhitespace.clean trim_whitespace

Every filter can be run at two different hooks: right after you pull, or right before you push. The smudge filter is for right after pulling and the clean filter is for right before pushing. This says

create a new filter called trimWhitespace
for the “clean” action, run my code through the trim_whitespace utility.

Save this ruby script as trim_whitespace somewhere in your PATH and make it executable:

!/usr/bin/env ruby

lines = STDIN.readlines
lines.each do |line|
puts line.rstrip
end

  1. How to recover lost data

This is an important one. Here’s the golden rule of git: if you lose data but you checked it in somewhere, you can probably recover it. If you didn’t check it in, you probably can’t. So check in often!

When you make a commit, git takes a snapshot of your repo in that state:

Each commit has a SHA1 hash that you can use to reference the commit. And each commit points to it’s parent:

A “branch” is just a pointer to a commit:

So when you say git checkout master, you’re saying “give me the commit that the master pointer points to”.

Now, let’s say you accidentally do a git reset --hard and you are stuck on an older commit. You look at your log and it looks like you’ve lost a couple of commits! What’s happened? They are there, it’s just that master doesn’t point to them anymore so you can’t get to them:

But they’re still there! And you can get to any commit if you know it’s SHA1 hash! Well lucky for you, there are a couple of ways to figure out the SHA1. One way if to use the reflog:
reflog

Any action you take that updates a branch head will get logged in your reflog. Check it out by running git log -g:

commit ee68d62d4cbac3ffefc38398a63d70e4dd518e7d
Reflog: HEAD@{0} (Aditya Bhargava bluemangroupie@gmail.com)
Reflog message: commit: Finish writing the kernel
Author: Aditya Bhargava bluemangroupie@gmail.com
Date: Tue Aug 13 15:10:55 1991 -0700

Finish writing the kernel

commit 2f9eaea2ce5e6306cb37897417cf63a8d8c63ec4
Reflog: HEAD@{1} (Aditya Bhargava bluemangroupie@gmail.com)
Reflog message: checkout: moving from master to adit/experimental
Author: Linus Torvalds linus@git.com
Date: Tue Aug 13 14:27:36 1991 -0700

CSS Tweaks

Do you see your lost commits in here? If you do, grab the SHA1 of the newest commit, and do:

git branch lost_data [SHA1]

Now the lost_data branch should have all of your lost commits! Merge it into your branch:

git merge lost_data

Ta-da! Lost data recovered!
fsck

Here’s another way:

git fsck --full

This shows you all the objects that aren’t pointed to by another object. One of your commits should be in this list, and you can get the SHA1 hash!