20

我们在团队中的工作如下:

  • 我们的 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. 修复 bug master,然后 checkout v1.2.4,然后选择适当的提交(假设 bugfix 是一个始终存在的提交)并将生成的提交标记为v1.2.4A.

  2. v1.2.4出,修复错误并提交,将提交标记为v1.2.4A,并将其合并到master,进行合并

我更赞成第一个版本(樱桃采摘),但我想听听其他人关于利弊的评论。

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

师傅摘樱桃的好处:

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

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

    与这个:

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

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

  • 假设我修复了一个问题v1.2.4,但几天后有人问我要一个补丁v1.2.3。樱桃采摘是最明智的做法。

在我忽略的情况下,合并有什么好处吗?我可以理解它比樱桃采摘更好地保留了两个提交之间的联系,但是我们保留了发布文档,并且所有这些都在那里进行了跟踪。

4

2 回答 2

28

在我从事的开源项目中,共识似乎是应该首先在 master 上进行修复,在那里进行测试,然后才能向后移植到旧版本。您可以在 Linux 内核如何发布稳定版本中看到这一点,例如:开发人员为主线提交补丁,但也提名它们包含在稳定版本中。

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

记录提交时,在原始提交消息中附加一行“(cherry pick from commit ...)”,以指示此更改是从哪个提交中挑选出来的。这仅适用于没有冲突的樱桃采摘。... [如果]您在两个公开可见的分支之间进行挑选(例如,将修复从开发分支向后移植到维护分支以获取旧版本),添加此信息可能很有用。

于 2012-11-07T18:24:00.547 回答
12

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

规则:主题分支

为每个主题(功能、错误修复……)创建一个分支。在您最终希望将其合并到的最旧的集成分支上分叉它。[强调补充]

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

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

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

但是,当您进行更改时,您必须考虑要修复的分支是哪个分支,而不是仅仅在master上执行,然后决定在哪里合并它。

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

于 2014-10-08T18:52:42.750 回答