ryota21silvaの技術ブログ

Funna(ふんな)の技術ブログ

これまで学んだ技術の備忘録。未来の自分が救われることを信じて

【Git】git rebase -iでpush済みのコミットまとめたれ

コミットをまとめる

コミットBとCをまとめたい

$ git log -n 3                                                                                                                                                              
commit 78dbdc4439854253a4c65a23aad687488bcf2051 (HEAD -> feature/hogehoge)
Author: ryota1116
Date:   Tue Sep 21 01:27:14 2021 +0900

    コミットC

commit 185f507a6a32fd93505db1cd05b6effa23f45532
Author: ryota1116
Date:   Tue Sep 21 01:14:21 2021 +0900

    コミットB

commit f19845709c26dea827c6097279472ecc3ddda491
Author: ryota1116
Date:   Tue Sep 21 01:10:07 2021 +0900

    コミットA

git rebase -iでコミットをまとめる。

$ git rebase -i HEAD~3

pick b536dec90 コミットA
pick 7fc1e2c81 コミットB
pick 3c98d9014 コミットC

# Rebase 185f507a6..3c98d9014 onto 185f507a6 (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 <commit> = like "squash", but discard this commit's log message
# 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.
#
# Note that empty commits are commented out

コミットC(3c98d9014)を、1つ前のコミットB(7fc1e2c81)にまとめたい場合以下のように書き換える。 squash(押し潰す)されたコミットCをコミットBが拾う(pick)。

$ git rebase -i HEAD~3

pick b536dec90 コミットA
pick 7fc1e2c81 コミットB
s 3c98d9014 コミットC

:wqでファイルを保存しviを終了すると、以下の画面になる。

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

コミットB

# This is the commit message #2:

コミットC

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Fri Sep 24 16:49:38 2021 +0900
#
# interactive rebase in progress; onto 185f507a6
# Last commands done (3 commands done):
#    pick 7fc1e2c81 コミットB
#    squash 3c98d9014 コミットC
# No commands remaining.
# You are currently rebasing branch 'feature/hogehoge
#
# Changes to be committed:
#       modified:   src/hogehoge.php
#       modified:   src/fuga.php
#       modified:   src/piyo.php
#

コミットメッセージをまとめてあげて、:wq

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

コミットB+

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Fri Sep 24 16:49:38 2021 +0900
#
# interactive rebase in progress; onto 185f507a6
# Last commands done (3 commands done):
#    pick 7fc1e2c81 コミットB
#    squash 3c98d9014 コミットC
# No commands remaining.
# You are currently rebasing branch 'feature/hogehoge
#
# Changes to be committed:
#       modified:   src/hogehoge.php
#       modified:   src/fuga.php
#       modified:   src/piyo.php
#

以下の画面に戻る。

$ git rebase -i HEAD~3
[detached HEAD 51ffdbb8d] コミットB+
 Date: Fri Sep 24 16:49:38 2021 +0900
 3 files changed, 11 insertions(+), 3 deletions(-)
Successfully rebased and updated refs/heads/feature/hogehoge

コミットが纏まったことが分かる。

$ git log -n 3                                                                                                                                                              
commit 51ffdbb8dc3f2b5336f5394739599313c25022a0 (HEAD -> feature/hogehoge)
Author: ryota1116
Date:   Fri Sep 24 16:49:38 2021 +0900

    コミットB+

commit b536dec90d6505bcfc6ae2f3f74ba03a5eeca8b3
Author: ryota1116
Date:   Tue Sep 21 01:27:14 2021 +0900

    コミットA

commit 185f507a6a32fd93505db1cd05b6effa23f45532
Author: ryota1116
Date:   Tue Sep 21 01:14:21 2021 +0900

    コミットα

問題無ければforce push。 同じブランチで他の人が一緒に作業してたりするなら、force pushは避けましょうね。

$ git push -f

まとめたコミットを戻したい時

git logではsquash後のコミットしか見れないが、

$ git log -n 3                                                                                                                                                              
commit 51ffdbb8dc3f2b5336f5394739599313c25022a0 (HEAD -> feature/hogehoge)
Author: ryota1116
Date:   Fri Sep 24 16:49:38 2021 +0900

    コミットB+

commit b536dec90d6505bcfc6ae2f3f74ba03a5eeca8b3
Author: ryota1116
Date:   Tue Sep 21 01:27:14 2021 +0900

    コミットA

commit 185f507a6a32fd93505db1cd05b6effa23f45532
Author: ryota1116
Date:   Tue Sep 21 01:14:21 2021 +0900

    コミットα

git reflogでHEADの移動履歴を確認できる。
3c98d9014まで戻せば良さそう。

$ git reflog -n 11
78dbdc443 (HEAD -> feature/hogehoge) HEAD@{0}: rebase -i (finish): returning to refs/heads/feature/hogehoge
78dbdc443 (HEAD -> feature/hogehoge) HEAD@{1}: rebase -i (squash): コミットB+
549583fe1 HEAD@{2}: rebase -i (squash): # This is a combination of 2 commits.
b536dec90 HEAD@{3}: rebase -i (start): checkout HEAD~3
3c98d9014 HEAD@{4}: rebase -i (abort): updating HEAD
3c98d9014 HEAD@{5}: rebase -i (abort): updating HEAD
bdd5515b2 HEAD@{6}: rebase -i (squash): # This is a combination of 2 commits.
b536dec90 HEAD@{7}: rebase -i (start): checkout HEAD~3
3c98d9014 HEAD@{8}: commit: コミットC
7fc1e2c81 HEAD@{9}: commit: コミットB

git reset --hard で戻す。

$ git reset --hard 3c98d9014                                                                                                                                           
HEAD is now at 3c98d9014 コミットC

reflog見ると、HEADの位置が移動していることが分かる。

$ git reflog -n 12
3c98d9014 (HEAD -> feature/hogehoge) HEAD@{0}: reset: moving to 3c98d9014
78dbdc443 HEAD@{1}: rebase -i (finish): returning to refs/heads/feature/hogehoge
78dbdc443 HEAD@{2}: rebase -i (squash): コミットB+
549583fe1 HEAD@{2}: rebase -i (squash): # This is a combination of 2 commits.
b536dec90 HEAD@{3}: rebase -i (start): checkout HEAD~3
3c98d9014 HEAD@{4}: rebase -i (abort): updating HEAD
3c98d9014 HEAD@{5}: rebase -i (abort): updating HEAD
bdd5515b2 HEAD@{6}: rebase -i (squash): # This is a combination of 2 commits.
b536dec90 HEAD@{7}: rebase -i (start): checkout HEAD~3
3c98d9014 HEAD@{8}: commit: コミットC
7fc1e2c81 HEAD@{9}: commit: コミットB

参考記事