简体   繁体   English

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

[英]Git strategy to backport bugfixes into older branches (cherry-pick vs. merge)

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; 我们的GitHub仓库中只有一个master分支,它不稳定 - 认为每天都被推到那里; for stable releases we use tags (for development, we use private forks on GitHub) 对于稳定版本,我们使用标签(用于开发,我们在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...) 我们每3周发布一个新的次要版本,其中包含错误修正和新功能(比如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. 我们还必须在有限的时间内(几个月)维护每个次要旧版本,所以当有人使用1.2.4而最新版本为1.2.7时,他们发现了一个错误,他们可以请求我们修复bug在他们使用的分支上。 Then we release a patch version , 1.2.4A. 然后我们发布补丁版本 1.2.4A。
  • patches are rather exceptional. 补丁非常特殊。 We usually do no more than 1-2 patches for the minor release. 对于次要版本,我们通常不会超过1-2个补丁。 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? 问题是,同时修复master和旧分支上的bug的最佳策略是什么?

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 . 修复master上的bug,然后checkout v1.2.4 ,然后挑选相应的提交(假设bugfix是一个始终保持的提交)并将结果提交标记为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 . Checkout v1.2.4 ,修复bug并提交,将提交标记为v1.2.4A ,并将其合并到master ,进行合并

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). 当然,当中间提交引入一些重大更改时可能会变得复杂,这些更改可能导致无法创建在1.2.4和master中都有效的提交 (例如,当某些函数名称更改时)或更复杂的事情)。 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 . 假设我在v1.2.4上修复了一个问题,但有几天有人要求我在v1.2.3修补一个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. 您可以在Linux内核如何执行稳定版本中看到这一点,例如:开发人员为主线提交补丁,但也提名它们以包含在稳定版中。

When cherry-picking in this situation, you probably want to use the -x flag: 在这种情况下挑选时,你可能想要使用-x标志:

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 (eg backporting a fix to a maintenance branch for an older release from a development branch), adding this information can be useful. ... [如果]您在两个公开可见的分支之间进行挑选(例如,从开发分支向旧版本的维护分支向后移植修复),添加此信息可能很有用。

Your strategy 2, first fixing the bug on the prior release branch, eg v1.2.4 and then merging that change to your development trunk, is suggested by gitworkflows(7) : 您的策略2,首先修复先前版本分支上的错误,例如v1.2.4 ,然后将该更改合并到您的开发中继,由gitworkflows(7)建议:

Rule: Topic branches 规则:主题分支

Make a side branch for every topic (feature, bugfix, …). 为每个主题(功能,错误修复,...)制作一个侧支。 Fork it off at the oldest integration branch that you will eventually want to merge it into. 在最旧的集成分支中解决它,您最终希望将其合并到其中。 [ emphasis added ] [ 强调补充 ]

Many things can then be done very naturally: 然后很多事情可以很自然地完成:

To get the feature/bugfix into an integration branch, simply merge it. 要将功能/错误修复纳入集成分支,只需将其合并即可。 If the topic has evolved further in the meantime, merge again. 如果主题在此期间进一步发展,请再次合并。 (Note that you do not necessarily have to merge it to the oldest integration branch first. For example, you can first merge a bugfix to next, give it some testing time, and merge to maint when you know it is stable.) (请注意,您不必首先将其合并到最旧的集成分支。例如,您可以先将错误修复合并到下一个,给它一些测试时间,并在知道它稳定时合并到maint。)

One reason that this tends to work well is that in my experience, stuff gets added more frequently than it gets removed, so by making the change in the older branch, you avoid depending on any new functions etc. which may be available in the development trunk. 这种方法运行良好的一个原因是,根据我的经验,东西比被删除的东西更频繁地添加,因此通过在旧分支中进行更改,您可以避免依赖于开发中可用的任何新功能等。树干。

However you have to think about which branch you are targeting for the fix when you make the change , instead of just doing it on master and then deciding where to merge it. 但是,在进行更改时 ,您必须考虑针对修复的目标分支,而不是仅在master进行修改 ,然后决定将其合并到何处。

Both strategies are viable and there are benefits to each. 这两种策略都是可行的,每种策略都有好处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM