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 <pattern>
However, this doesn’t return the commit hash straight away. I played around with git grep
to no avail.
1
To search for commit content (i.e., actual lines of source, as opposed to commit messages and the like), you need to do:
git grep <regexp> $(git rev-list --all)
git rev-list --all | xargs git grep <expression>
will work if you run into an “Argument list too long” error.
If you want to limit the search to some subtree (for instance, “lib/util”), you will need to pass that to the rev-list
subcommand and grep
as well:
git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util
This will grep through all your commit text for regexp
.
The reason for passing the path in both commands is because rev-list
will return the revisions list where all the changes to lib/util
happened, but also you need to pass to grep
so that it will only search in lib/util
.
Just imagine the following scenario: grep
might find the same <regexp>
on other files which are contained in the same revision returned by rev-list
(even if there was no change to that file on that revision).
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 -l -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 working tree for changed lines of text matching pattern:
git diff --unified=0 | grep <pattern>
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>)