如何调查Git为什么删除了一些代码

时间:2018-01-25 13:14:37

标签: git git-merge merge-conflict-resolution

我们刚刚遇到自动合并提交的问题,其中某些行已被删除但不应删除。然后我们手动修复它,但它再次发生了。

我们目前有一个更像SVN的Git工作流程:每个人都应该承诺一个分支("开发"),我们只使用a"发布"分支到"冻结"当前的开发状态,修复那里的主要问题,并将其合并到" master"一旦它足够稳定。然而,执行有问题的合并以将本地分支合并到远程开发分支中,因此没有"真正的"已合并的分支。

我检查了合并提交的代码被删除的文件的父提交的版本,但正如您所期望的那样:在一个行中有行,而在另一行中它们不是

我的问题是我不知道为什么Git会选择删除这些行,而且我也不知道在哪里寻找有关它的信息。这可以以某种方式确定,或者有人已经告诉我可能导致决定删除代码的原因是什么?我们如何防止这种情况发生(除了手动合并)?

旁注: 该存储库中的大多数人使用Git客户端构建到Visual Studio(版本2015和2017),我认为参与问题的每个人(合并提交的父提交的创建者)正在使用该客户端。

2 个答案:

答案 0 :(得分:2)

我认为我们应该先澄清一些事情。

  

执行有问题的合并以将本地分支合并到远程开发分支

合并始终在本地进行,默认情况下,正常的“pull-then-push”工作流将远程开发分支合并到本地分支中。我认为这就是发生了什么,这里的措辞只是有点偏离,所以如果不是他的情况,请澄清你正在使用什么过程将本地工作与远程工作结合起来。

  

所以没有合并的“真正”分支。

这至多是半真的,并没有你想象的那么有意义。假设用于共享分支的正常的pull-to-push工作流,开发人员将合并到真正的分支(他们的本地分支);让我们称之为“我们的”。要合并的工作(“他们的”)是根据远程分支参考指定的,但这很好; “他们的”可以是你想要融入“我们的”的任何东西。

但是好的,为什么要删除行?您注意到,当您查看合并父项时,一个有行,另一个没有。这是有道理的,但现在我们需要知道第三个提交,称为“合并基础”。

O - A - B - M <--(development)
 \         /
  C - D - E

合并前origin/development位于B且用户的本地分支(development?)位于E。其中一个有线,另一个没有。好吧,git会找到一个“合并基础” - 通常只是来自BE的最新提交“可达”(通过父指针)。这是上图中的O

O是否有问题?

如果不是,那么git认为“其中一个父母添加了这些行;所以我应该将它们添加到结果中”。

但是如果是,那么git认为“其中一个父母没有对这些行做出任何改变,而另一个已删除它们;所以我应该从结果中删除它们。”

所以听起来你会期望的行在合并基础中,但它们是。最常见的原因与git revert的使用有关 - 尤其是如果“太快完成”则还原合并。但这只是一种可能性。

这是我能提供的所有一般信息;提供更多关于如何发生这种情况或如何避免它的建议,需要更多具体细节,而且从我的角度来看,我甚至不清楚我要问的是什么(或者它是否比你能分享的更详细)。希望了解有关如何计算合并结果的这一点额外信息将提供一些见解。

答案 1 :(得分:0)

  

我们刚刚遇到了自动合并提交的问题,其中包含一些行   已被删除,不应删除。然后我们修复它   手动,但它只是再次发生。

恕我直言,看起来有一个冲突(或冲突),在合并之前没有正确解决。仅当您所做的更改不干扰(例如,位于不同文件中)与当前位于远程存储库上的更改同时未在您当前工作树中反映时,才会发生自动合并。

  

我们目前有更多类似SVN的Git工作流程:只有一个   每个人都应该承诺(&#34;开发&#34;),我们只使用   a&#34;发布&#34;分支到&#34;冻结&#34;当前的发展状态,修复   那里的主要问题,并将其合并到&#34; master&#34;一旦它   足够稳定。但是,执行有问题的合并以进行合并   一个本地分支进入远程开发分支,所以没有   &#34;实&#34;已合并的分支。

所以让我直截了当 - 有起源/开发,起源/主人(制作)和起源/发布(因为你已经称之为:冻结)。每个人都在本地工作,当你的工作完成后,你会将你的变化推向原点/发展?如果是这样的话,那就是可能发生的事情(A - Alice,B - Bob):

  1. A 克隆或在本地拉取当前原点/ dev。
  2. A 正在努力开发新功能......
  3. Meanwhille B 克隆或在本地拉取当前来源/ dev,因为他需要在READ.ME文件中快速修复。
  4. B 完成了他的工作,他做了承诺&amp;推,所以他的修复程序目前在origin / dev。
  5. A 终于完成了她的工作(这个功能很棒BTW)。现在她想要承诺并推动。但是,origin / dev的状态已经改变了,所以现在:
    • 如果她没有触及 B&#39> 文件 - 她可以拉(已更改的READ.ME文件),然后推送合并后的更改。
    • 如果她对 B&#39> 文件中的任何一个进行了更改(尤其是在B发生更改的行中),则会发生冲突并且git不知道是谁版本没关系? A&B,S&B甚至两者?
  6. 所以现在,如果Alice解决了冲突,取出她的文件版本并将冲突标记为已解决然后推送,源/ dev上的READ.ME将丢失B的更改。这就是你的情况可能发生的事情。

    她要做的是手动解决此冲突。因为现在,在B&#39; s改变后,她的代码可能根本不需要,或者另一方面,她可能需要将他们的改变结合起来进行相互改变。

      

    我的问题是我不知道为什么Git会选择删除它们   我也不知道在哪里寻找有关它的信息。

    据我所知,如果没有告知,Git就可以删除代码中的任何部分。也许有人推动这些改变只是采用了他们的,并覆盖了之前在分支中出现的代码。就像在这张图片中一样:

    enter image description here

      

    这可以以某种方式确定,或者有人已经告诉我什么   可能导致决定删除代码?我们怎样才能防止   发生的事情(手动合并除外)?

    当您的整个团队处理相同的文件并且您将其推送到单个开发分支时,手动合并迟早是必须的。

      

    旁注:该存储库中的大多数人都使用Git客户端构建   进入Visual Studio(版本2015和2017),我想每个人都是   正在参与发生的问题(父母的创造者   合并提交的提交)正在使用该客户端。

    由于我主要使用WebStorm作为我的主要IDE,有时候使用SourceTree浏览我们的git存储库,不幸的是我对VS 2015/17中的git客户端有一点了解。这些链接可能会有所帮助:

    Resolve merge conflicts

    Using Git for .NET

    我希望它能够解决你的问题。