網頁

2022/11/17

Git 使用rebase squash合併多個commit

Git若有多個commit(提交)想要合併為一個commit可使用rebase squash。


例如現在有commit如下。

* bca40e7 (HEAD -> main) c
* 75c4408 b
* f858a99 a
* 1e2398a (origin/main, origin/HEAD) first commit

若要把最後三個commit即bca40e775c4408f858a99合併為一個commit可輸入git rebase -i 1e2398ai相當於--interactive

$ git rebase -i 1e2398a

執行後會進入rebase的互動模式,即開啟Vim編輯器修改從HEAD commit bca40e71e2398a後的提交。最上方可以看到由舊到新的三個提交的hash。

pick f858a99 a
pick 75c4408 b
pick bca40e7 c

# Rebase 1e2398a..bca40e7 onto 1e2398a (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified); use -c <commit> to reword the commit message
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

從註解可看到p, pick為使用此commit;s, squash為使用此commit的內容,但與前一個commit合併。因此把要合併的commit hash前的command由pick改為s(即squash)如下,修改後儲存離開。

p f858a99 a
s 75c4408 b
s bca40e7 c

# Rebase 1e2398a..bca40e7 onto 1e2398a (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified); use -c <commit> to reword the commit message
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.

離開rebase互動模式後又會進入Vim修改合併commit的訊息,現有合併前的三個commit訊息如下。

# This is a combination of 3 commits.
# This is the 1st commit message:

a

# This is the commit message #2:

b

# This is the commit message #3:

c

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Wed Nov 16 13:38:35 2022 +0800
#
# interactive rebase in progress; onto 1e2398a
# Last commands done (3 commands done):
#    squash 75c4408 b
#    squash bca40e7 c
# No commands remaining.
# You are currently rebasing branch 'main' on '1e2398a'.
#
# Changes to be committed:
#       modified:   main.go
#

修改commit如下為合併後的commit訊息,儲存離開。

# This is a combination of 3 commits.
# This is the 1st commit message:

abc

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Wed Nov 16 13:38:35 2022 +0800
#
# interactive rebase in progress; onto 1e2398a
# Last commands done (3 commands done):
#    squash 75c4408 b
#    squash bca40e7 c
# No commands remaining.
# You are currently rebasing branch 'main' on '1e2398a'.
#
# Changes to be committed:
#       modified:   main.go
#

離開後檢視提交歷史即可看到原本的三個commit被合併為一個新commit a75ef09

$ git rebase -i 1e2398a
[detached HEAD a75ef09] abc
 Date: Wed Nov 16 13:38:35 2022 +0800
 1 file changed, 3 insertions(+)
Successfully rebased and updated refs/heads/main.
$ git log --all --graph --decorate --oneline
* a75ef09 (HEAD -> main) abc
* 1e2398a (origin/main, origin/HEAD) first commit


沒有留言:

張貼留言