在祖先路径上保持 git 平分
Keeping git bisect on the ancestry path
我有一个包含复杂分支和合并树的存储库,我想使用 git bisect 来查找引入错误的时间。
我有一个好提交和一个坏提交来开始二等分,其中好提交是坏提交的祖先。
我希望 git bisect
能够提交具有良好提交作为祖先的提交,但它没有(使用 git 2.21.0)。
目前我正在通过保留提交列表并使用 git rev-list --ancestry-path GOOD..BAD
并在中间选择一个提交来手动进行二等分。有没有办法用 git bisect
自动执行此操作?它是否有标志留在祖先路径中?
首先在祖先路径中一分为二的推理
与正在搜索的错误相关的功能可能并不存在于所有分支中,因此检查在那里无关紧要。不过它们应该存在于祖先路径中。
一旦将祖先路径一分为二,人们可能会将合并提交归咎于此,并且他们会知道该错误源自该分支。这已经教会了很多关于这个错误的知识。
要继续对引入错误的分支进行二等分,不需要单独测试每个提交(因为它们不一定具有使错误浮出水面所需的功能),但应该合并每个提交最后一次好的提交,然后检查错误是否存在。然后可以查明一个特定的提交,当与好的提交合并时,会引入错误。
请注意,这个过程我已经做过好几次了,对我很有用,我只是在寻找更方便的方法。
git bisect
没有遵循祖先路径的选项。由于以下几个原因,这样的选项通常没有用:
- 大多数情况下,用户不确定引入回归的位置。因此,不太可能使用复杂的选项来控制路径遍历。
- 在大多数情况下,您会忽略大量可能的分支,因为您会跳过它们。如果您有 1024 个单独的分支,其中一个提交合并到您的
master
分支中,git bisect
将忽略其中的一半,甚至在第一次测试后不会被考虑,并且仍然只需要运行 12 次就可以找到有问题的提交。
- 经常,有问题的提交是在一个合并的分支上,而不是在祖先路径上。对于没有线性历史记录(即基于合并的工作流)的大多数情况都是如此。
除非您对您的存储库有特定的了解,以至于不在祖先路径上的提交会产生误报或漏报,否则通常让 git rebase
做它的事情就可以了。由于它的行为是 O(log N),因此额外成本往往可以忽略不计。但是,如果需要,您可以使用 git bisect skip RANGE
指定要跳过的范围。
如果您可以使用 shell 脚本或命令自动测试您的分支,则可以将 git bisect run
与该 shell 脚本一起使用。如果提交是好的,它应该退出 0,如果应该跳过提交则应该退出 125,如果提交是错误的则应该退出 1 到 127 之间的任何其他代码。这可用于避免检查出于任何原因不适合的提交。
您可以使用现有的二分法轻松完成此操作,而不是 git bisect good agoodone
do
git bisect good $(git rev-list \
--ancestry-path --boundary agoodone..thebadone | sed -n s/-//p)
我有一个包含复杂分支和合并树的存储库,我想使用 git bisect 来查找引入错误的时间。
我有一个好提交和一个坏提交来开始二等分,其中好提交是坏提交的祖先。
我希望 git bisect
能够提交具有良好提交作为祖先的提交,但它没有(使用 git 2.21.0)。
目前我正在通过保留提交列表并使用 git rev-list --ancestry-path GOOD..BAD
并在中间选择一个提交来手动进行二等分。有没有办法用 git bisect
自动执行此操作?它是否有标志留在祖先路径中?
首先在祖先路径中一分为二的推理
与正在搜索的错误相关的功能可能并不存在于所有分支中,因此检查在那里无关紧要。不过它们应该存在于祖先路径中。
一旦将祖先路径一分为二,人们可能会将合并提交归咎于此,并且他们会知道该错误源自该分支。这已经教会了很多关于这个错误的知识。
要继续对引入错误的分支进行二等分,不需要单独测试每个提交(因为它们不一定具有使错误浮出水面所需的功能),但应该合并每个提交最后一次好的提交,然后检查错误是否存在。然后可以查明一个特定的提交,当与好的提交合并时,会引入错误。
请注意,这个过程我已经做过好几次了,对我很有用,我只是在寻找更方便的方法。
git bisect
没有遵循祖先路径的选项。由于以下几个原因,这样的选项通常没有用:
- 大多数情况下,用户不确定引入回归的位置。因此,不太可能使用复杂的选项来控制路径遍历。
- 在大多数情况下,您会忽略大量可能的分支,因为您会跳过它们。如果您有 1024 个单独的分支,其中一个提交合并到您的
master
分支中,git bisect
将忽略其中的一半,甚至在第一次测试后不会被考虑,并且仍然只需要运行 12 次就可以找到有问题的提交。 - 经常,有问题的提交是在一个合并的分支上,而不是在祖先路径上。对于没有线性历史记录(即基于合并的工作流)的大多数情况都是如此。
除非您对您的存储库有特定的了解,以至于不在祖先路径上的提交会产生误报或漏报,否则通常让 git rebase
做它的事情就可以了。由于它的行为是 O(log N),因此额外成本往往可以忽略不计。但是,如果需要,您可以使用 git bisect skip RANGE
指定要跳过的范围。
如果您可以使用 shell 脚本或命令自动测试您的分支,则可以将 git bisect run
与该 shell 脚本一起使用。如果提交是好的,它应该退出 0,如果应该跳过提交则应该退出 125,如果提交是错误的则应该退出 1 到 127 之间的任何其他代码。这可用于避免检查出于任何原因不适合的提交。
您可以使用现有的二分法轻松完成此操作,而不是 git bisect good agoodone
do
git bisect good $(git rev-list \
--ancestry-path --boundary agoodone..thebadone | sed -n s/-//p)