git - 为什么在 Github 上总是可以使用 "squash and merge"快速转发?

标签 git github

Github docs这么说

Pull requests with squashed commits are merged using the fast-forward option.

这与我对正在发生的事情的心理模型(如下图所示)相冲突,如果您能提供一些说明,我将不胜感激。

初始情况,特征应该被“压缩并 merge ”到 master 中:

enter image description here

压缩后 merge 前的情况:

enter image description here

在将特征 merge 到主特征时,现在如何执行快进 merge ?

编辑:所以从评论来看,似乎发生的实际上是“挤压和 rebase ”而不是“挤压和 merge ”。这是正确的吗?

最佳答案

文档中所说的在技术上是正确的,但有些误导。

当您执行压缩并与 GitHub merge 时,它会获取您的两个分支的内容并 merge 它们,但不会创建 merge 提交。相反,它创建了一个只有一个父级的提交。这相当于命令行中的 git merge --squash && git commit

在您的图表中,这是 masterfeature 的 merge 。

GitHub 创建的这个临时提交随后作为快进 merge merge 到您的主分支中,因为它必然是主分支的超集。这就是为什么它在技术上是正确的,但却具有误导性。 GitHub 包含此消息是为了告诉您它不会创建 merge 提交(即具有两个或更多父级的提交),而是创建仅以主分支作为其父级的单个提交。

从本质上讲,squash 和 merge 只是一种 merge ,只是有着不同的历史。有一个提交与单个父项,而不是多个提交与 merge 提交相结合。例如,如果你有这个:

A - B - C - D (dev)
 \
  E - F - G (feature)

如果您想 merge DG,正常的 merge 会给您这样的结果:

A - B - C - D - H (dev)
 \             /
  E - F - G --    (feature)

Squash merge 会给你这个:

A - B - C - D - H' (dev)

HH' 的内容相同,但提交的父项数量不同。此 H 将通过在临时分支上创建但未提交 H 然后将其快进 merge 到 dev 中来创建。

如果挤压首先发生,则此行为可能不同于挤压和 rebase ,因为一种情况可能会发生冲突,而另一种情况可能不会。但在没有冲突的情况下,它们应该几乎一直产生相同的结果。

squash-and-merge 和 squash-and-rebase 是否不同取决于所使用的 rebase 类型。旧式 am rebase 使用补丁,因此如果上下文在多个地方相同,补丁可能会被误用,这是这种方法的一个已知缺陷。它也不执行重命名检测,这意味着 merge 尝试可能会失败。较新的样式 rebase 在幕后使用 merge 机制,我不知道有什么地方不会产生相同的结果(尽管我不是 Git merge 机制专家),因为它本质上是一个 merge 。

请注意,squash-and-rebase 与基于 merge 的 rebase 或 squash-and-merge 在性质上不同于 rebase-and-squash,因为后者涉及对多个补丁进行 rebase,每个补丁都可能有冲突,而 squash -and-rebase 将只考虑旧的基础、新的基础和压缩的提交。如果中间的补丁会导致冲突但最终结果不会(例如,因为冲突代码在本系列的后面被删除),那么 rebase-and-squash 将遍历有问题的提交和冲突,而 squash- and-rebase 不会也将会成功。

关于git - 为什么在 Github 上总是可以使用 "squash and merge"快速转发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62728095/

相关文章:

git - 为什么 'git commit' 不保存我的更改?

git - 将 Git 提交从复制的 fork 存储库重新应用到原始存储库

merge 之间的 git rebase 导致完全不相关的文件发生冲突

javascript - 带有 js 扩展名的 React 文件的 GitHub 代码高亮显示

pull 请求的 git-blame

github - bower ECMDERR 无法执行 "git ls-remote --tags --heads > git@github.om:mobify/bellows.git",退出代码为 #128

svn - 如何在保留分支的同时将我的 SVN 存储库转换为 Git?

git - 如何在 Windows 版 Git 客户端中对 TFS 服务器进行身份验证?

node.js - 如何通过 API 发布要点(非匿名)

git - 如何查看Github用户内容?