我修复了一个文件,并将其提交到我的git
存储库。
一段时间后,我发现它已经退步了。我想知道修复程序已在哪个提交中被删除,因此我尝试了git bisect
和git log --all -S TERM
,其中" TERM"是我的修复程序添加的一个字符串,它在项目中没有出现。
我发现git bisect
指责了一个不相关的提交,我发现git log --all -S TERM
只列出了我添加TERM的提交,并没有列出任何提交删除它,甚至虽然它不再出现在" master"。
经过一些手动搜索后,我发现两个分支之间存在合并提交。一个分支有我的修复,一个没有。合并作者选择了没有我修复的分支(奇怪,因为文件中没有冲突)。
我的问题是:
git bisect
找不到合并更改?关于此限制,我在联机帮助页中看不到任何内容。是否有不同的方法可以在上述场景中找到错误的合并?git log --all -S TERM
没有列出合并提交?该联机帮助页说它列出了提交"引入或删除"的实例。合并提交不会删除我的字符串吗?是否有不同的方法可以在上述场景中找到错误的合并?git bisect
和git log -S
在上述方案中无用,那么查找错误合并的有效方法是什么?如果没有这些工具,我会花很长时间来追查有关的变化。答案 0 :(得分:3)
为什么
git log --all -S TERM
不列出合并提交?
您必须为其添加-m
选项:
git log -m --all -S TERM
为了理解为什么在这种情况下需要特殊选项,让我们首先看一下git log -p
的操作,该操作必须包括列出的历史记录中的更改。您可以轻松检查,默认情况下,不显示合并提交更改。原因是更改是两个修订版之间的差异,而对于合并提交,我们有三个(或更多)修订版。 -m
option to git log
解决了该问题:
差异格式
...
-m
此标志使合并提交像常规提交一样显示完整的差异; 对于每个合并父级,单独的日志条目和差异为 生成。唯一的例外是与第一个父项的差异是 在给出
--first-parent
选项时显示;在这种情况下,输出 表示合并带入当时分支的更改。
然后,假设git log -S
就像通过处理git log -p
返回的差异一样工作,您应该承认默认情况下,合并提交将从结果中排除。但是,幸运的是,您可以在-S
中结合使用-m
和git log
选项,它可以按预期工作。
答案 1 :(得分:0)
git bisect
git bisect start $badCommit $goodCommit
git bisect run bash -c "! git merge-base --is-ancestor $goodCommit HEAD || grep -q $TERM"
bit bisect reset
注意:为简单起见,此解决方案使用git bisect run
。您也可以在“交互”模式下使用git bisect
。请参阅下面的“说明”部分。
这个想法是将bisect算法分析的提交限制在祖先路径中。
CB Bailey在this comment中提出了这个想法,尽管我找不到使用git rev-list
的方法。
关于git bisect
的部分,说明有些棘手。
它基于二等分算法的工作原理。
该算法假设一个好的提交的所有祖先都是好的。
因此,在测试git bisect
中的特定提交时,必须将非良好提交的后代也标记为良好。仅使用简单的grep函数时,通常情况并非如此。
您可以使用git merge-base --is-ancestor $goodCommit HEAD
(有关How can I tell if one commit is an ancestor of another commit (or vice-versa)?或checking if a commit is an ancestor of another的更多信息)来确定这些提交是否是另一次提交的后代