git将添加到旧分支的新更改复制到分支中的最新工作



我有两个git分支,main是分支中的最新工作,prod-2022-08(旧的)是上个月在生产中部署的备份。如果我需要提供生产上的热修复程序,我将在prod-2022-08分支中进行更改并从该分支进行部署。现在,对于下一个生产版本,我希望对我在分支main中的最新工作进行更改,以便在main中包含热修复程序和新功能。我该怎么做?

基本上,cherry-pickmerge-取决于您在这些分支中拥有什么,您想要得到什么,以及您如何使用git来帮助您的工作。

假设你的代码是";"干净";,然后,首先考虑从prodmain的合并。这样做的好处是确保prod分支上所做的更改不会被意外遗忘。这意味着所有未来的"同步"方向都是:prod->to:main也可以用同样的方法完成,只需合并即可。这还有一个好处,如果你查看提交图,你可以很容易地看到是否有任何尚未同步的prod修复程序。我喜欢叫它back-merge

然而,这也有局限性。我想你了解merge的所有含义。由此产生了限制,以及我所说的";清洁";。

如果您在prod分支上保留任何对main分支不好的内容,那么您可能不应该执行纯合并。例如,这通常包括特定于环境的东西,如密码、密钥、服务URL、品牌资源等。除了这些资源之外,这也可能意味着您实际上不想跨分支移植的任何修补程序(然而,对于这些修补程序,我建议无论如何合并它们,然后在main分支上显式删除/恢复/撤消它们,因此在提交历史记录中有一个明确的指示,即(1)它们已被考虑,(2)决定不再保留在较新版本中)。

与环境相关的资源并不总是阻止反向合并工作流。这完全取决于你如何管理那些与环境相关的东西(如果你有它们的话)。跨prod/main合并可能是安全的,例如,如果将所有这些文件都保存在单独的文件(env.devel.configenv.prod.config等)中,这样它们就不会在合并过程中意外地相互覆盖。

如果你不知道你的代码库中是否有类似的东西,就试着做这样的prod->本地主合并,不要将其推到任何地方,并仔细分析合并的结果(merge-commit-diff-查看main上的提交发生了什么变化)。如果您看到任何不需要的东西流入main,只需中止/重置/etc合并即可。

现在,如果由于某种原因合并是不可行的,那么就像阿萨德在评论中建议的那样进行挑选。

Cherry pick的好处是,它不会自动选择任何您没有明确要求的提交。Cherry pick默认情况下会在分支之间复制一个提交(或范围),并将其复制。对于git来说,这将是main上的一个全新更改,只是顺便说一句,与prod分支的旧更改不太一样。cherry pick中的-x选项只为人类留下一条消息,因此如果需要,可以手动跟踪cherry picks,git不会将此消息用于任何事情。有时,在分支之间进行樱桃采摘非常有用,但如果经常这样做,随着复制的提交数量的增加,情况会很快变得更糟。由于-x生成了提交消息,很容易发现提交实际上是从其他地方复制的,但反过来追踪它——找出东西被复制到了哪里,或者什么东西还没有被复制——可能是一个巨大的痛苦。

当然,还有第三条路。既不合并,也不摘樱桃。您可以在main上手动重新进行更改。这将是一个非自动化、非git辅助的樱桃采摘。有时,当出于某种原因,挑拨离间会导致严重的冲突破裂时,这是必要的。

编辑:你可以找到一些关于merge with squash的建议。小心点。尽管被称为"合并",但这基本上是所有人的选择。它不会留下"合并提交",也不会像普通合并那样留下回溯父级的"行"。

编辑:和往常一样,如果有人说merge,另一个人会说rebase。从prod移植补丁对于rebase来说不是一个好的例子,但无论如何,rebase基本上是一个自动的串行樱桃选择。它有很多怪癖,非常强大,但很容易射中自己的脚。我总是建议将-i(交互式)添加到任何重新基础中。

编辑:你也可以用一种feature branches相对安全地解决这个问题。比如:去掉prod的补丁。找到prod和main之间的共同基础。在此位置创建修补程序分支。把补丁放在补丁分支上。将补丁分支合并到prod,将补丁分支并入main。然而,在某些情况下,这可能会导致:

  • 巨大的宽树,如果你有很多这样的路径,并且你为每个路径创建新的分支(即,如果由于某种原因你不能在旧的补丁分支上搭载新的补丁)
  • 丑陋的冲突(如果公共基础在历史上已经足够了,并且代码从那时起发生了很大变化)
  • 等等

soo。。一堵文字墙,但一如既往,YMMV,HtH,GL!

最新更新