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

Jon*_*röm 367 git search

我希望能够找到任何分支中任何提交中引入的某个字符串,我该怎么做?我找到了一些东西(我为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>
Run Code Online (Sandbox Code Playgroud)

如果您的解决方案很慢,这并不重要.

Mar*_*air 628

你可以做:

git log -S <whatever> --source --all
Run Code Online (Sandbox Code Playgroud)

查找添加或删除固定字符串的 所有提交whatever.该--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
Run Code Online (Sandbox Code Playgroud)

这是一个-G用于查找出现次数的示例function foo() {:

git log -G "^(\s)*function foo[(][)](\s)*{$" --source --all
Run Code Online (Sandbox Code Playgroud)

  • +1表现卓越.指着-S是一回事,更好地解释事情.此外,我喜欢使用--decorate来查看分支的来源 (18认同)
  • @sehe:谢谢你的好评.我想值得注意的是,`--decorate`只会将分支名称添加到每个分支顶端的提交中.实际上我并没有真正使用`--source`或`--decorate`,而是使用`git branch -a --contains <commit-hash>`来查找哪些分支包含我感兴趣的提交. (7认同)
  • 添加-p以查看内联差异,以及FWIW (3认同)
  • 对我来说这只有在我删除-S和搜索词之间的空格**时才有效,即``git log -S"dude,哪里是我的车?" --source --all`.@ribamar还在下面的[answer](http://stackoverflow.com/a/35988667/1330329)中写道,但在这个最佳答案旁边可能很容易被忽略. (2认同)

Cir*_*四事件 64

--reverse很有用,因为您需要进行更改的第一个提交:

git log --all -p --reverse --source -S 'needle'
Run Code Online (Sandbox Code Playgroud)

这样,旧的提交将首先出现.


小智 17

Mark Longair的答案非常好,但我发现这个更简单的版本适合我.

git log -S whatever
Run Code Online (Sandbox Code Playgroud)

  • 只是为了澄清,如果您正在寻找的提交是在"HEAD"中,那么该工作正常,但是这个特定的问题特别询问了如何查看存储库中的所有分支. (24认同)

alb*_*fan 17

用相同的答案搞清楚:

$ git config --global alias.find '!git log --color -p -S '
Run Code Online (Sandbox Code Playgroud)
  • !因为其他方式,git不能正确地将参数传递给-S.看到这个回复
  • --color-p有助于准确显示"whatchanged"

现在你可以做到

$ git find <whatever>
Run Code Online (Sandbox Code Playgroud)

要么

$ git find <whatever> --all
$ git find <whatever> master develop
Run Code Online (Sandbox Code Playgroud)


rib*_*mar 6

git log -S"string_to_search" # options like --source --reverse --all etc
Run Code Online (Sandbox Code Playgroud)

注意不要在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
Run Code Online (Sandbox Code Playgroud)


Eld*_*mir 6

虽然这并不能直接回答您的问题,但我认为这可能是您将来的一个很好的解决方案。我看到了我的代码的一部分,这很糟糕。不知道是谁写的,什么时候写的。我可以看到文件中的所有更改,但很明显代码已从其他文件移至此文件。我想首先找到是谁真正添加了它。

为此,我使用了Git bisect,它很快让我找到了罪魁祸首。

我跑git bisect start了然后git bisect bad,因为签出的修订版有问题。由于我不知道问题何时发生,因此我将第一次提交的目标定为“好”,git bisect good <initial sha>.

然后我继续在存储库中搜索错误代码。当我找到它时,我跑了git bisect bad,当它不存在时:git bisect good

在大约 11 个步骤中,我覆盖了大约 1000 个提交,并找到了引入问题的确切提交。非常棒。


BMW*_*BMW 6

不知道为什么接受的答案在我的环境中不起作用,最后我运行下面的命令来获取我需要的东西

git log --pretty=format:"%h - %an, %ar : %s"|grep "STRING"
Run Code Online (Sandbox Code Playgroud)