“经常”合并是更好还是仅在功能分支完成大合并之后合并?


40

说多个分支正在开发中,A并且B,还有一个增量“错误修复”分支C

现在C已经“完成”并合并到母版中。A并且B仍在开发中,并且不会在(可能)另一个错误修复分支合并到master中之前进行修复。

C尽快合并到新功能分支中是一个好主意吗?以便使新功能尽可能接近master?还是让新功能在自己的“世界”中开发,然后在完成后才合并到母版中更好?

无论如何都会有冲突,因此需要花费时间来解决这些冲突。



5
关于将功能合并到主行的@gnat,我想知道在开发功能时将主功能合并到功能是否良好,可以“尽早解决冲突”。
paul23

1
@ paul23,我要说这是实际需要。
Berin Loritsch

3
老实说,当我开始在代码上使用正确的设计时,例如隔离模块和创建定义良好的工作模型,我的大量版本问题就消失了。如果您在合并期间在问题上踩得太多,则可能在另一个地方潜伏着另一个更严重的问题。一个好的设计对于避免不必要的冲突非常有帮助。
T. Sar-恢复莫妮卡

2
您可能希望定期与主管理员合并,以保持足够的“亲密感”,以免以后合并太麻烦。
托尔比约恩Ravn的安徒生

Answers:


71

分支的生存时间越长,它与主分支和分支之间的分歧就越大,最终完成的合并将变得更加复杂。与1个大冲突相比,十个小冲突更容易解决,并且实际上可能阻止开发人员重复或浪费精力。鉴于这种情况,你应该合并masterAB规律; 每天一次的建议是很常见的建议,不过,如果分支机构有很多活动,则可能希望每天合并多次。

除了使冲突解决更容易之外,您还特别提到C了一个错误修正分支。作为开发人员,我希望我的分支机构拥有所有最新的错误修正,以确保我不会重复导致错误的行为,也不会基于错误数据编写测试。

无论如何都会有冲突,因此需要花费时间来解决这些冲突。

如果您知道会有冲突,则不妨采用其他分支策略。尽可能在同一分支上对同一文件进行多次更改,从而减少或消除冲突的数量。重构故事,以便它们尽可能完全独立,并重做分支以涵盖多个故事(分支,功能和故事并不总是可互换的)。


33
合并或变基,因为变基通常会产生更清晰的提交历史记录。
克莱里斯

11
@chrylis:如果“分支涵盖多个故事”表示两个开发人员在同一个分支上工作,则重新定级可能很危险
meriton-罢工

9
来自官方文档的@meriton:不要对存储库外部存在的提交进行重新基准设置,否则人们可能会基于它们进行工作。如果您遵循该准则,就可以了。如果您不这样做,人们会讨厌您,并且您会受到朋友和家人的嘲笑。哈哈
Xtreme Biker

6
@XtremeBiker:Git中的一个基础更改了历史记录。在这方面,Git就像现实生活一样:为了改变历史,您需要阴谋。Git本身在存储库中有一个分支,该分支会定期重新设置基础,并且是一个高度公开的分支。之所以起作用,是因为存在一个阴谋:每个使用此分支的人都同意在某些时候重写历史,因此他们将确保能够在那些时候合并所有内容。
约尔格W¯¯米塔格

1
@ paul23在将A和B交付给主分支之前,请认真考虑将其交付给新的共享分支。如果它们都是彻底的大修,则您希望它们一起进行一轮测试,然后再对母版进行组合。如果您有信心,可以将一个直接交付给master,然后将另一个交付给新的更新分支。您可能希望能够从第二个功能中查看原始代码,以防合并失败或需要重新设计某些内容。
Sinc

11

假设您打算最终将A,B合并回master并维护单个代码库,那么偏离master绝不是一个好主意。与master的偏离时间过长,尤其是在开发A,B时将错误修复和其他开发合并到master时,肯定会引起冲突。

我会考虑类似以下的策略

  1. 负责A,B的任何人都应密切注意主人并合并所有更改。
  2. 更好的是,如果您具有构建和测试自动化功能,请确保A,B合并到主服务器中,并每晚通过测试。
  3. 根据您对其他答案的评论,似乎A,B可能需要一段时间才能发展。在这种情况下,您甚至可以考虑将A,B彼此合并,这样最终您就不会遇到将两者重新合并为master的麻烦。
  4. 在更高的层次上,考虑一下为什么需要两条单独的长期开发线。您可以分解成较小的合并吗?您可以分为单独的微服务吗?

5

通常通常比大规模的要好。

较小,更频繁的请求请求几乎总是更好。

我主要开始使用配置标志,以便可以提早执行较小的拉取请求,从而可以更轻松地合并代码,但不激活该功能。拉取请求越小,即使总拉取请求更多,也更容易查看代码。任何种类的大多数人将无法对大量拉取请求进行有意义的审核。要了解大量代码更改可能带来的所有影响,这真是太难了。

创建配置标志会产生额外的开销,因此在较小的功能上不值得。但是无论如何,您的拉取请求将很小。

但是,在某些情况下,必须立即释放所有功能。即便如此,最好还是将较小的请求发送给为此目的而创建的另一个分支。

当有人提出大量拉动请求时,我的大多数同事吟,这在大多数情况下是正确的。

还要注意,有时我需要将提交挑选到单独的分支中。如果需要将需要采摘的东西放入单个提交中,则可以更轻松地将其移动到其他分支。在这种情况下,实际上很少提交会更好,但是如果您选择樱桃,那也不完全是标准过程。


1
功能标记可能会很昂贵(45分钟内耗资 4.5亿美元)。Bob叔叔提到了这个示例(但没有任何技术性的要求(正如人们所期望的那样))。
Peter Mortensen

1
是的,最终删除它们会有开销,尽管通常不会那么困难。可以将它们维护更长的时间,但是该标志提供了更大的用途。我同意,如果偶然地或没有采取后续行动,事情可能会变得很糟。虽然当大的拉取请求变得难以审核时情况可能会变糟。另一方面,某些人可能无法向他们正在使用的应用添加类似配置标志的内容。通常,它有助于UAT和功能的推出。
Mark Rogers

3

在马丁·福勒(Martin Fowler)的《重构》中,他给出的建议绝不是让分支从master分支超过一天。IIRC,您应该进行一些小的更改,进行测试以确保您没有破坏任何东西,然后将其合并回去。


2
好吧A,请B对应用程序的工作方式进行重大的彻底改革,它们不会在一个月内“完成”。但是,它们在完成之前也没有用……
paul23

8
在完成之前,它们可能不是没有用的-它们通过迈向全面成果并减少将来所需的工作来提供价值。使用功能切换,抽象分支或仅在最后完成用户界面部分之类的技术,应该可以安全地将不完整的工作合并到母版中。
bdsl

1
这就是为什么在master分支中的任何更改之上重新部署本地资源对于长期开发非常方便。保持您的工作好像是最新的分支一样
NKCampbell

2

对于可能已经完成但尚未准备好使用的长期更改,另一种选择是将它们放在功能标记后面,以便可以将其合并到母版中,而不会破坏任何内容。然后,当它们准备好使用时,可以删除功能标记。


1
功能标记=僵尸代码(直到复活)?
Peter Mortensen

@PeterMortensen好吧,您必须着眼于尽快删除标记,但是它可以在某些情况下
起作用

3
@PeterMortensen不是,如果至少有一个人打开了旗帜
伊恩
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.