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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2427238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 08:00:51  来源:igfitidea点击:

In git, what is the difference between merge --squash and rebase?

gitmergerebasegit-rebasesquash

提问by GiH

I'm new to git and I'm trying to understand the difference between a squash and a rebase. As I understand it you perform a squash when doing a rebase.

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

采纳答案by VonC

Both git merge --squashand git rebase --interactivecan produce a "squashed" commit.
But they serve different purposes.

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

will produce a squashed commit on the destination branch, without marking any merge relationship.
(Note: it does not produce a commit right away: you need an additional git commit -m "squash branch")
This is useful if you want to throw away the source branch completely, going from (schema taken from SO question):

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

 git checkout stable

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

to:

到:

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

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

and then deleting tmpbranch.

然后删除tmp分支。



Note: git mergehas a --commitoption, but it cannot be used with --squash. It was neverpossible to use --commitand --squashtogether.
Since Git 2.22.1 (Q3 2019), this incompatibility is made explicit:

注意:git merge有一个--commit选项,但不能与--squash. 这是从来没有可以使用--commit--squash在一起。
自 Git 2.22.1(2019 年第 3 季度)以来,这种不兼容性已明确:

See commit 1d14d0c(24 May 2019) by Vishal Verma (reloadbrain).
(Merged by Junio C Hamano -- gitster--in commit 33f2790, 25 Jul 2019)

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

merge: refuse --commitwith --squash

Previously, when --squashwas supplied, 'option_commit' was silently dropped. This could have been surprising to a user who tried to override the no-commit behavior of squash using --commitexplicitly.

merge:垃圾--commit--squash

以前,当--squash被提供时,' option_commit' 会被悄悄删除。对于试图使用--commit显式覆盖壁球的无提交行为的用户来说,这可能会令人惊讶。

git/gitbuiltin/merge.c#cmd_merge()now includes:

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

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


replays some or all of your commits on a new base, allowing you to squash (or more recently "fix up", see this SO question), going directly to:

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

git checkout tmp
git rebase -i stable

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

If you choose to squash all commits of tmp(but, contrary to merge --squash, you can choose to replay some, and squashing others).

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

So the differences are:

所以区别在于:

  • squashdoes not touch your source branch (tmphere) and creates a single commit where you want.
  • rebaseallows you to go on on the same source branch(still tmp) with:
    • a new base
    • a cleaner history
  • squash不会触及您的源分支(tmp此处)并在您想要的地方创建单个提交。
  • rebase允许您继续使用相同的源分支(仍然tmp):
    • 新基地
    • 更清洁的历史

回答by Md Ayub Ali Sarker

Merge commits: retains all of the commits in your branch and interleaves them with commits on the base branchenter image description here

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

Merge Squash: retains the changes but omits the individual commits from history enter image description here

Merge Squash:保留更改但忽略历史记录中的单个提交 在此处输入图片说明

Rebase: This moves the entire feature branch to begin on the tip of the master branch, effectively incorporating all of the new commits in master

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

enter image description here

在此处输入图片说明

More on here

更多在这里

回答by Mauricio Scheffer

Merge squash merges a tree (a sequence of commits) into a single commit. That is, it squashesall changes made in ncommits into a single commit.

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

Rebasing is re-basing, that is, choosing a new base (parent commit) for a tree. Maybe the mercurial term for this is more clear: they call it transplant because it's just that: picking a new ground (parent commit, root) for a tree.

Rebasing 是 re-base,即为树选择一个新的基础(父提交)。也许这方面的善变术语更清楚:他们称之为移植,因为它只是:为一棵树挑选一个新的基础(父提交,根)。

When doing an interactive rebase, you're given the option to either squash, pick, edit or skip the commits you are going to rebase.

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

Hope that was clear!

希望这很清楚!

回答by ahmednabil88

Let's start by the following example:

让我们从以下示例开始:

enter image description here

在此处输入图片说明

Now we have 3 options to merge changes of feature branchinto master branch:

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

  1. Merge commits
    Will keep all commits history of the feature branchand move them into the master branch
    Will add extra dummy commit.

  2. Rebase and merge
    Will append all commits history of the feature branchin the front of the master branch
    Will NOT add extra dummy commit.

  3. Squash and merge
    Will group all feature branchcommits into one committhen append it in the front of the master branch
    Will add extra dummy commit.

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

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

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

You can find below how the master branchwill look after each one of them.

您可以在下面找到master 分支将如何处理每个分支

enter image description here

在此处输入图片说明

In all cases:
We can safely DELETE the feature branch.

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