如何在 Git 中找到向后合并?
Posted
技术标签:
【中文标题】如何在 Git 中找到向后合并?【英文标题】:How to find a backwards merge in Git? 【发布时间】:2020-02-05 17:49:11 【问题描述】:我的公司有发布分支。在合并回发布分支之前,必须在自己的分支中创建更改。典型的工作流程可能如下所示:
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?
【问题讨论】:
【参考方案1】:因为“向后合并”的想法并不是 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 的脚本。如果第一个(最近的)提交返回 false,则没有向后合并;否则,最后一次返回 true 的提交是向后合并。
【讨论】:
以上是关于如何在 Git 中找到向后合并?的主要内容,如果未能解决你的问题,请参考以下文章