如何处理复杂的合并


25

这是一笔交易,我加入了一家新公司,并被要求完成在已经近一年没有碰过的分支机构上的工作。同时,主分支机构也在稳定增长。理想情况下,我希望将master分支中的所有更改合并到feature分支中,然后从那里继续工作,但是我不太确定该如何处理。

如何在保留分支两侧的重要更改的同时安全地执行此合并?


多谢大家的宝贵意见。我要去git-imerge,如果结果很乱,我将使用新的分支方法!
Vlad Spreys,2015年

谁能解释为什么我们不能git cherry-pick在这里使用?
Santosh Kumar 2015年

1.祈祷。2.变基。3.测试。4.合并。
AK_15年

1
我更喜欢在这种情况下重新部署,因为它将逐个提交。它还使您可以压缩新功能,然后再使用合并的代码。YMMV。
斯蒂芬

Answers:


27

从本质上讲,如何组合两个(可能是不兼容的)代码段是一个开发问题,而不是版本控制问题。Git merge命令在此过程中可能会有所帮助,但这取决于问题的形式。

首先将两个版本与基准进行比较是最有意义的。这将为您提供最佳方法,以实现这一目标。根据每个分支中更改的性质和重叠情况,您的方法可能有所不同。

想象一下理想的情况:您会发现main分支和feature分支各自仅修改了代码的互斥部分,因此您只需提交所有更改即可。

当然,几乎肯定不是这种情况,但是问题是:与理想情况相距多远?即这些变化有多混杂?

另外,旧功能分支的成熟程度如何?它是否处于良好的工作状态(或未知)?完成了多少功能?

如果主分支中的相关代码在过去的一年中发生了很大变化,或者该功能尚未处于非常成熟的状态,则可以考虑创建一个最新的分支,并手动将其合并。 这将使您能够采用渐进的方法使其正常运行。

如果您进行了很多代码的混乱合并而无法正常工作,则将很难调试。如果主分支在过去一年中发生了很大变化,则可能需要对该功能进行重大设计更改才能使其正常工作。通过“解决冲突”进行这些更改是不合适的,因为这将需要立即进行所有更改并希望它能起作用。旧的部分完成的分支中可能存在错误,这会使问题变得更加复杂。


+1“我可能会考虑创建一个最新的分叉,并手动将旧功能再次纳入其中”
mika,2015年

1
第一个关键问题是:是否建立了旧功能分支?它运行吗?如果没有,将很难测试您的合并。
莫兹

22

以我有限的git经验,我可以说有时候,如果主服务器离分离点太远,重新启动功能分支会更快。

在不知道代码背后的历史的情况下合并两个分支(假设您刚刚加入该项目)确实很困难,我敢打赌,即使是从一开始就关注该项目的开发人员也可能在合并中犯一些错误。

如果要素分支不是很大,这当然是有道理的,但是您可以简单地保持旧的要素分支处于打开状态,再次从master 分支,然后手动重新引入组成该要素的更改。我知道这是最手动的方法,但是在丢失或移动代码的情况下,它可以让您完全控制。

在这种情况下,与高级人员进行配对编程将是最好的情况,从而帮助您更好地了解代码。
如果考虑到合并冲突和测试时间,它甚至可能会变得更快。

我有点假设,至少尝试进行合并显然是最好的选择。如果失败或变得太困难,请尝试摘樱桃,如果出错,请手动进行。


2
绝对不是正确的方法。
安迪

12
不,这是正确的方法-如果您有一个古老的分支,并且您不知道代码,那么尝试合并将不会非常成功,并且会带来很大的风险。确定最初所做的更改,调查它们是否与新代码相关,然后将其应用为有意义的方法就是这样做。这是一种手动方法,但是在这种情况下,这是唯一安全的方法。当然,我仍然会先尝试合并,只是为了查看会发生什么,并且我会检查日志以查看分支上也发生了多少更改-可能是微不足道的。
gbjbaanb 2015年

