git - 如何在 Git 中找到向后合并?
问题描述
我公司有发布分支。在合并回发布分支之前,必须在自己的分支中创建更改。典型的工作流程可能如下所示:
A---F----------M------ V.1
\ / \ /
E H------L
在合并回版本 V.1 分支之前,在 E、H 和 L 中添加了更改。
如果我们同时在开发 V.2,那么对 V.1 的任何更改也必须“合并”到 V.2:
C--D
/ \
B---G--J---K---N-- V.2
/ / \ / /
/ / I--' /
/ / /
A---F----------M------ V.1
\ / \ /
E H------L
这确保了适用于 V.1 的任何错误修正都被带到 V.2 中。
偶尔,开发人员会不小心合并到错误的发布分支。假设从 V.2 分支的提交“I”被向后合并到 V.1:
C--D
/ \
B---G--J-------N-- V.2
/ / \ /
/ / I /
/ / \ /
A---F-------K--M------ V.1
\ / \ /
E H------L
在这种情况下,我们称 K 为“向后合并”。它会导致 V.2 中的所有新功能都合并到 V.1 中,这是非常糟糕的。
当这种情况发生时,我们会尝试找到反向合并 K,以便我们可以恢复更改。不幸的是,每天有数百次提交,通过视觉检查图表很难找到 K。
我们如何以编程方式找到反向合并 K?
解决方案
因为“向后合并”的想法不是 git 所知道的,所以您需要编写一些自定义脚本。(我能想到的最接近真正帮助的事情是git bisect
- 但它不会完全起作用,因为它认为它正在寻找引入某些行为的个人提交,而你想找到一些行为被合并到的地方一个特定的分支。)
所以...
您需要的第一个方法是测试提交是否包含来自v2
. 您可以检查最早的v2
提交(B
在您的示例图中)并在那里创建一个标签
git tag v2-root
然后您可以检查提交以查看是否v2-root
“可达”;有几种方法,但最直接的可能是
git merge-base --is-ancestor v2-root <some-commit>
接下来,您需要一个提交列表来测试。您可以使用git rev-list
. 一般情况下你可以使用
git rev-list --first-parent v1.0
这假设对于添加到发布分支的每个合并,第一个父级是发布分支的先前提交,这通常是正确的。有一些方法可以创建不正确的合并。(最简单的是合并V1.0
到另一个分支,然后快进V1.0
到合并。)
如果您担心会发生这样的事情,那么您必须省略该--first-parent
选项,然后您的脚本需要一种方法来整理分支拓扑。现在我假设这没有必要。
所以现在你只需要一个脚本沿着提交列表向下工作,git merge-base ...
在每次提交时运行测试(),直到它找到一个测试返回错误的地方。如果第一个(最近的)提交返回 false,则没有向后合并;否则,最后一次返回 true 的提交是向后合并。
推荐阅读
- javascript - 这是在我的项目中获取字母的好方法吗?
- angular - Angular 10 找不到“object”类型的不同支持对象“[object Object]”。NgFor 仅支持绑定到 Iterables,例如 Arrays
- dask - 在具有不同模块版本的项目之间共享 Dask 集群?
- ruby-on-rails - Rails / Passenger / Nginx:“缺少用于解密文件的加密密钥”
- sql - Oracle SQL:连接 - 缺少表达式
- java - 如何使用弹出窗口中的按钮从 recyclerview 项目中复制文本?
- c - makefile 无法创建 .o 文件
- unity3d - 我如何在 unity 2018.1 中设置和使用 proGrids?
- python - Django 在保存之前加密 FileField
- javascript - 从Javascript中的字符串中删除子字符串