複数のコミットを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」をまとめます。
順序変更を含めて次のように、pick
をs
または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)
以上です。