在git中,merge --squash和rebase有什么区别?


363

我是git的新手,正在尝试了解南瓜和rebase之间的区别。据我了解,您在进行重新设置基准时会执行壁球操作。

Answers:


360

双方git merge --squashgit rebase --interactive能产生“挤压”承诺。
但是它们有不同的目的。

将在目标分支上产生压缩的提交,而不标记任何合并关系。
(注意:它不会立即产生提交:您需要额外的git commit -m "squash branch"
如果要完全丢弃源分支(从SO问题中获取的模式),这将很有用:

 git checkout stable

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

至:

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

      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()的commit 1d14d0c(2019年5月24日(由Junio C Hamano合并--reloadbrain
gitster Hamano commit 33f2790中,2019年7月25日)

merge:垃圾--commit--squash

以前,在--squash提供时,“ option_commit”被静默删除。对于试图--commit显式地覆盖南瓜的无提交行为的用户来说,这可能是令人惊讶的。

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

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

在新的基础上重播部分或全部提交,从而使您可以进行压扁(或更近些的“修复”,请参见此问题)),直接转到:

git checkout tmp
git rebase -i stable

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

如果您选择压缩所有提交 tmp(但与merge --squash,您可以选择重播某些内容,并压榨其他内容)。

所以区别是:

  • squash 不会触及您的来源分支(tmp此处),并在您需要的位置创建一个提交。
  • rebase允许您使用以下命令在同一源分支上(仍然tmp):
    • 新基地
    • 更清洁的历史

11
Gc--d--e--f--g挤压在一起吗?
韦恩·康拉德

8
@Wayne:是的,在这些示例中,G表示tmp压缩在一起的提交。
VonC

3
@ Th4wn:由于Git G会提供所有项目的快照g,因此由于引起的更改,将不会代表相同的内容X
VonC

1
@VonC:不确定最后的评论。如果您使用git merge --no-ff temp而不是git merge --squash temp,那么您会获得较混乱的历史记录,但是您也可以git revert e更轻松地执行诸如此类的操作。这是一个混乱,但诚实和务实的历史,并且主要分支仍然保持整洁。
naught101

2
@ naught101我同意。如stackoverflow.com/a/7425751/6309中所述,它也不会破裂git bisectgit blame使用频率过高(例如git pull --no-ffstackoverflow.com/questions/12798767/…)。有没有一种方法,无论如何,这就是为什么这篇文章描述了三个(stackoverflow.com/questions/9107861/...
VonC

183

合并提交:将所有提交保留在分支中,并将它们与基础分支上的提交交织在此处输入图片说明

合并壁球:保留更改,但忽略历史记录中的单个提交 在此处输入图片说明

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

在此处输入图片说明

这里更多


81

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

重定基就是重定基,即为树选择新的基(父提交)。也许这个术语的含义更为明确:他们之所以称其为“移植”,是因为:为树选择新的地面(父提交,根)。

进行交互式基准调整时,您可以选择挤压,选择,编辑或跳过将要基准调整的提交。

希望那是清楚的!


7
我什么时候应该变基,什么时候应该压扁?
马丁·托马

31

让我们从下面的示例开始:

在此处输入图片说明

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

  1. 合并提交
    将保留功能分支的所有提交历史记录,并将它们移至master分支。
    将添加额外的虚拟提交。

  2. Rebase和merge
    将在master分支的前面附加Feature分支的所有提交历史记录。 不会添加额外的虚拟提交。

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

您可以在下面找到master分支如何照顾每个分支

在此处输入图片说明

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


1
您能在第二张图片中解释什么是虚拟提交吗?我是git的初学者。
优素福

1
@Yusuf,这只是一个额外的提交,其中包含两个分支的更新,它是默认的提交消息=“将XYZ分支转移到master中”
ahmednabil88
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.