10
@DavidPacker:我不认为GavianoGrifoni建议将所有工作都扔掉。他建议逐步将变更从旧分支手动转移到当前开发线。那将抛弃旧的历史,仅此而已。
布朗

3
@DavidPacker第一个:分支已过期一年,第二个:完成任务的家伙根本不知道代码。考虑到这两个因素,手动重新应用是处理任务的唯一现实方法。没有人建议对旧分支的技巧修订版进行简单的复制粘贴。
gbjbaanb 2015年

5
@DavidPacker:合并冲突可能会变得很邪恶-如果必须先解决500个冲突,然后才能使程序再次处于可编译和可测试的状态。OP在这里期望的就是这种情况。如果您认为可以有效地使用git来避免这种“全有或全无”的情况,那么为什么不编辑答案并告诉OP如何做到这一点呢?
布朗

16

git-imerge正是为此目的而设计的。这是一个git工具,提供了一种增量合并的方法。通过增量合并,您只需要处理两个版本之间的冲突,就不再需要更多了。此外,由于各个变更集较小,因此可以自动执行大量合并。


6

尝试将主线头合并到一年陈旧的分支中可能会令人沮丧,并且会使您的额头加深办公桌上的凹痕。

在几个月的时间里,主线一站式到达目的地。它也有开发和发布。试图在一个整体合并中将其全部更新可能是压倒性的。

取而代之的是,从陈旧的分支拆分后,从第一个功能合并到主线开始合并。获取合并的工作。然后下一个功能合并。等等。这些功能合并中有许多将合并而不会发生冲突。确保陈旧分支的当前功能保持与主线前进方向兼容仍然很重要。

您可能希望从陈旧的分支的顶部分支,以合并其他更改。这更多地是关于确保有人回顾时的提交和历史记录是清晰的,并传达每个分支的角色和策略。陈旧的分支是功能分支。您正在处理的是累积和对帐分支。

如果旧功能或发行分支仍然存在并且可以轻松访问,则许多操作会更容易(某些地方制定了清理早于某个日期的分支名称的策略,以使分支列表不会被淹没) )。

所有这些重要的事情是确保在成功将主线历史记录的每个部分合并到位之后进行测试和修复。即使某些内容可以合并而不会发生冲突,但这仅表示代码没有冲突。如果过时或过时的陈旧功能访问方式已删除或删除,则在成功合并后可能需要修复。

顺便说一句,这也适用于其他版本控制系统。我偶尔需要将一组特定的svn提交合并到一个分支的分支(樱桃采摘)中,修复该分支以使用该功能,然后合并下一组svn提交而不是仅仅进行批发的svn合并。

虽然可以在此处进行git cherry-pick,并且确实允许引入特定的提交,但这有一些缺点,可能会使过程复杂化。樱桃选择不会显示有关您从中选择的提交的信息(您可以将其附加到提交消息中)。这实际上使跟踪历史记录中的提交更加困难。

此外,这意味着您将无法有效地将母版重播到陈旧的分支上-您将选择可能不完整的功能-且这些功能可能会乱序播放。

一个人应该从历史提交合并到陈旧分支上的关键原因是能够保留该分支,将其称为陈旧分支的“未来历史”处于您可以推断的状态。您可以清楚地看到从历史到陈旧分支的合并,以及重新集成功能的修复程序。功能以与掌握相同的顺序添加。完成后,最后从master头合并到陈旧分支,您知道所有内容都已合并,并且不会丢失任何提交。


+1这是一个有趣的潜在替代解决方案,它使用合并来合并较大的更改。但是,我看到一个缺点:假设您有主要版本ABCDE,并且想要将功能分支A1合并到E中。将代码合并到BC和D中可能会花费很多精力。例如,如果D到E是重大的设计更改导致B,C和D的增量更改不相关?同样,它再次取决于该功能最初的成熟程度。一种有用的潜在方法,但是在开始之前需要考虑其适当性。

