如何确定git merge删除某些代码行的原因?

时间:2012-04-12 01:18:45

标签: git

我们有一个版本,有问题的提交(daf7110)是在合并回主人的历史中。此时(85a13270),master具有daf7110添加的代码行。

当我们的一个开发人员将master合并到他的分支(dev-branch)时,代码行消失了。它们从未出现在开发者合并的历史中。我用以下方法验证了这一点:

git checkout c513d2 # <--last commit on dev-branch before the merge
git log -S string_that_was_added -- lib/File/It/Was/In.pm

所以:

  1. 代码在合并之前从未存在于dev-branch上。
  2. 它是在主人,自“git merge-base c513d2 85a13270”以来添加
  3. 我怎样才能获得更多关于为什么git的合并逻辑决定代码不能在合并中存活的细节?或者是否还有其他原因导致我的提交无法在合并中存活下来?

2 个答案:

答案 0 :(得分:12)

我不知道为什么会发生这种情况的原因,但我可以提供一些调试技巧。

首先,我会确保您没有任何奇怪的设置。在没有Git配置的帐户中,执行具有这两个分支的repo的新克隆。尝试合并。它还会发生吗?如果没有,那么检查你的设置,看看有什么奇怪的;特别是,我会怀疑任何rerere设置。另外,尝试与--no-rerere-autoupdate合并以查看它是否仍会丢弃相关的行。

之后,我会首先打开合并的最大详细程度,然后尝试再次合并:

GIT_MERGE_VERBOSITY=5 git merge -v master

这将为您提供有关合并过程所做决定的更多信息。

如果不能告诉您任何有用的信息,您还可以尝试查看它是否与不同的合并策略或默认的递归合并策略的不同选项一起发生。尝试git merge -s resolve尝试更简单但更愚蠢的合并策略。你还有问题吗?如何为递归策略尝试不同的选项,例如git merge -s recursive -X patience?在打开额外详细程度的情况下执行最后操作,并查看是否与默认合并策略做出不同的决定。

如果这不起作用,那么是时候尝试手动将其减少到最小的测试用例。首先,我会尝试将自己限制在有问题的文件中。确保你在一次性回购中工作,然后使用git filter-branch删除所有文件,但是缺少这些文件。当你这样做,并尝试再次进行合并时,你会得到相同的结果吗?如果没有,由于Git感到困惑,并且当他们确实没有移动到另一个文件时,行可能会消失。

如果你仍然可以只用一个文件重现问题,那么就该开始回溯每个分支的修订历史记录,进行合并,直到问题消失为止。例如,从devel分支开始,跳回大约一半,尝试再次进行合并,并查看来自master的行是否仍然消失。如果他们这样做,请尝试进一步跳回去。如果没有,沿着devel分支向前跳,然后再试一次。一旦你找到了在开发方面引入问题的提交,在master上尝试相同的操作,移回你正在合并的提交,直到问题消失。

现在你已经尽可能地回去了,尝试在那之前重新创建历史的简化版本。创建一个新的Git仓库,检查这两个提交的合并基础。然后在单独的分支中检入您在上面跟踪的两个提交。你可以合并那些没有问题,或者它是否依赖于合并拓扑的某些方面?如果是,请尝试重新创建完整的合并拓扑;只创建执行历史记录中所有合并所需的提交。这可以重现你的问题吗?

此时,您应该有最简单的历史记录来重现问题,只需要一个文件来证明它(或者当您无法进一步减少它时会发现一些有趣的东西并重现问题) 。我建议公开发布这个repo,以便我们可以查看它,如果那个文件中没有任何敏感信息,或者是否存在,尝试进一步减少它,编辑每个提交以删除除了相关的路线。您还应该能够使用占位符值替换每个相关行,从而为您提供一个不包含任何实际代码的最小测试用例。

以上所有内容都是大量工作,但希望您在完成所有工作之前能够找到一些有趣的内容,或者可以跳过前面并生成一个最小的测试用例,而无需经过所有中间步骤。一旦你有一个更小的测试用例,或上述步骤之一的结果,发布它们,我们可以仔细看看。

答案 1 :(得分:2)

我遇到了类似的问题,看起来这是因为有问题的代码行首先由提交引入,然后由revert删除,该分支被合并到master。 然后在dev分支上重新引入该行,但在将dev分支合并到master时,系统地剥离了该行。我假设git以某种方式跟踪恢复并假设不需要这条线并且将被删除。