正如标题所说,我想找到每个 diff 包含特定字符串的提交。
目前,我使用
git log -p 'filename'
这显示不太像每个差异的界面,我在其中搜索字符串。然后我回溯以找到实际的提交消息。
简单的替代方法可能是将 git log -p 输入到 grep 中,但我无法通过这种方式找到提交 ID 或消息。
git log -p -S'string'
可用于搜索添加或删除字符串的提交。它的行为并不完全相同,因为它只匹配实际添加或删除模式实例的提交,而不是(例如)它在 diff 上下文中出现的提交。但也许这对你来说已经足够了。
这是一个单行 shell 脚本(出于格式化目的分成多行),它提取影响path
包含git show -p
给定pattern
. 它并不完美(它会匹配提交消息和差异),但它应该很容易从这里进行调整。
git rev-list HEAD -- path |
while read rev; do
if git show -p $rev | grep pattern >/dev/null; then
echo $rev
fi
done
请注意,您可以替换git show
为,例如git diff $rev^ $rev
(请注意,这仅与第一父级进行比较,如果它是合并),或git whatchanged $rev
,或任何您喜欢的。主要技巧是从git rev-list
提取所有候选者开始(影响给定路径的提交;省略-- path
部分以获取从 开始的所有提交HEAD
)。请参阅git-rev-list(1)了解您可以使用git rev-list
.
我知道这个问题已经回答了一段时间,但我也遇到了这个问题并找到了一个不同的解决方案,所以我想我会分享。Git-log的-G开关应该做你想要的,其中-S开关只会输出匹配字符串出现次数发生变化的提交。
从git-log的手册页:
-G 查找补丁文本包含匹配的添加/删除行的差异。
为了说明 -S --pickaxe-regex 和 -G 之间的区别,请考虑在同一文件中具有以下差异的提交:
+ return !regexec(regexp, two->ptr, 1, ®match, 0); ... - hit = !regexec(regexp, mf2.ptr, 1, ®match, 0);
虽然 git log -G"regexec(regexp" 将显示此提交,但 git log -S"regexec(regexp" --pickaxe-regex 不会(因为该字符串的出现次数没有改变)。
有关更多信息,请参阅 gitdiffcore(7) 中的镐条目。
git log --all -G'my_search' -i -m -p
助记符:git log all GIMP
--all
:搜索所有可能的路径,而不仅仅是通过 HEAD。-G
:比只搜索显示不同出现次数的差异-S
更普遍。搜索完整的差异并接受正则表达式。-S
my_search
-G
-i
[可选]:使 -G 忽略大小写。-m
:默认情况下 git log 不会输出合并提交的差异。-m
更改此默认行为,使合并提交输出完整差异。这一点至关重要:如果格式错误的合并提交更改了您的行,您将无法看到没有-m
.-p
: 还输出找到的每个提交的完整补丁。你甚至可以将它连接到 vim。我觉得它非常有用:
git log --no-color --all -G'regex' -i -m -p | vim -
我在这里使用--no-color
,因为 vim 为我突出显示了补丁。
如果你在 linux 上,通过 egrep 管道它并在正则表达式上搜索
git log -p 'filename' | egrep '(yourstring|commit-message)'
您可以为此使用 git,例如:
git log --grep="filename"
或在特定文件上:
git log --grep="filename" README
您是否考虑过使用管道和 grep 命令?
例子:
git log -p | grep 'filename'