1

步骤1.了解代码,分析其体系结构,以及自最新的共同祖先以来在两个分支上所做的更改。

第2步。如果该功能看起来很独立,并且主要涉及不同的代码区域,合并,修复冲突,测试,修复等。这是一条很幸福的路,那么您就很高兴了。否则请转到步骤3

步骤3.分析冲突区域,详细了解功能影响和原因。在这里很容易发现业务需求冲突。与BA和其他适当的开发人员讨论。了解解决干扰所涉及的复杂性。

步骤4.根据上述情况,决定是否只合并/冲突/剪切/剪切粘贴不冲突的部分并重新编写冲突的部分,还是是否从头开始重新编写整个功能? 。


0

1.切换到用作主要开发者/发行者分支的分支。

这是包含对系统的最新更改的分支。可以mastercoredev,这取决于公司。在您的情况下,可能是master直接的。

git checkout master
git pull

拉动以确保您拥有最新版本的主要开发分支。

2.检出并拉出包含您应完成的工作的分支。

拉动以确保您确实具有分支的最新内容。通过直接检出它,而无需先在本地创建它,可以确保其中没有新的内容master(或分别来自主dev分支)。

git checkout <name of the obsolete branch>
git pull origin <name of the obsolete branch>

3.将主要开发分支合并到过时分支。

在运行以下命令之前,请通过键入git branchgit status确保您位于过时的分支中来确保。

git merge master

git merge命令将尝试将指定分支(在本例中)的内容合并master到当前所在的分支。

着重于会尝试。可能存在合并冲突,您和您仅需要解决。

4.修复合并冲突,提交并推送冲突修复

修复所有文件中的合并冲突后,暂存,提交并将冲突解决方案推送到origin

git add .
git commit -m "fixed the merge conflict from the past year to update the branch"
git push

通常,您可以调用git add .暂存所有文件以进行提交。处理合并冲突时,您希望所有必要的文件都被更新。

附加说明

解决合并冲突可能是一件乏味的工作。特别是如果您是公司的新手。您甚至可能没有足够的知识来单独解决所有合并冲突。

在继续工作之前,请花点时间仔细检查所有已发生的冲突并适当解决它们。


可能会发生这种情况,您开始在一个成立了一年的分支机构上工作,将当前的开发状态合并到该分支中,而根本不会发生任何合并冲突。

即使系统在一年中发生了很大变化,却没有人碰过在一年历史分支中实际更改过的文件,就会发生这种情况。


6
#4可能是问题所在。如果去年有很多更改,则可能需要对旧功能进行重大更改。通过合并执行此操作要求您一次性对代码进行重大更改,并希望它能起作用,这不是好的开发实践。还有谁知道未完成功能的状态是什么?您可能最终会陷入一大堆无法工作的代码,谁知道这是由于原始代码的问题还是您所做的更改导致的?

David,只要此标准方法可行,就可以了,OP应该首先尝试这种方法。但是,在上述情况下,绝对有太多合并冲突的风险,无法以“全有或全无”的方式处理它们。
布朗

@ dan1111存在合并冲突是完全可以的,实际上,解决它们是解决之道。由于分支保持了一年不变,因此您可以肯定它并不重要,不会影响整个系统。因此,即使分支落后了一年,您也只能获得2到无合并冲突。
安迪

4
该分支不重要的假设是没有根据的。可能是根本的设计更改,被放弃,现在又被重新使用。可能是任何东西。你是正确的,它可能是一件简单的事,有可能是很少或没有冲突-在这种情况下,你的答案是正确的。但这不是唯一的可能性。

@ dan1111如果某人一年都没有碰过另一个分支中的某个特色地点,那么它对系统的更改不会有太多的影响。这来自我自己对过时的分支机构(超过6个月大)的经验。
安迪
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.