tags:

views:

512

answers:

5

I have deleted a file or some code in a file sometime in the past. Can I grep in the content (not in the commit messages)?

A very poor solution is to grep the log:

git log -p | grep

However this doesn't return the commit hash straight away. I played around with "git grep" to no avail.

A: 

I am not sure, if that's what you want ...

You can use git show to see old content. See git usermanual for an example:

You can always view an old version of a file by just checking out the correct revision first. But sometimes it is more convenient to be able to view an old version of a single file without checking anything out; this command does that:

$ git show v2.5:fs/locks.c

Before the colon may be anything that names a commit, and after it may be any path to a file tracked by git.

then you can grep the output.

tanascius
I neither know the file name nor the version, so this doesn't help in my case.
Ortwin Gentz
+1  A: 

So are you trying to grep through older versions of the code looking to see where something last exists?

If I were doing this, I would probably use git bisect. Using bisect, you can specify a known good version, a known bad version, and a simple script that does a check to see if the version is good or bad (in this case a grep to see if the code you are looking for is present). Running this will find when the code was removed.

Rob Di Marco
Thanks, I know git bisect but in my case it's not about any good or bad versions but just about old code I still need.
Ortwin Gentz
Yes, but your "test" can be a script that greps for the code and returns "true" if the code exists and "false" if it does not.
Rob Di Marco
+9  A: 

You should use the pickaxe (-S) option of git log

git log -SFoo -- path_containing_change 
git log -SFoo -- path_containing_change --since=2009.1.1 --until=2010.1.1

See Git history - find lost line by keyword for more.


As Jakub Narębski comments:

  • this looks for differences that introduce or remove an instance of <string>.
    It usually means "revisions where you added or removed line with 'Foo'".

  • the --pickaxe-regex option allows you to use extended POSIX regex instead of searching for a string.

VonC
Caveat: this would find those revisions in which number of occurences of 'Foo' changed, which usually means revisions where you added or removed line with 'Foo'.
Jakub Narębski
There is also `--pickaxe-regex` if you want to use extended POSIX regex instead of searching for a string.
Jakub Narębski
Thanks, I wasn't aware of this option. Looks like this is the best solution if you're interested in the commit messages and Jeet's solution is most appropriate if you need the traditional UNIX grep behavior of pure line matching.
Ortwin Gentz
@Ortwin: agreed (and I have upvoted the chosen solution). the `git log` bit in your question had me confused ;)
VonC
+13  A: 

To search for commit content (i.e., actual lines of source, as opposed to commit messages and the like), what you need to do is:

git grep <regexp> $(git rev-list --all)

This will grep through all your commit text for regexp.

Here are some other useful ways of searching your source:

Search working tree for text matching regular expression regexp:

git grep <regexp>

Search working tree for lines of text matching regular expression regexp1 or regexp2:

git grep -e <regexp1> [--or] -e <regexp2>

Search working tree for lines of text matching regular expression regexp1 and regexp2, reporting file paths only:

git grep -e <regexp1> --and -e <regexp2>

Search working tree for files that have lines of text matching regular expression regexp1 and lines of text matching regular expression regexp2:

git grep -l --all-match -e <regexp1> -e <regexp2>

Search all revisions for text matching regular expression regexp:

git grep <regexp> $(git rev-list --all)

Search all revisions between rev1 and rev2 for text matching regular expression regexp:

git grep <regexp> $(git rev-list <rev1>..<rev2>)

If you run OS X, I have written an OS X Dashboard Widget summarizing this (and other Git commands) here.

Jeet
Thanks, works great! It's sad though that "$(git rev-list --all)" is needed and no convenient switch to specify searching in the whole history of a branch.
Ortwin Gentz
Excellent. +1. The GitBook add some details (http://book.git-scm.com/4_finding_with_git_grep.html), and Junio C Hamano illustrates some of your points: http://gitster.livejournal.com/27674.html
VonC
+1  A: 

These blog posts by Junio C Hamano (git maintainer) might be interesting for you:

Jakub Narębski