在平常开发中,咱们的Git提交原则常常是小功能屡次提交,可是有时须要在完成功能以后将多个连续的提交合并成一个,或者进行分支合并时,只保留一个提交,以保证分支简介,这时就须要进行squash操做,两种分别称为 Rebase Squash 和 Merge Squash。这篇tip主要记录如何处理这两种操做以及之间的区别,git
用来将多个连续的提交合并为一个,如下面的提交记录为例,master
是主分支,分支 featureY
提交了一系列的修改:shell
$ git lg
* 392dc11 - (HEAD -> featureY) Y5 (5 minutes ago) <qiwihui>
* 740e7d2 - Y4 (5 minutes ago) <qiwihui>
* b54cd87 - Y3 (5 minutes ago) <qiwihui>
* fb3a5cf - Y2 (6 minutes ago) <qiwihui>
* 61b5ff9 - Y1 (6 minutes ago) <qiwihui>
* 220e45c - (master) feature X (7 minutes ago) <qiwihui>
复制代码
其中,lg
是以下命令:bash
[alias]
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --
复制代码
这里咱们须要合并 featureY
功能分支上的 Y1
到 Y5
这五个提交为一个。git提供了以下命令:编辑器
git rebase --interactive HEAD~[N]
# 或者
git rebase -i HEAD~[N]
复制代码
其中 [N]
表示须要合并的数量,从最近一个提交开始数,这里为5
。在命令行输入 git rebase --interactive HEAD~5
进入编辑器进行选择。 注意,这里的提交顺序是 反 的,从最先的 Y1
开始:post
pick 61b5ff9 Y1
pick fb3a5cf Y2
pick b54cd87 Y3
pick 740e7d2 Y4
pick 392dc11 Y5
复制代码
对应须要合并的提交,将pick
改为squash
(或者简化为s
),修改以后为:ui
pick 61b5ff9 Y1
s fb3a5cf Y2
s b54cd87 Y3
s 740e7d2 Y4
s 392dc11 Y5
复制代码
保存并关闭编辑器,这是编辑器会自动跳出并须要你提交一个新的提交:spa
# This is a combination of 5 commits.
# This is the 1st commit message:
Y1
# This is the commit message #2:
Y2
# This is the commit message #3:
Y3
# This is the commit message #4:
Y4
# This is the commit message #5:
Y5
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Thu May 9 13:45:03 2019 +0800
#
# interactive rebase in progress; onto 220e45c
# Last commands done (5 commands done):
# squash 740e7d2 Y4
# squash 392dc11 Y5
# No commands remaining.
# You are currently rebasing branch 'featureY' on '220e45c'.
#
# Changes to be committed:
# new file: featY
#
复制代码
能够看到,Git提供了详细的信息指导提交,只须要修改为你须要的信息便可,好比 featureY
,而后保存。这时就完成了修改,修改以后的提交信息以下:命令行
$ git lg
* 1b07941 - (HEAD -> featureY) featureY (3 minutes ago) <qiwihui>
* 220e45c - (master) feature X (36 minutes ago) <qiwihui>
复制代码
用于在合并分支时,最后只在合并后的分支上保留一个提交。一样以上面的代码提交为例子。code
$ git lg
* 392dc11 - (HEAD -> featureY) Y5 (5 minutes ago) <qiwihui>
* 740e7d2 - Y4 (5 minutes ago) <qiwihui>
* b54cd87 - Y3 (5 minutes ago) <qiwihui>
* fb3a5cf - Y2 (6 minutes ago) <qiwihui>
* 61b5ff9 - Y1 (6 minutes ago) <qiwihui>
* 220e45c - (master) feature X (7 minutes ago) <qiwihui>
复制代码
$ git checkout master
$ git merge --squash featureY
Updating 220e45c..392dc11
Fast-forward
Squash commit -- not updating HEAD
featY | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 featY
复制代码
此时,分支featureY
保持不变,同时在master
上多了一个未被提交的更改:orm
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: featY
复制代码
这些更改是分支featureY
中全部提交的合并,如今只须要提交这些更改就能够了:
git commit -m "featureY"
复制代码
从以上的擦坐过程能够看出二者之间的差异:Rebase Squash会合并以前的提交,以前的记录会消失,而Merge Squash只会在合并的分支上新生成提交,原来的那些提交熬还会保留。
若是须要合并的提交数量不少,数数容易出错,可使用提交哈希来识别:
git rebase --interactive [commit-hash]
复制代码
这个[commit-hash]
是须要合并的提交以前的一个提交:
$ git lg
* 392dc11 - (HEAD -> featureY) Y5 (5 minutes ago) <qiwihui>
* 740e7d2 - Y4 (5 minutes ago) <qiwihui>
* b54cd87 - Y3 (5 minutes ago) <qiwihui>
* fb3a5cf - Y2 (6 minutes ago) <qiwihui>
* 61b5ff9 - Y1 (6 minutes ago) <qiwihui>
* 220e45c - (master) feature X (7 minutes ago) <qiwihui>
复制代码
这里,须要使用 220e45c
而不是 61b5ff9
。