Git策略将错误修正反向旧版分支(cherry-pick vs. merge)

时间:2012-11-07 17:44:31

标签: git git-merge

我们的团队工作如下:

  • 我们的GitHub仓库中只有一个master分支,它不稳定 - 认为每天都被推到那里;对于稳定版本,我们使用标签(用于开发,我们在GitHub上使用私人分支)
  • 我们每3周发布一个新的次要版本,其中包含错误修正和新功能(例如1.2.4,1.2.5,1.2.6 ......)
  • 我们还必须在有限的时间内(几个月)维护每个次要旧版本,所以当有人使用1.2.4而最新版本是1.2.7时,他们发现了一个错误,他们可以要求我们修复他们使用的分支上的错误。然后我们发布补丁版本,1.2.4A。
  • 补丁非常特别。对于次要版本,我们通常不会超过1-2个补丁。对于大多数版本,我们不做补丁。

问题是,同时修复master和旧分支上的bug的最佳策略是什么?

我可以想到两个主要策略:

  1. 修复master上的错误,然后结帐v1.2.4,然后 cherry-pick 相应的提交(假设错误修正是一个始终保持的提交)并且将生成的提交标记为v1.2.4A

  2. 结帐v1.2.4,修正错误并提交,将提交标记为v1.2.4A,并将其合并到master,执行合并

  3. 我更赞成第一个版本(挑选樱桃),但我想听听对方关于利弊的评论。

    当然,当中间的提交引入一些重大更改时会出现问题,这些更改可能会导致无法创建在1.2.4和主服务器中都能正常工作的提交(例如当一些函数名称改变或更复杂的事情)。但更常见的情况是修复程序可以毫无问题地移植。

    从主人那里采摘樱桃的好处:

    • 我认为樱桃采摘的历史更“可食用”。考虑一下:

      | <- bugfix done on master
      |
      |
      | <- v1.2.7
      ...
      |
      |
      |
      |
      |
      |
      |
      |
      |
      |  - <- v.1.2.4A (cherry-picked from master)
      | / 
      | <- v1.2.4
      

      vs this:

      | <- bugfix merged to master
      |\ 
      | \
      |  |
      |  |   <- v1.2.7
      ...
      |  |
      |  |
      |  |
      |  |
      |  |
      |  |
      |  |
      |  |
      |  |
      |  - <- v.1.2.4A (direct bugfix)
      | / 
      | <- v1.2.4
      

      想想中间有几十个提交。考虑并行应用这样的多个补丁。屏幕的一半将被污染。

    • 假设我在v1.2.4修复了一个问题,但有几天有人要求我在v1.2.3上修补一个问题。樱桃挑选是最明智的方式。

    在我们的案例中,我忽略了合并的优点吗?我可以理解它保留两个提交之间的连接比挑选樱桃更好,但我们保留了发布的文档,所有这些也在那里被跟踪。

2 个答案:

答案 0 :(得分:21)

在我参与过的开源项目中,共识似乎是修复应首先登陆,然后在那里进行测试,然后再将其移植到旧版本。您可以在Linux内核如何执行稳定版本中看到这一点,例如:开发人员为主线提交补丁,但也提名它们以包含在稳定版中。

在这种情况下挑选时,你可能想要使用-x标志:

  

录制提交时,添加一行“(樱桃挑选   从commit ...)“到原始提交消息以便   表明这个改变是从哪个提交中挑选出来的。这是   只为没有冲突的樱桃选择做。 ...... [如果]   你是在两个公开可见的分支之间挑选的(例如   向旧版本的维护分支向后移植修复程序   开发分支),添加此信息可能很有用。

答案 1 :(得分:9)

您的策略2,首先修复先前版本分支上的错误,例如gitworkflows(7)建议v1.2.4,然后将该更改合并到您的开发中继线:

  

规则:主题分支

     

为每个主题(功能,错误修复,......)制作一个侧支。 在最旧的集成分支中解决它,您最终希望将其合并到其中。 [强调添加]

     

很多事情可以很自然地完成:

     

要将功能/错误修复纳入集成分支,只需将其合并即可。如果主题在此期间进一步发展,请再次合并。 (请注意,您不必首先将其合并到最旧的集成分支。例如,您可以先将错误修复合并到下一个,给它一些测试时间,并在知道它稳定时合并到maint。)

这种方法运行良好的一个原因是,根据我的经验,东西的添加次数比删除的次数要多,因此通过在旧分支中进行更改,您可以避免依赖可能可用的任何新功能等在开发主干中。

但是,您必须考虑在进行更改时针对修复定位哪个分支,而不是仅仅在上执行此操作,然后决定合并的位置它

这两种策略都是可行的,每种策略都有好处。