Git合併提交

在日常開發中,我們的Git提交原則經常是小功能多次提交,但是有時需要在完成功能之後將多個連續的提交合併成一個,或者進行分支合併時,只保留一個提交,以保證分支簡介,這時就需要進行squash操作,兩種分別稱爲 Rebase Squash 和 Merge Squash。這篇tip主要記錄如何處理這兩種操作以及之間的區別,

<!--more-->

Rebase Squash

用來將多個連續的提交合併爲一個,以下面的提交記錄爲例,master是主分支,分支 featureY 提交了一系列的修改:

$ 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 是如下命令:

[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 功能分支上的 Y1Y5 這五個提交爲一個。git提供瞭如下命令:

git rebase --interactive HEAD~[N]
# 或者
git rebase -i HEAD~[N]

其中 [N] 表示需要合併的數量,從最近一個提交開始數,這裏爲5。在命令行輸入 git rebase --interactive HEAD~5 進入編輯器進行選擇。
注意,這裏的提交順序是 的,從最早的 Y1 開始:

pick 61b5ff9 Y1
pick fb3a5cf Y2
pick b54cd87 Y3
pick 740e7d2 Y4
pick 392dc11 Y5

對應需要合併的提交,將pick改成squash(或者簡化爲s),修改之後爲:

pick 61b5ff9 Y1
s fb3a5cf Y2
s b54cd87 Y3
s 740e7d2 Y4
s 392dc11 Y5

保存並關閉編輯器,這是編輯器會自動跳出並需要你提交一個新的提交:

# 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>

Merge Squash

用於在合併分支時,最後只在合併後的分支上保留一個提交。同樣以上面的代碼提交爲例子。

$ 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上多了一個未被提交的更改:

git-merge-squash

$ 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

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章