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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5816134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:48:55  来源:igfitidea点击:

How to find the Git commit that introduced a string in any branch?

gitsearch

提问by Jonas Bystr?m

I want to be able to find a certain string which was introduced in any commit in any branch, how can I do that? I found something (that I modified for Win32), but git whatchangeddoesn't seem to be looking into the different branches (ignore the py3k chunk, it's just a msys/win line feed fix)

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

It doesn't really matter if your solution is slow.

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

回答by Mark Longair

You can do:

你可以做:

git log -S <whatever> --source --all

To find all commits that added or removed the fixed stringwhatever. The --allparameter means to start from every branch and --sourcemeans to show which of those branches led to finding that commit. It's often useful to add -pto show the patches that each of those commits would introduce as well.

查找添加或删除固定字符串的所有提交whatever。该--all参数意味着从每个分支开始,并--source意味着显示哪些分支导致找到该提交。添加-p以显示每个提交也会引入的补丁通常很有用。

Versions of git since 1.7.4 also have a similar -Goption, which takes a regular expression. This actually has different (and rather more obvious) semantics, explained in this blog post from Junio Hamano.

自 1.7.4 以来的 git 版本也有类似的-G选项,它采用正则表达式。这实际上具有不同(而且更明显)的语义,在Junio Hamano 的这篇博客文章中进行了解释。

As thameerapoints out in the comments, you need to put quotes around the search term if it contains spaces or other special characters, for example:

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

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

Here's an example using -Gto find occurrences of function foo() {:

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

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

回答by Steven Penny

Mark Longair's answeris excellent, but I have found this simpler version to work for me.

Mark Longair 的回答非常好,但我发现这个更简单的版本对我有用

git log -S whatever

回答by albfan

Messing around with the same answers:

用相同的答案胡闹:

$ git config --global alias.find '!git log --color -p -S '
  • !is needed because other way, git do not pass argument correctly to -S. See this response
  • --colorand -phelps to show exactly "whatchanged"
  • 需要,因为其他方式,git 不会正确地将参数传递给 -S。看到这个回复
  • --color-p有助于准确显示“改变了什么”

Now you can do

现在你可以做

$ git find <whatever>

or

或者

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

回答by ribamar

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

Pay attention not to use spaces between S and "string_to_search". In some setups (git 1.7.1), you'll get an error like:

注意不要在 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

回答by Eldamir

While this doesn't directly answer you question, I think it might be a good solution for you in the future. I saw a part of my code, which was bad. Didn't know who wrote it or when. I could see all changes from the file, but it was clear that the code had been moved from some other file to this one. I wanted to find who actually added it in the first place.

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

To do this, I used Git bisect, which quickly let me find the sinner.

为此,我使用了Git bisect,它可以让我很快找到罪人。

I ran git bisect startand then git bisect bad, because the revision checked out had the issue. Since I didn't know when the problem occured, I targetted the first commit for the "good", git bisect good <initial sha>.

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

Then I just kept searching the repo for the bad code. When I found it, I ran git bisect bad, and when it wasn't there: git bisect good.

然后我只是继续在 repo 中搜索错误代码。当我发现它,我跑了git bisect bad,而当它不存在:git bisect good

In ~11 steps, I had covered ~1000 commits and found the exact commit, where the issue was introduced. Pretty great.

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

回答by BMW

Not sure why the accepted answer doesn't work in my environment, finally I run below command to get what I need

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

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