在 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
In git, what is the difference between merge --squash and rebase?
提问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 --squash
and git rebase --interactive
can produce a "squashed" commit.
But they serve different purposes.
双方git merge --squash
并git 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 tmp
branch.
然后删除tmp
分支。
Note: git merge
has a --commit
option, but it cannot be used with --squash
. It was neverpossible to use --commit
and --squash
together.
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--commit
with--squash
Previously, when
--squash
was 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--commit
explicitly.
merge
:垃圾--commit
带--squash
以前,当
--squash
被提供时,'option_commit
' 会被悄悄删除。对于试图使用--commit
显式覆盖壁球的无提交行为的用户来说,这可能会令人惊讶。
git/git
builtin/merge.c#cmd_merge()
now includes:
git/git
builtin/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:
所以区别在于:
squash
does not touch your source branch (tmp
here) and creates a single commit where you want.rebase
allows you to go on on the same source branch(stilltmp
) 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 branch
合并提交:保留分支中的所有提交,并将它们与基础分支上的提交交错
Merge Squash: retains the changes but omits the individual commits from history
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 中
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:
让我们从以下示例开始:
Now we have 3 options to merge changes of feature branchinto master branch:
现在我们有 3 个选项可以将功能分支的更改合并到主分支中:
Merge commits
Will keep all commits history of the feature branchand move them into the master branch
Will add extra dummy commit.Rebase and merge
Will append all commits history of the feature branchin the front of the master branch
Will NOT add extra dummy commit.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.
合并提交
将保留功能分支的所有提交历史并将它们移动到主分支
将添加额外的虚拟提交。变基和合并
将在主分支的前面附加功能分支的所有提交历史 不会添加额外的虚拟提交。Squash and merge
将所有功能分支提交组合为一个提交,然后将其附加到主分支的前面
将添加额外的虚拟提交。
You can find below how the master branchwill look after each one of them.
您可以在下面找到master 分支将如何处理每个分支。
In all cases:
We can safely DELETE the feature branch.
在所有情况下:
我们可以安全地删除功能分支。