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

複数のコミットを1つにまとめるとき、いつも 「5. rebase -i でコミットをまとめる」 を参考にしてるんだけどメモしておく。


rebase -i

rebase -i でコミットを4コミット分まとめます。(~を4つ)

$ git rebase -i HEAD~~~~

または

$ git rebase -i HEAD~4

するとテキストエディタ(たいていvim)が開き、HEADから4つ分のコミットが表示されます。

pick 8145f1c Fix screen rotation problem

pick d90db4a v1.2.4
pick 646bf79 Fix screen rotation problem
pick 71a6940 v1.2.4

# Rebase ed7420a..71a6940 onto ed7420a
#
# 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.
#

ここでは同じコミットメッセージの「8145f1c」と「646bf79」、「d90db4a」と「71a6940」をまとめます。

順序変更を含めて次のように、picksまたはsquashへ変更します(今回はs)。

pick 8145f1c Fix screen rotation problem

s 646bf79 Fix screen rotation problem
pick d90db4a v1.2.4
s 71a6940 v1.2.4

# Rebase ed7420a..71a6940 onto ed7420a
...

するとコミットメッセージを統合するためのエディタが2回開きます。

例えば1つ目は次のように、修正します。

# This is a combination of 2 commits.

# The first commit's message is:

Fix screen rotation problem

# This is the 2nd commit message:

Fix screen rotation problem

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Not currently on any branch.
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: app/src/main/java/jp/takke/datastats/LayerService.java
#

Fix screen rotation problem

# ...

これでコミットがまとまりました。


git log で確認

$ git log -2

commit 0fdbb3d37c0f793ed3f93f0600fdc3d90972f050
Author: takke <takke30@gmail.com>
Date: Tue Mar 3 17:07:27 2015 +0900

v1.2.4

commit 3735ff495d700822f237997f925c33746861438d
Author: takke <takke30@gmail.com>
Date: Tue Mar 3 17:07:08 2015 +0900

Fix screen rotation problem

このようにハッシュ値は新たな値が割り振られますが変更日時はpickのほう(各squashの1つ前のコミットのほう)になります。


git push -f

あとはリモートリポジトリに push するわけですが、コミットハッシュが変わるので -f が必要です。

※言うまでもないですが共同開発のリモートリポジトリ・ブランチに安易に git push -f するのは御法度ですよ。

$ git push

...
To git@github.com:takke/TkTrafficMonitorSample.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:takke/TkTrafficMonitorSample.
git'

hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

$ git push -f

...
Counting objects: 26, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (13/13), done.
Writing objects: 100% (15/15), 1.34 KiB, done.
Total 15 (delta 9), reused 0 (delta 0)
To git@github.com:takke/TkTrafficMonitorSample.git
+ d90db4a...0fdbb3d master -> master (forced update)

以上です。


参考文献