草庐IT

Git 将错误修复反向移植到旧分支的策略(cherry-pick vs. merge)

coder 2023-06-24 原文

我们团队的工作方式如下:

  • 我们的 GitHub 存储库中只有一个 master 分支,它不稳定 - 每天都会被推送到那里;对于稳定版本,我们使用标签(为了开发,我们在 GitHub 上使用私有(private)分支)
  • 我们每 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 上的错误,然后 checkout v1.2.4,然后 cherry-pick 适当的提交(假设错误修复是一个始终持有的提交)并将生成的提交标记为 v1.2.4A

  2. checkout v1.2.4,修复错误并提交,将提交标记为 v1.2.4A,并将其 merge 到 master,执行 merge

我更倾向于第一个版本(cherry-picking),但我想听听其他人对优缺点的评论。

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

从大师那里 cherry-pick 的优势:

  • 我认为 cherry-pick 后的历史更“可食用”。考虑一下:

    | <- 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 上的补丁。 Cherry-pick 是最明智的做法。

在我们的案例中,是否有任何我忽略的 merge 优势?我可以理解它比 cherry-picking 更好地保留了两个提交之间的联系,但我们保留了一份发布文档,所有这些也都在那里进行了跟踪。

最佳答案

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

在这种情况下进行挑选时,您可能希望使用 -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 (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),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13275223/

有关Git 将错误修复反向移植到旧分支的策略(cherry-pick vs. merge)的更多相关文章

  1. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  2. git使用常见问题(提交代码,合并冲突) - 2

    文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g

  3. ruby - Dropbox 类似 git 的服务——没有 rsync 和 inotify - 2

    关于如何使用git设置类似Dropbox的服务,您有什么建议吗?您认为git是解决此问题的合适工具吗?我在考虑使用git+rush解决方案,你觉得怎么样? 最佳答案 检查这个开源项目:https://github.com/hbons/SparkleShare来自项目的自述文件:Howdoesitwork?SparkleSharecreatesaspecialfolderonyourcomputer.Youcanaddremotelyhostedfolders(or"projects")tothisfolder.Theseprojec

  4. ruby - 混帐 & ruby : How can I unset the GIT_DIR variable from inside a ruby script? - 2

    我编写了一个非常简单的“部署”脚本,作为我的裸git存储库中的post-updateHook运行。变量如下livedomain=~/mydomain.comstagingdomain=~/stage.mydomain.comgitrepolocation=~/git.mydomain.com/thisrepo.git(bare)core=~/git.mydomain.com/thisrepo.gitcore==addedremoteintoeachlive&stagegitslive和stage都初始化了gitrepos(非裸),我已经将我的裸仓库作为远程添加到它们中的每一个(名为co

  5. ruby - 让 bundler 使用 http : instead of git:? - 2

    我正在安装gitlabhq,并且在Gemfile中有对某些资源的“git://...”的引用。但是,我在公司防火墙后面,所以我必须使用http://。我可以手动编辑Gemfile,但我想知道是否有另一种方法告诉bundler使用http://作为git存储库? 最佳答案 您可以通过运行gitconfig--globalurl."https://".insteadOfgit://或通过将以下内容添加到~/.gitconfig:[url"https://"]insteadOf=git://

  6. ruby-on-rails - 在 Ruby 或 Rails 中,hash.merge({ :order => 'asc' }) can return a new hash with a new key. 什么可以返回带有已删除键的新散列? - 2

    在Ruby(或Rails)中,我们可以做到new_params=params.merge({:order=>'asc'})现在new_params是一个带有添加键:order的散列。但是是否有一行可以返回带有已删除key的散列?线路new_params=params.delete(:order)不会工作,因为delete方法返回值,仅此而已。我们必须分3步完成吗?tmp_params=paramstmp_params.delete(:order)returntmp_params有没有更好的方法?因为我想做一个new_params=(params[:order].blank?||para

  7. ruby-on-rails - 安装 active admin 时 activeadmin.git (at master) is not yet checked out 错误 - 2

    Activeadmingem已添加到我的rails项目中,但每次我尝试安装railsgactive_admin:install时,我都会收到类似的错误git://github.com/activeadmin/activeadmin.git(atmaster)isnotyetcheckedout.Runbundleinstallfirst.我肯定在运行“railsgactive_admin:install”之前运行了bundle。运行“bundleshow”后,我看到我已将“*activeadmin(1.0.0.pre3f916d6)”添加到我的项目中,但不断收到此错误消息。我的gem文

  8. ruby - 如何修复 RVM gem "[ missing bin/ruby ]" - 2

    执行rvmlist后,我得到以下输出:rvmrubiesgems[missingbin/ruby]=*ruby-2.0.0-p645[x86_64]ruby-2.1.6[x86_64]ruby-2.2.1[x86_64]gems[missingbin/ruby]是什么意思?gems是某种系统gemset吗?它不是我创建的,我不知道我是否可以或应该删除它。 最佳答案 在我跑完之后:rvmfix-permissions然后我能够卸载具有[缺少bin/ruby]的版本。 关于ruby-如何修复

  9. ruby-on-rails - 可移植 Ruby on Rails 环境 - 2

    我给自己买了一个新的8gigUSBkey,我正在寻找一个合适的解决方案来拥有一个可移植RoR环境来学习。我在谷歌上搜索了一下,发现了一些可能性,但我很想听听一些现实生活中的经历和意见。谢谢! 最佳答案 我喜欢InstantRails,非常容易使用,无需安装程序,也不会修改您的系统环境。 关于ruby-on-rails-可移植RubyonRails环境,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/q

  10. ruby - 如何让 GitHub 页面使用 master 分支? - 2

    我有一个使用Jekyll托管在GitHub上的静态网站。问题是,我真的不需要master分支,因为存储库唯一包含的是网站。这样我就必须gitcheckoutgh-pages,然后gitmergemaster,然后gitpushorigingh-pages。有什么简单的方法可以摆脱gh-pages分支并直接从master推送? 最佳答案 Theproblemis,Idon'treallyneedthemasterbranch,astheonlythingtherepositorycontainsisthewebsite.Isthere

随机推荐