git rebaseでsquashする

photo credit: Jeremy Kendall via photopin cc

Merge Requestを送った後の指摘に対応していたところ、「squashしてコミットを1個にまとめて」と言われたので、手順を調べた。

squashには2種類ある

squashはすべてのコミットを1つにまとめるもので、調べたら、以下の2種類があることが分かった。

  • git merge --squash [branch or commit]
  • git rebase -i [commit]

git merge –squash [branch or commit]

前者はgit mergeコマンドで実行している通り、[branch or commit]で指定した内容を1つにまとめてmergeする。

今回、Merge Requestを送った自分に対して「squashしろ」と言っているので、これとは別対応になる。

git rebase -i [commit]

後者はgit rebaseコマンドで実行している通り、[branch or commit]で指定した内容を1つにまとめてrebaseする。

今回、Merge Requestを送った自分に対して「squashしろ」と言っているので、こちらが必要な対応になる。

実行例

事前準備(何度かコミットしているファイルの準備)

$ echo add file >> test_file
$ git add test_file
$ git commit -m "Add test_file"
[master (root-commit) xxxxxxx] Add test_file
 1 file changed, 1 insertion(+)
 create mode 100644 test_file
$ echo edit one >> test_file
$ git add test_file
$ git commit -m "Modify 1"
[master yyyyyyy] Modify 1
 1 file changed, 1 insertion(+)
$ echo edit two >> test_file
$ git add test_file
$ git commit -m "Modify 2"
[master zzzzzzz] Modify 2
 1 file changed, 1 insertion(+)
$ echo edit two >> test_file
$ git add test_file
$ git commit -m "Modify 3"
[master 1111111] Modify 3
 1 file changed, 1 insertion(+)
$ cat test_file 
add file
edit one
edit two
edit three

これらのコミットを1つにまとめるためにsquashする。

$ git rebase -i HEAD~3
pick yyyyyyy Modify 1
squash zzzzzzz Modify 2 <--これをsquashするのでpickから変更する
squash 1111111 Modify 3 <--これをsquashするのでpickから変更する

# Rebase xxxxxxx..xxxxxxx onto xxxxxxx
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# 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

pickからsquashに変更後保存すると、以下のコミットメッセージを編集する画面に切り替わる。

# This is a combination of 3 commits.
# The first commit's message is:
Modify 1

# This is the 2nd commit message:

Modify 2

# This is the 3rd commit message:

Modify 3

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      xxxxxxxx
#
# rebase in progress; onto xxxxxxxx
# You are currently editing a commit while rebasing branch 'master' on 'xxxxxxxx'.
#
# Changes to be committed:
#  modified:   test_file
#

保存すると、以下のようにコミットを1つにまとめることができる。ちなみにaddにまとめることはできない。

$ git log
commit yyyyyyy
Author: xyz 
Date:   yyyyyyy

    Modify 1
    
    Modify 2
    
    Modify 3

commit xxxxxxx
Author: xyz 
Date:   xxxxxxx

    Add test_file