Gitで複数のcommitを一つにまとめる方法

複数人で開発をしているとよくこんなことがあると思います。


pull requestー!

師匠「ここ修正してくださーい!」

修正は完了したけど、どうリポジトリに反映すれば…?
修正した後のコミットが増えちゃうの嫌だし、一つにまとめたいなぁ。
ブランチを消して再pushもしたくないし…


そんなときは以下のように操作します。
まず修正したいブランチに移動します。

$ git checkout branch_name


指摘された点を修正し、コミットします。

$ git commit -m "Fix hoge!"


ここで直前のコミットを2つ前のコミットにリベースします。
(←同一ブランチ内でのリベースもできるのね!)
オプション-i を指定します。
これはinteractiveモードで、各コミットに対して操作を指定するためのオプションです。
i 以降で編集対象を指定します。HEADは最新のコミットを表していて、^^ は最新のコミットから2つ前までのコミットを編集することを表しています。
HEAD^^ の部分は HEAD~2 とも書けます。

$ git rebase -i HEAD^^ 


するとvimが立ち上がります。

pick 5c30631 Delete unused gemfile
pick 7f01e5e Fix hoge!

# Rebase 8bdb124..7f01e5e onto 8bdb124
#
# 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を指定したコミットに統合し、コミットメッセージは破棄したいのでfixupを指定します。

pick 5c30631 Delete unused gemfile
f 7f01e5e Fix hoge!

# Rebase 8bdb124..7f01e5e onto 8bdb124
#
# 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

保存すると複数のコミットを一つにまとめるためのリベースが完了します。

あとは、リモートリポジトリにpushしてあげるとコミットが一つにまとまった状態で反映されます。

git rebase -i が使えるようになるとgitの幅が広がった感があります。


Gitによるバージョン管理

Gitによるバージョン管理