如何找到在任何分支中引入字符串的Git提交?

我希望能够找到在任何提交中引入的某个字符串 任何分支,我怎么做呢?我发现了一些东西(我为Win32修改了), 但是git whatchanged似乎没有查看不同的分支 (忽略py3k块,这只是一个msys/win换行修复)

git whatchanged -- <file> | \
grep "^commit " | \
python -c "exec(\"import sys,msvcrt,os\nmsvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)\nfor l in sys.stdin: print(l.split()[1])\")" | \
xargs -i% git show origin % -- <file>

如果你的解决方案很慢,这并不重要。

135263 次浏览

你可以:

git log -S <search string> --source --all

查找添加或删除固定的字符串 search string的所有提交。--all参数表示从每个分支开始,而--source表示显示哪一个分支导致了该提交。添加-p来显示每次提交都会引入的补丁通常是有用的。

从1.7.4开始的git版本也有类似的选项-G,它接受一个正则表达式。这实际上有不同的(更明显的)语义,在这篇博文来自Junio Hamano中解释。

正如thameera在注释中指出的那样,如果搜索词包含空格或其他特殊字符,则需要在搜索词周围加上引号,例如:

git log -S 'hello world' --source --all
git log -S "dude, where's my car?" --source --all

下面是一个使用-G查找function foo() {出现情况的示例:

git log -G "^(\s)*function foo[(][)](\s)*{$" --source --all

Mark Longair的回答是优秀的,但我发现这个更简单的版本为我工作。

git log -S whatever

用同样的答案瞎折腾:

$ git config --global alias.find '!git log --color -p -S '
  • 是必需的,因为其他方式,git不会正确地将参数传递给-S。看到这种反应
  • ——颜色- p有助于准确显示“发生了什么变化”

现在你可以

$ git find <whatever>

$ git find <whatever> --all
$ git find <whatever> master develop

——反向也很有帮助,因为你想要第一次提交进行更改:

git log --all -p --reverse --source -S 'needle'

这样旧的提交将首先出现。

git log -S"string_to_search" # options like --source --reverse --all etc

注意不要在“S”和“string_to_search”之间使用空格。在一些设置中(git 1.7.1),你会得到这样的错误:

fatal: ambiguous argument 'string_to_search': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

虽然这并没有直接回答你的问题,但我认为这可能是你未来的一个很好的解决方案。我看到了我的一部分代码,很糟糕。不知道是谁写的,什么时候写的。我可以看到文件中的所有更改,但很明显,代码已经从其他文件移到了这个文件中。我想知道到底是谁先把它加进去的。

为了做到这一点,我使用Git平分,它很快让我找到罪人。

我运行了git bisect start,然后git bisect bad,因为修订检查出来有这个问题。因为我不知道问题是什么时候发生的,所以我将第一次提交作为“好”,git bisect good <initial sha>

然后我就一直在回购中寻找坏代码。当我找到它时,我运行git bisect bad,当它不存在时:git bisect good

在大约11个步骤中,我已经讨论了大约1000个提交,并找到了引入问题的确切提交。好极了。

不确定为什么接受的答案在我的环境中不起作用,最后我运行下面的命令来获得我需要的

git log --pretty=format:"%h - %an, %ar : %s"|grep "STRING"