みなさんgit使いこなせていますか?
gitのcommitが積み上がるのはいいけど、うまく整理したい!
そんな時に便利なコマンドが git rebase -i
です。
git rebase
rebase
コマンドは基本的にcommitを修正するためのコマンドと言ってもいいでしょう。
git rebase master
なんかはみなさんもよく使っているのでは?
今回紹介するのは、そんなrebase
のオプションの-i
いわゆる--interactive
ってやつです。
使い方のフロー
今回は、gitの履歴で、以下のようなシーンを想定しています。
- 採用したくないcommitがある時
- commitを統合したいとき
- wipなどのcommitがあるとき
それでは早速使って行きましょう。
と、その前に全体を通しての使い方を先に書いておきます。
修正したいcommitが積まれているブランチで以下のコマンドを打ち込みます
git rebase -i HEAD~5
~5
の部分は修正したいcommitが入る分だけのcommit履歴数が入る数字にしましょう。
最新の状態から3つ分以内を修正したい場合は HEAD~3
です。
ここで注意点ですが、
必要以上のcommitをHEAD~
に含めてしまうとgit push
した際に余分なものもpushしてしまいがちなので注意。
採用したくないcommitがある時
さて、採用したくないcommitがある時の使用フローを書きます。
状況はこんなかんじとします。
$ git log --oneline dbc05cb third 0b88237 second 2a570af first
3つのcommitが積み上がっているとします。
2番目のcommitをなかったことにしましょう。
git rebase -i HEAD~2
と打ち込みます。
pick 0b88237 second pick dbc05cb third # Rebase 2a570af..dbc05cb onto 2a570af (2 commands) ...
するとvimが起動し、このような画面になるはずです。
ここで、それぞれのcommitをどう処理するかを記述します。
pick
はcommitとして採用
s
は下のcommitと統合
1行削除するとcommitがなかったことになります(drop)
今回は2番目のcommitをなかったことにしたいので、1行削除して保存します。
vimの場合は保存はesc
を押してから:wq
で保存して終了できます。
その後、logをみてみましょう。
git log --oneline
を打って見ます。
$ git log --oneline dc52c71 third 2a570af first
お見事!2番目のcommitであるsecond
がない状態となりました。ヤッタネ。
この状態でpushするには、-f
のオプションが必要となります。commitの書き換えを行なっているので、リモートのorigin/master
と差分ができてしまうのは仕方ありません。
git push -f origin <branch>
でOKです。
統合したいcommitがある場合
さて、では次にwipのcommitなど、不必要だけど更新があるcommitを統合したい場合を書きます。
状態はやはりこの状態から。
$ git log --oneline 1fc4b87 second 0903db0 wip 2a570af first
wipのcommitがある状態なので、これを first
と、second
だけの状態にします。
もちろん、wipのcommitの更新分は反映されるようにします。
git rebase -i HEAD~2
を実行します。
pick 0903db0 wip pick 1fc4b87 second # Rebase 2a570af..1fc4b87 onto 2a570af (2 commands) ...
vimが起動し、このような表示がされるはずです。
ここで、wipのcommitのpick
をs
に変更します。
s 0903db0 wip pick 1fc4b87 second # Rebase 2a570af..1fc4b87 onto 2a570af (2 commands) ...
こんな感じです。
これで、保存してみましょう。
するとあら不思議、logをみると綺麗になっています。
と、思いきやできませんでした。
rebase -i
でのs
による統合は、以前のcommitに統合されるようです。
first
のcommitは最初のcommitであるため、認識されずに失敗してしまったようです。
気を取り直して、作り直しました。
$ git log --oneline 0958e38 third a7e62a8 wip 22d29bf second 2a570af first
この状態から、git rebase -i HEAD~3
を実行。
pick 22d29bf second pick a7e62a8 wip pick 0958e38 third
このwipのcommit部分を
pick 22d29bf second s a7e62a8 wip pick 0958e38 third
s
にしてあげて保存します。
すると、次のcommitメッセージ変更状態になります。
# This is a combination of 2 commits. # This is the 1st commit message: second # This is the commit message #2: wip
以上の内容をまとめたいcommitメッセージだけにします。
例えばこんな感じ。
second
不必要な部分は消しました。そして保存。
これでwipなどのcommitをその前のcommitと統合することができました!!
エラー
fatal: Needed a single revision invalid upstream HEAD~3
このようなエラーがよくでます。
first commit の分は認識されないようです。
そりゃ、最初のcommitがないと起点がなくなるわけですので、そちらはいじることはできない、ということでしょう。
参考
こちらにより詳しい内容が書いています。