我怎样才能确定为什么一个混帐删除了一些代码行? [英] How can I determine why a git merge deleted some lines of code?

查看:95
本文介绍了我怎样才能确定为什么一个混帐删除了一些代码行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们发布了一个版本,并且有问题的提交(daf7110)在合并到master的历史记录中。在这一点上(85a13270),master拥有daf7110添加的代码行。



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

  git checkout c513d2#<  - 在合并之前的最后一次提交开发分支
git log -S string_that_was_added - lib / File / It / Was / In.pm

/ p>


  1. 合并前,dev-branch上的代码从未存在过。 因为git merge-base c513d2 85a13270



  2. 如何获得更多细节,以了解为什么git的合并逻辑决定代码不应该存活合并?或者还有其他一些原因,我的提交不会在合并后生存?

    解决方案

    我不知道有什么原因为什么会出现这种情况,但我可以给出一些调试提示。

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



      

    然后,我会开始为您的合并打开最大的冗余度,然后再次尝试合并: GIT_MERGE_VERBOSITY = 5 git merge -v master

    这会给你更多关于合并决定的信息

    如果这不能告诉你任何有用的东西,你也可以尝试看看它是否发生在不同的合并策略中,或者不同的选项到默认值,递归合并策略。试试 git merge -s resolve 来尝试一个更简单但愚蠢的合并策略。你仍然遇到问题吗?如何尝试递归策略的不同选项,如 git merge -s recursive -X耐心?是否打开了最后一个细节,并查看是否做出与默认合并策略不同的决策。



    如果这样做不起作用,那么现在是时候尝试手动将其降低到最小的测试案例。首先,我会尽力将自己限制在只是有问题的文件中。确保你在一次性回购中工作,并使用 git filter-branch 来删除所有文件,除了那些缺少行的文件。当你这样做,并尝试再次合并,你会得到相同的结果?如果不是这样,可能会由于Git混淆而导致线条消失,并且认为他们确实没有移动到另一个文件。



    如果仍然可以重现只有一个文件的问题,是时候开始回溯每个分支的修订历史,进行合并,直到问题消失。例如,从devel分支开始,一半跳回来,再次尝试合并,看看master的行是否消失。如果他们这样做,尝试进一步跳回。如果不是,沿着devel分支向前跳,然后再试一次。一旦找到引发问题的提交,请在master上尝试相同的方法,将您正在合并的提交移回,直到问题消失。



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



    在这一点上,你应该有最简单的历史来重现这个问题,只有一个文件展示它(或者已经发现当你无法进一步减少并重现问题时,有趣的事情)。我建议要么公开发布这个回购,以便我们可以看看它,如果这个文件中没有任何敏感内容,或者如果有的话,试图进一步降低它,编辑每个提交以移除除了相关线路。您还应该能够用占位符值替换每个相关行,并留下一个最小的测试用例,该用例不包含任何实际的代码。



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


    We had a release and the commit in question (daf7110) was in the history that was merged back to master. At this point (85a13270), master has the lines of code that were added by daf7110.

    When one of our developers merged master into his branch (dev-branch), the lines of code went away. They never existed in the history of the developer's side of the merge. I verified this with:

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

    So:

    1. The code never existed on dev-branch before the merge.
    2. It was on master, added since "git merge-base c513d2 85a13270"

    How can I get more detail as to why git's merge logic decided the code should not survive the merge? Or is there some other reason my commit would not have survived that merge?

    解决方案

    I don't know of a reason off the top of my head why this would happen, but I can give some debugging tips.

    First, I would make sure that you don't have any odd settings. Do a fresh clone of a repo that has both of these branches, in an account that has no Git config. Try doing a merge. Does it still happen? If not, then check your settings, see if there's anything odd; in particular, I would be suspicious of any rerere settings. Also, try doing the merge with --no-rerere-autoupdate to see if it still drops the lines in question.

    After that, I would start by turning on the maximum verbosity for your merge, and try doing the merge again:

    GIT_MERGE_VERBOSITY=5 git merge -v master
    

    This will give you some more information on the decisions that the merge process made.

    If that doesn't wind up telling you anything useful, you can also try to see if it happens with different merge strategies, or different options to the default, recursive merge strategy. Try git merge -s resolve to try a simpler, but stupider merge strategy. Do you still get the problem? How about trying different option for the recursive strategy, such as git merge -s recursive -X patience? Do the last with the extra verbosity turned on, and see if that makes different decisions than the default merge strategy.

    If that doesn't work, then it's time to try manually reducing this down to a minimal test case. First, I would try to limit yourself down to just the file in question. Make sure you're working in a throwaway repo, and use git filter-branch to delete all files but the one in question that the lines are missing from. When you do that, and try doing the merge again, do you get the same results? If not, it's possible that the lines are disappearing due to Git getting confused and thinking that they moved to another file when they really didn't.

    If you can still reproduce the problem with just the one file, it's time to start walking back the revision history of each branch, doing a merge, until the problem goes away. For instance, starting with the devel branch, jump back about halfway, try doing the merge again, and see if the lines from master still disappear. If they do, try jumping back further. If not, jump forward along the devel branch, and try again. Once you've found the commit that introduces the problem on the devel side, try the same on master, moving back the commit that you are merging in until the problem goes away.

    Now that you've gone back as far as you can, try recreating a simplified version of the history before that point. Create a new Git repo, check in the merge base of those two commits. Then check in the two commits that you tracked back to above in separate branches. Can you merge those without problems, or does it depend on some aspect of the merge topology in between? If it does, try recreating the full merge topology; create just the commits necessary to do all of the merges in the history. Can that reproduce your problem?

    At this point, you should have the simplest possible history to reproduce the problem, with just a single file demonstrating it (or will have found out something interesting when you weren't able to reduce it any further and reproduce the problem). I would recommend either posting this repo publicly so that we could take a look at it, if there isn't anything sensitive in that one file, or if there is, trying to reduce it down further, editing each commit to remove everything but the relevant lines. You should also be able to replace each relevant line with a placeholder value, leaving you with a minimal test case that doesn't contain any of your actual code.

    All of the above is a significant amount of work, but hopefully you will find something interesting before completing all of it, or may be able to skip ahead and produce a minimal test case without going through all of the intermediate steps. Once you have a more minimal test case, or results from one of the above steps, post them and we can take a closer look.

    这篇关于我怎样才能确定为什么一个混帐删除了一些代码行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