How to grep (search) committed code in the git his

2018-12-31 09:43发布

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.

标签: git grep diff
13条回答
千与千寻千般痛.
2楼-- · 2018-12-31 10:13

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.

查看更多
步步皆殇っ
3楼-- · 2018-12-31 10:19

If you want to browse code changes (see what actually has been changed with the given word in the whole history) go for patch mode - I found a very useful combination of doing:

git log -p
# hit '/' for search mode
# type in the word you are searching
# if the first search is not relevant hit 'n' for next (like in vim ;) )
查看更多
忆尘夕之涩
4楼-- · 2018-12-31 10:19

@Jeet's answer works in PowerShell.

git grep -n <regex> $(git rev-list --all)

The following displays all files, in any commit, that contain a password.

# store intermediate result
$result = git grep -n "password" $(git rev-list --all)

# display unique file names
$result | select -unique { $_ -replace "(^.*?:)|(:.*)", "" }
查看更多
人间绝色
5楼-- · 2018-12-31 10:20

I took @Jeet's answer and adpated it to Windows (thanks to this answer):

FOR /F %x IN ('"git rev-list --all"') DO @git grep <regex> %x > out.txt

Note that for me, for some reason, the actual commit that deleted this regex did not appear in the output of the command, but rather one commit prior to it.

查看更多
公子世无双
6楼-- · 2018-12-31 10:22

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

To search for Foo:

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

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


As Jakub Narębski commented:

  • 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.


As Rob commented, this search is case-sensitive - he opened a follow-up question on how to search case-insensitive.

查看更多
永恒的永恒
7楼-- · 2018-12-31 10:22

In my case I needed to search a Short Commit and the listed solutions were unfortunately not working.

I managed to do it with: (replace the REGEX token)

for commit in $(git rev-list --all --abbrev-commit)
do
    if [[ $commit =~ __REGEX__ ]]; then 
        git --no-pager show -s --format='%h %an - %s' $commit
    fi
done
查看更多
登录 后发表回答