【问题标题】:Semi linear merge半线性合并
【发布时间】:2020-01-13 10:04:38
【问题描述】:

我刚刚注意到在 Azure DevOps 中有一个名为 semi-linear merge 的选项。我想知道它有什么作用?它是否介于合并策略和变基策略(来自名称半线性)之间?如果是这样,有什么优点/缺点?

编辑: 来自Microsoft Devblog 我相信这个选项包括2点:

  1. 从 master/dev 分支变基功能分支
  2. 然后在master/dev分支中合并feature分支

但这不是合并策略吗?

【问题讨论】:

    标签: git azure-devops


    【解决方案1】:

    半线性合并
    这种策略是最奇特的——它是变基和合并的混合体。首先,拉取请求中的提交是基于主分支之上的。然后将这些重新定位的拉取请求合并到主分支中。它模拟在拉取请求分支上运行git rebase master,然后在主分支上运行git merge pr --no-ff

    有些人认为这是两全其美:保留单个提交,以便您可以看到工作是如何演变的,但不仅仅是重新定位,而是显示“合并气泡”,以便您可以立即看到每个单独的拉取请求中的工作。

    取自Pull Requests with Rebase

    【讨论】:

    • 最新的右蓝不是已经包含了所有的变化(确切地说是一个重新定位的版本),那么如何创建另一个新状态呢?新状态不是必须与最新的右蓝有完全相同的内容吗?
    • @nonopolarity 是的。在变基之后,可以进行快进合并,但这会强制合并提交。 (出于同样的原因,您将使用 --no-ff 进行正常合并。)
    【解决方案2】:

    半线性合并只是添加一个变基以在完成合并之前让您的分支保持最新。如果您将 my-branch 公关到 target-branch,它与以下命令相同:

    git fetch
    git checkout my-branch
    git rebase origin/target-branch
    git branch -D target-branch # just in case you have an old version of it locally
    git checkout target-branch
    git merge --no-ff my-branch
    

    一些优点和缺点如下:

    优点:

    1. 变基首先使每个合并更清晰,更容易在视觉上跟踪。它还将所有更改放入提交本身,而不必在合并提交中追踪不良副作用,这通常很困难。请注意,仍然建议开发人员在创建 PR 之前自己进行 rebase,以便他们可以看到当时发生的任何更改,并针对最新版本运行他们的单元测试,以确保没有发生任何奇怪的事情。 (这类似于在创建 PR 之前测试合并提交并运行测试,只是为了确保常规合并仍能按预期工作。)
    2. 合并(使用 --no-ff)强制合并提交,这很有帮助,因为每个 PR 都包含与该 PR 关联的提交列表,使您能够查看显示所有合并到的第一父历史记录分支,并轻松比较它们。强制合并提交的另一个好处是,只需恢复合并提交即可轻松恢复整个 PR,而不是单独恢复原始 PR 中的每个提交。

    缺点:

    • 在某些情况下您不想使用半线性合并。一个很好的例子是,如果您的源分支中有您想要保留的新合并提交。在 Git Flow 中,当您将 release 合并到 master,或将 master 合并回 develop 时,您需要保留任何来自这些分支上 PR 的合并提交。半线性合并的变基部分将重写那些合并提交,不仅“气泡”会被弹出,更糟糕的是,提交 ID 将被重写。这意味着您无法确定 master 中的所有内容当前是否都在 develop 中。尽管代码相同,但仍可能缺少 ID。根据经验,如果源分支包含新的合并提交,就不要进行半线性合并。
    • 半线性合并后,在删除本地分支时,您可能必须使用 git branch -D my-branch(而不是小写 -d),因为提交 ID 可能已更改。除非您通常不立即删除本地分支机构,否则这几乎不会带来不便;如果你等待,你需要确认你真的可以删除它。
    • 如果您的工作流程是让开发人员在创建 PR 之前重新定位到目标分支,则提供此选项可能会使他们变得懒惰,因为他们知道这会为他们做这件事。大多数时候这不是问题,但每隔一段时间自动合并或变基都会破坏某些东西,最好他们习惯先变基以在 PR 完成之前检测到它。否则,在这种(诚然罕见的)场景中,冲突会自动解决,并且您的集成分支会出现问题。
    • 如果您使用签名提交,如果在半线性合并期间需要变基,则不会保留签名(因为重新编写了提交)。根据您签署提交的原因,这可能不是一个可接受的选择。

    旁注:其他工具也提供此功能:

    • Bitbucket offers the identical merge strategy,并将其恰当地称为“变基,合并”。
    • GitLab 曾经有设置用于强制“将提交与半线性历史记录合并”但是,在撰写本文时 AFAIK 它 is 只是 MR 上的一扇门。 (注意 GitLab 将 Pull Requests 称为“Merge Requests”。它们是同一件事。)有了这个设置,你 have had 首先自己重新设置它(你可以在UI),然后完成 MR。基本上是 2 次按钮点击而不是 1 次。更新:这可能不再可能。现在 GitLab 有fast-forward only 的选项,但我不知道您可以要求检查分支是否是最新的,并且仍然执行--no-ff 合并。
    • GitHub 尚不支持此功能,但自 2017 年以来人们一直在请求它。

    附加说明:我在任何地方都找不到此文档,但我已经测试并确认,在 Azure DevOps 中完成 PR 时,如果您选择“Rebase and fast-forward”或“半线性合并”,你的 PR 源分支在 PR 完成之前被重写。通常,您会在合并后勾选该框以删除您的源分支并且不会关心这一点,但如果您选择不选中该设置,那么重要的是要意识到您的远程分支将显示为“(强制更新)”如果需要变基,您的下一个本地提取。根据您的用例,这可能是 Pro 或 Con;大多数时候我会倾向于这个。

    关于其他工具,使用此策略 GitLab 强制 通过单击按钮来更新您的分支,而 Bitbucket 专门 修改其等效的 PR 分支“变基,合并”策略。

    【讨论】:

    • 小插件,但是如果你使用Github并且你想做半线性合并,我写了一个脚本来做这个。可在pypi.org/project/git-pr-linear-merge 获得
    • @WaldoBronchart 脚本执行哪些操作? (顺便说一句,我认为我可能更喜欢您的脚本使用“半线性”一词,因为我认为大多数人将“线性”与完全缺乏合并提交联系在一起,这样分支在合并时会快进。)
    • 是的,我听到了同样的评论。为了清楚起见,我想我会重命名它。检查文档以了解脚本的作用(基本上是变基 + 合并,但适用于许多边缘情况)
    猜你喜欢
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 2021-05-31
    • 2014-02-11
    • 2012-12-08
    • 2016-01-09
    • 2023-01-20
    相关资源
    最近更新 更多