493

我是 git 新手,我试图了解 squash 和 rebase 之间的区别。据我了解,您在进行变基时会执行壁球。

4

4 回答 4

456

合并提交:保留分支中的所有提交,并将它们与基础分支上的提交交错在此处输入图像描述

Merge Squash:保留更改但忽略历史中的单个提交 在此处输入图像描述

Rebase:这会将整个功能分支移动到 master 分支的顶端,有效地将所有新提交合并到 master

在此处输入图像描述

更多关于这里


前两张图来自GitHub Docs 上的 About pull request merges

于 2017-04-21T20:21:35.200 回答
429

两者都git merge --squash可以git rebase --interactive产生一个“压扁”的提交。但它们有不同的用途。

将在目标分支上生成一个压缩提交,而不标记任何合并关系。(注意:它不会立即产生提交:你需要一个额外的git commit -m "squash branch"

如果您想完全丢弃源分支,这很有用,从(从SO question获取的模式):

git checkout stable

          X               stable
         /
a---b---c---d---e---f---g tmp

至:

git merge --squash tmp
git commit -m "squash tmp"


# In the following graph, G is c--d--e--f--g squashed together

          X-------------G stable
         /
a---b---c---d---e---f---g tmp

然后删除tmp分支。


注意:git merge有一个--commit选项,但不能与--squash. 永远不可能同时使用--commit--squash。自 Git 2.22.1(2019 年第三季度)以来,这种不兼容性变得明确:

请参阅Vishal Verma ( ) 的提交 1d14d0c(2019 年 5 月 24 日(由Junio C Hamano 合并 -- --提交 33f2790中,2019 年 7 月 25 日)reloadbraingitster

merge--commit:拒绝--squash

以前,当--squash被提供时,' option_commit' 被默默地丢弃。对于试图--commit显式覆盖 squash 的无提交行为的用户来说,这可能会令人惊讶。

git/git builtin/merge.c#cmd_merge()现在包括:

if (option_commit > 0)
    die(_("You cannot combine --squash with --commit."));

在新的基础上重播您的部分或全部提交,允许您进行压缩(或最近“修复”,请参阅此SO 问题),直接转到:

git checkout tmp
git rebase -i stable

   stable
      X----------------G tmp
     /
a---b

如果您选择压缩所有提交tmp(但是,与 相反merge --squash,您可以选择重放一些,并压缩其他)。

所以区别是:

  • squash不会触及您的源分支(tmp此处)并在您想要的位置创建单个提交。
  • rebase允许您继续使用相同的源分支(仍然tmp):
    • 新基地
    • 更清洁的历史
于 2010-03-11T18:17:12.790 回答
105

让我们从以下示例开始:

在此处输入图像描述

现在我们有 3 个选项可以将功能分支的更改合并到主分支

  1. 合并提交
    将保留功能分支的所有提交历史并将它们移动到主分支
    将添加额外的虚拟提交。

  2. 变基和合并将在主分支前面附加功能分支
    的 所有提交历史 不会添加额外的虚拟提交。

  3. 挤压和合并
    将所有功能分支提交分组为一个提交,然后将其附加到主分支的前面
    将添加额外的虚拟提交。

您可以在下面找到主分支将如何处理它们中的每一个。

在此处输入图像描述

在所有情况下:
我们可以安全地删除功能分支

于 2019-10-29T13:39:19.953 回答
99

合并壁球将树(提交序列)合并为单个提交。也就是说,它将n次提交中所做的所有更改压缩到单个提交中。

Rebase 是 re-base,即为树选择一个新的基础(父提交)。也许这个变化无常的术语更清楚:他们称之为移植,因为它就是:为一棵树选择一个新的地面(父提交,根)。

在进行交互式变基时,您可以选择压缩、选择、编辑或跳过要变基的提交。

希望这很清楚!

于 2010-03-11T18:15:41.337 回答