Git策略将错误修复反馈到旧分支(cherry-pick vs merge) [英] Git strategy to backport bugfixes into older branches (cherry-pick vs. merge)

查看:238
本文介绍了Git策略将错误修复反馈到旧分支(cherry-pick vs 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次。对于大多数版本,我们不做补丁。



问题是,修复错误的最佳策略是什么在主人和老分行同时?

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


  1. 修正 master 中的错误,然后签出 v1.2.4 ,然后 cherry-pick 适当的提交(假设bug修复是一个始终有效的提交)并将结果标记为 v1.2.4A

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


我宁愿支持第一个版本(樱桃采摘),但我想听听其他人对专业人士的评论and cons。

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



主人挑选樱桃的优势:




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

      | <在master 
    |上完成的错误修复
    |
    | < - v1.2.7
    ...
    |
    |
    |
    |
    |
    |
    |
    |
    |
    | - < - v.1.2.4A(从主人挑选)
    | /
    | < - v1.2.4

    vs this:

      | <  -  bugfix合并为主
    | \
    | \
    | |
    | | < - v1.2.7
    ...
    | |
    | |
    | |
    | |
    | |
    | |
    | |
    | |
    | |
    | - < - v.1.2.4A(直接修正错误)
    | /
    | < - v1.2.4

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

  • 我们假设我解决了 v1.2.4 但几天后有人要求我在 v1.2.3 上打补丁。 Cherry-pick是最明智的方法。


在我们的案例中,合并有什么优势吗?忽略了?我可以理解,它比樱桃采摘更好地保留了两个提交之间的连接,但是我们保留了一个发布的文档,所有这些也都在那里进行跟踪。

解决方案

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



当樱桃采摘在这种情况下,您可能需要使用 -x 标志:


记录提交,在
中添加一行说(樱桃挑选
从提交...)到原来的提交消息,以指明哪些提交此更改是从中挑选出来的。这是
仅适用于樱桃选择没有冲突。 ... [如果]
您在两个公开可见的分支之间进行樱桃选择(例如
将补丁从
a开发分支中恢复为维护分支),添加此信息可以是有用的。



We work as follows in our team:

  • we have only a master branch in our GitHub repo, it's not stable - thinks get pushed there each day; for stable releases we use tags (for development, we use private forks on GitHub)
  • we release a new minor version every 3 weeks, which contains bugfixes and new features (say 1.2.4, 1.2.5, 1.2.6...)
  • we also have to maintain each minor old version for a limited amount of time (few months), so when someone uses 1.2.4 while the newest version is 1.2.7, and they find a bug, they can request us to fix the bug on the branch they use. Then we release a patch version, 1.2.4A.
  • patches are rather exceptional. We usually do no more than 1-2 patches for the minor release. For most of the releases we don't do patches.

The question is, what's the best strategy to fix the bug on master and the old branch at the same time?

I can think of the two main strategies:

  1. Fix the bug on master, then checkout v1.2.4, then cherry-pick the appropriate commit (suppose the bugfix is one commit which always holds) and tag the resulting commit as v1.2.4A.

  2. Checkout v1.2.4, fix the bug and commit, tag the commit as v1.2.4A, and to incorporate it to master, do a merge.

I'm rather in favor of the first version (cherry-picking), but I would like to hear the other's comments about pros and cons.

Of course, things can get complicated when the commits in the middle introduce some major changes that can result in the fact that one can't create a commit which will work in both 1.2.4 and in master (for instance when some function name changed or more complicated things). But the more common situation is that the fix can be ported without problems.

Advantages of cherry-picking from master:

  • I think the history is more "eatable" with cherry-picking. Consider this:

    | <- 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
    

    Think of having dozens of commits in between. Consider having multiple patches applied like this in parallel. Half of the screen will be polluted.

  • Let's say I fixed an issue on v1.2.4, but in a few days someone asks me for a patch on v1.2.3. Cherry-pick is the most sensible way to do it.

Are there any advantages of merging in our case that I overlooked? I can understand it preserves the connection between the two commits better than cherry-picking, but we keep a documentation of releases and all of this is also tracked there.

解决方案

In open source projects that I've worked on, the consensus seems to be that fixes should land on master first, be tested there, and only then be back-ported to older releases. You can see this in how the Linux kernel does stable releases, for example: Developers submit patches for mainline but nominate them for inclusion in stable as well.

When cherry-picking in this situation, you probably want to use the -x flag:

When recording the commit, append a line that says "(cherry picked from commit ...)" to the original commit message in order to indicate which commit this change was cherry-picked from. This is done only for cherry picks without conflicts. ... [If] you are cherry-picking between two publicly visible branches (e.g. backporting a fix to a maintenance branch for an older release from a development branch), adding this information can be useful.

这篇关于Git策略将错误修复反馈到旧分支(cherry-pick vs merge)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