【问题标题】:Why isn't 'git bisect' branch aware?为什么'git bisect'分支不知道?
【发布时间】:2015-12-18 18:08:36
【问题描述】:

我正在尝试查找自过去一天在名为 feature-x 的长期存在的分支(将在很久以后发布)上提交以来出现的错误的根源。

虽然有一个错误。我发现我的脚本中没有预料到的行为可能已经在迄今为止的任何提交中引入,特别是因为 master 的功能在 feature-x 中被大量使用,但在 Master 本身中则较少使用。

要测试这种行为,我必须运行我的脚本dependent.pl。但是当 bisect 跳转到代码的一半时,我的脚本在 Master 上不存在,因此无法测试。

我相信这是因为 bisect 会将您拉入无头状态,但在这种情况下,我真的希望处于另一个历史/变更集的上下文中,而不是漂浮在以太中。

在有人跳起来敲你做错了蜂鸣器之前,我们的团队喜欢在这些情况下合并分支,因为这个比喻很适合这种情况,而不是变基。

我将通过创建一个示例 repo 来演示这个:

git init

echo 'sub f { print $_; }' > main.pl
git add .
git commit -a -m "inital commit"

git branch feature-x
git checkout feature-x
echo 'main::f(1)' > dependent.pl
git add .
git commit -a -m "Starting work on feature X"
git tag dev-1.0

git checkout master
echo "sub f { return 1; }" > main.pl
git commit -a -m "sub f { return 1; }"
echo "sub f { return 2; }" > main.pl
git commit -a -m "sub f { return 2; }"
echo "sub f { return 3; }" > main.pl
git commit -a -m "sub f { return 3; }"

git tag release-1.0

git checkout feature-x
git merge master

echo 'print main::f();' > dependent.pl
git commit -a -m "Updating call to f"

所以现在你得到一个如下所示的 repo:

o Updating call to f ( Head of branch 'feature-x' )
o Merge branch master onto feature-x
|\
| o sub f { return 3; } (TAG release-1.0) ( Head of branch 'master' )
| o sub f { return 2; }
| o sub f { return 1; }
o | Starting work on feature X ( TAG 'dev-1.0' )
 \|
  o initial commit

所以我运行命令git bisect start feature-x dev-1.0 期望我能够找到在dependent.pl 中破坏我的代码的原因,我最终提交'sub f { return 2 }' 没有我从feature-x 更改的历史(即,如果我运行 ls,我看到的只是 main.pl 和dependent.pl 丢失)。

这使我处于无法测试的状态。我不知道当前的提交是否破坏了我的工作,我也不能说 master 上的提交破坏了它,所以我不能说这个提交是好还是坏。

我如何测试是什么破坏了我当前的分支?

【问题讨论】:

  • 我不确定是否完全理解您的问题。 1)我做了“git bisect start testdependent”。 2)文件dependent.txt 不存在,所以还没有问题-> 我做“git bisect good” 3)文件dependent.txt 存在,包含“dependent”,这很好:“git bisect good”。 4) git bisect 找到了有罪的提交(没有其他提交了)。您可能知道该错误在测试分支上,但 git bisect 无法猜到,因此它通过所有祖先“平分”。
  • gawi:dependent.txt 包含对 a.txt 的引用,测试错误的唯一方法是运行dependent.txt。如果dependent.txt 不存在,则无法对其进行测试,因此在那个阶段您不能说“git bisect good”。
  • @The Daemons Advocate 嗯...也许使用文本文件的示例太有限,无法说明问题的根源。我仍然认为“git bisect good”是合适的,因为它告诉 bisect 继续前进,因为要测试的项目尚不存在。
  • 顺便说一下,如果这是实际的测试代码,它应该在你的主分支中。它可能不是您 分发 的一部分(打包时可以忽略它),但测试代码是代码库的一部分,应该可以随时运行,以便例如,在提交 b 之前,您可以运行您的测试,而不必提交、合并、测试,然后在它不起作用时重置/修改。
  • 如果这有助于澄清任何问题,如果您签出提交“将分支 master 合并到 feature-x”,那么您不在分支上,这显然是平分你想做的事。

标签: git debugging branch rebase git-rebase


【解决方案1】:

这里的问题是 git bisect 分支感知。当您告诉它“依赖”是好的而“测试”是坏的,并且其中一个更改是合并提交时,它知道为了找出问题的引入位置,它必须查看提交 a、b 和 c - 否则,它所能告诉你的只是它在合并提交时是否已损坏。

听起来您期望的是测试提交 b 与来自其他分支的更改的组合,这是任何提交中都不存在的内容,git bisect 只允许您测试提交!为了测试该内容,您必须进行一系列测试合并 - 签出 b,合并依赖,让您测试,然后签出 a 或 c,合并依赖,让您再次测试。你可以很容易地在提交 b 处执行 git merge --no-commit dependent,然后在运行 git bisect good/bad 之前完成测试后执行 git reset --hard

否则,如果我误解了你希望它不会测试合并分支上的 任何 提交,而只测试合并提交本身(你不关心 a、b 或c 打破了它),只需告诉它合并分支上的一切都很好。如果您知道 a、b 和 c 与它无关,那就更好了。那么您甚至无需测试就知道它们是好的!

但你不能指望的一件事是 git 完全忽略提交 a、b 和 c。它绝对无法知道他们的更改是否与您的“错误”相关,并且他们的更改是您的好提交和坏提交之间差异的一部分。

【讨论】:

  • 假设 a.txt 有一个从dependent.txt 调用的函数 f,并在提交 a、b 和 c 中应用了更改。你怎么知道 f 中引入的更改没有破坏dependent.txt?
  • 再次,您要求测试一组在任何提交中都不存在的内容 - 例如,来自 b 的更改与来自依赖的更改的组合。要在您的工作树中获取该内容,最通用的方法是按照我的描述进行测试合并,然后在继续之前将其重置。
  • @The Daemons Advocate 我同意 Jefromi 的观点。看起来您正在使用测试分支将测试材料添加到树中,这有点不寻常。如果用dependent.txt 进行测试,可能应该在master 分支。另一个答案可能是:更频繁地合并以获得更好的粒度。
  • > * 它所能告诉你的只是它是否在合并提交时被破坏* 在许多情况下,我们不关心哪个 commit 破坏了,我们关心哪个Pull Request。我们想要合并提交!
猜你喜欢
  • 2022-01-09
  • 2013-03-05
  • 1970-01-01
  • 2020-06-30
  • 2011-07-13
  • 1970-01-01
  • 2011-08-04
  • 2019-09-18
  • 2019-09-17
相关资源
最近更新 更多