Finding with Git

Git is an amazing version control system that never loses anything, but
sometimes it can be hard to find out where things are. Most of the time
it is going to be git log that is our friend, but not all the time.

Where is my file?

Sometimes you know that you have a file in your repository but, you
don't know exactly where it is. git ls-files is the answer.

Obviously, you can use any particular grep options you prefer, like -i
to ignore case.

In what files does word exist?

If you want to find information inside files git grep is your friend.
git grep works similar to a recursive grep grep -r . but it only
searches files that are managed by git.

It is also possible to give versions to grep to find out what has
changed between revisions.

Maybe this is not that impressive. Most of the above can be accomplished
with standard grep, find, ack, and friends. But Git is a version
control system. How do I find out about things that happened in the past?

Who deleted my file?

You know how it is, you are working in some project and, your dog gets
sick and you have to stay home from work, when you come back someone has
deleted your file! Where is it and who did it? git log to the rescue.

git log shows you the commit logs. It is your eye into the past.

Looks like I found the culprit, was I working from home? But is the file
really deleted here. To get some more information about files add the
--summary option.

Yes, it looks like the file is really deleted. Stupid bastard! Let me
break this command down starting with the last command.

  • test/create-table-test.js – The filename has to be the relative path
    to the file (from your current directory).
  • -- – The double-dash is used to tell Git that this is not a branch
    or an option.
  • --summary – Show me what files were deleted or added.
    --name-status is similar.
  • --diff-filter – This is a real beauty, it allows me to limit the log
    to show me only the specified kind of change, in this case D, for
    Deleted. Other options are: Added (A), Copied (C), Modified (M) and Renamed (R)

When was a file added?

This uses the same technique as above, but I will vary it since I don't
want to type the full path of the file.

As you can see here I am using --name-status as a variation on
--summary, it uses the same notation as the --diff-filter.

I am using grep -C 6 to get some context around the found element, in
this case six lines before and after the match. Very useful!

Who changed that line?

As you probably know it is to see who has done something in a file by
using git blame

Every line gets annotated with the commit who introduced it and by whom.
Very helpful.

Who deleted that line?

Another feature, which is not as well known, is git blame --reverse.
It allows you to see the file as it was before, annotated to show you
where it has been changed.

In the output you can see that most of the lines are still the same at
HEAD (558b8e7f). But the fourth and fifth line 093c13e9 and ba6c4d8b
don't exist anymore. And the sixth and seventh lines ^b96c68b have
been changed after this commit.

What commits contain the string?

Another thing I find very useful is to find out when certain words or
sentences are removed or added. For this you can use git log -S<string> or
git log -G<regex>

That's all folks!

4 Comments

  1. Thanks, this is really helpful!

  2. @Nathan I’m glad you liked it!

Trackbacks for this post

  1. Finding Files by Name With Git « Mas-Tool's Favorites
  2. Finding Content in Files With Git « Mas-Tool's Favorites

Leave a Reply