スマレジエンジニアyushiのブログ

スマレジエンジニアのブログ

git rebase -i でcommit履歴をコントロールする

前回に続いてgitの話題です。

gitとは履歴管理の仕組みであり、履歴が整っているほど性能も発揮しやすいです。

とはいえ、ガリガリ開発していると、あっちこっちの追加・修正履歴が入り混じってしまうもの。

例えば、

機能Aの追加
機能Bの追加
機能Aの微調整
機能Cの追加
機能Aの微調整
機能Cの削除

といった感じです(上の方ほど古いcommit)。

これを、

機能Aの追加
機能Bの追加

というように整理できると、後々機能Aの実装を見返したり、機能BだけRevertみたいなことがしやすくなります。

これを実現するのが、git rebase -i というコマンドです。

git rebase -i の使い方

-i とは --interactiveの意味ですが、文字通りinteractiveな操作でcommit履歴を操作します。

git rebase -i [commit hash]

ここで[commit hash]は、編集したい範囲の直前のcommit hashを選択します。
もちろん、branch名やtag名でもOKです。

commit 履歴

f:id:yushi0:20210123164235p:plain

コマンド

git rebase -i start

コマンドの実行結果

f:id:yushi0:20210123164326p:plain

この実行結果はviの編集画面となっており、pickの箇所をrewordとしたり、
行を並び替えたりしてcommit 履歴を編集します。

reword

commit messageを編集します。

rebase -i の画面

f:id:yushi0:20210123164524p:plain

この状態で保存すると、commit messageの編集画面が表示されます。

commit 2の行で、pick を r(rewordの略)に編集しています。

commit messageの編集画面

f:id:yushi0:20210123164647p:plain

commit 履歴

f:id:yushi0:20210123164812p:plain

edit

過去のcommitを編集できます。

rebase -i の画面

f:id:yushi0:20210123165157p:plain

commit 2の行で、pick を e(editの略)に編集しています。

実行後

f:id:yushi0:20210123165325p:plain

commit 2をcheckout した状態になります。
この状態でcommit --amendを使うとcommit 2の内容を編集できます。
git rebase --continueで、編集を終了します。

並び替え

-i の画面で行の並び順を変えると、履歴上の順番も変わります。

f:id:yushi0:20210123171822p:plain

commit 2とcommit3の順番を入れ替えています。

実行後のcommit 履歴

f:id:yushi0:20210123171922p:plain

rebase -iで変更した通りの順番になっています。

squash, fixup

複数のcommitを1つcommitにまとめることができます。

squashを試してみます。

rebase -i の画面

f:id:yushi0:20210123172053p:plain

commit 2のpickの箇所をs(squashの略)に変更しています。

commit 履歴, git show の実行結果

f:id:yushi0:20210123172522p:plain

f:id:yushi0:20210123172627p:plain

commit 2 がcommit 3に吸収されています。

(画像からだとわからないですが、commitの内容も合体しています)

今回はsquashを試しましたが、fixupの場合はcommit messageが反映されずに削除されます。

drop

commit自体削除します。

f:id:yushi0:20210123173457p:plain

pickをd(dropの略)に変更しています。

f:id:yushi0:20210123173716p:plain

commit履歴から削除されました。もちろんcommit 内容も削除されています。

まとめ

gitの中でも、git rebase -iはかなりややこしいコマンドです。

その分使いこなせるとできると多いです。