在平常開發中,咱們的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
。