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

jak*_*b.g 17 git git-merge

我们的团队工作如下:

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

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

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

  1. 修复bug master,然后检查v1.2.4,然后挑选适当的提交(假设错误修复是一个始终保持的提交)并将结果提交标记为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
    
    Run Code Online (Sandbox Code Playgroud)

    对此:

    | <- bugfix merged to master
    |\ 
    | \
    |  |
    |  |   <- v1.2.7
    ...
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  - <- v.1.2.4A (direct bugfix)
    | / 
    | <- v1.2.4
    
    Run Code Online (Sandbox Code Playgroud)

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

  • 假设我已经解决了一个问题v1.2.4,但是有几天有人问我补丁v1.2.3.樱桃挑选是最明智的方式.

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

Jam*_*arp 23

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

在这种情况下采摘樱桃时,你可能想要使用这个-x标志:

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


Col*_*ett 9

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

规则:主题分支

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

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

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

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

但是,在进行更改时,您必须考虑针对修复的目标分支,而不是仅在master进行修改,然后决定将其合并到何处.

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