git合并:强制线性历史和合并提交

3
在我们的项目中,我们希望在git log --graph中看到合并的功能分支,但仍然保持线性历史记录,以便主分支在功能分支的持续时间内没有提交。这意味着,在将功能分支合并到主分支之前,请确保对主分支进行了变基。
目前,我们已经将merge = merge --no-ff设置为别名,并尝试记住在合并之前始终执行git rebase,但有时我们会忘记。
即,如果合并之前的情况如下:
A--B--C--D
    \
     E--F

我们想要强制执行这个结果(0)

A--B--C--D------m--
          \    /
           E--F

并且阻止这个(1)

A--B--C--D--m--
    \      /
     E----F

或者这个(2)

A--B--C--D--E--F--

很遗憾,我无法看到如何通过git别名来实现这一点。

  • git merge --no-ff 创建合并提交,但允许出现(1)
  • git merge --ff-only 确保主分支上没有提交,但会创建出现(2)
  • git merge --ff 愉快地创建(1)或(2),但不会创建(0)
  • git merge --ff-only --no-ff 的行为类似于 --no-ff

我们都需要独立于他人向主分支提交代码,因此基于限制对主分支的访问或代码审查的解决方案并不真正有帮助。


1
我非常确定git merge中没有内置功能可以强制执行快进情况,但是仍然会进行提交。对于Git开发人员来说,这样的工作流程不够明智,不能被默认支持。 - j6t
你们是否将自己的分支合并到本地的 main 分支,然后再推送到远程仓库? - TTT
@TTT 是的。这些都是本地 (file:///) 存储库。 - Edheldil
@Edheldil 好的,那么我认为我下面回答中的预合并钩子可能是你最好的选择。你需要要求每个人安装钩子,所以你不能强制他们使用它(就像你不能强制使用别名一样),但是听起来这不应该成为问题。 - TTT
1个回答

5

术语提示:我不建议称这为“线性历史”,因为没有上下文情况下,这通常意味着根本没有合并提交。

你试图实现的通常被称为“半线性合并”或“变基,合并”策略。这提供了功能“冒泡”,并且这些冒泡在日志中呈线性。请注意,有些人允许在功能分支只有一个提交时跳过合并提交,因为在结果图中功能上没有信息丢失。你应该事先决定是否允许这样做。(出于一致性考虑,我的个人喜好是不允许这样做。但这意味着我们最终会得到许多微小的一个提交+一个合并提交冒泡,这并不影响我的工作。)

至于如何实现这一点,我不建议按照你所提出的别名想法。因为在你每天的本地工作中,可能有太多的情况需要快进式合并。

相反,我首先倾向于在服务器端强制执行此策略,如果无法实现,则可以尝试使用钩子。对于服务器端实现,这里有一个答案,讨论了流行工具及其在此策略方面的能力。(目前Azure DevOps和Bitbucket都可以直接实现这一点。)如果你正在使用一个没有内置支持的工具,请考虑实施某种门禁检查,以验证源分支与目标完全保持同步,然后才允许合并完成(或推送)。有许多检查方法,其中之一可能是(使用Bash):

# return the target branch tip commit if it passes, nothing otherwise:
git rev-list <source-branch> | grep $(git rev-parse <target-branch>)

关于此声明的说明:
我们都需要独立于他人提交到主分支,所以基于限制对主分支的访问或代码审查的解决方案并不真正有帮助。
您仍然可以强制执行Pull Request完成策略,而无需要求其他人审核您的代码。例如,在Azure DevOps中,您需要一个PR将分支合并到main,然后只允许半线性合并。 AzDO会自动为您重新设置基础(如果需要),然后创建合并提交,您仍然不需要涉及另一个人。我很确定Bitbucket也具有此功能。对于GL或GH,您需要MR / PR,但允许自行完成,并打开门控检入以仅允许在完全更新时完成它。
如果您正在将内容合并到本地的main并直接推送到远程main,则另一种机制是使用Git hooks。也许pre-mergepre-push钩子最适合。在钩子内部,您可以查看main的HEAD提交,并确保满足以下条件:
1. 它是合并提交。 2. 两个父提交的合并基础(@^1@^2)等于第一个父提交(@^1)的相同提交。
附注:在将功能分支合并到共享分支时强制执行此策略是可以的。但是,如果您使用具有多个共享分支的工作流程,则不要将共享分支重新设置为另一个共享分支,因此请确保在执行这些合并操作时仅使用普通的合并。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接