Git の履歴を rebase でキレイに保つ
以下の記事で紹介したLinear historyというGitのルールで運用するにあたり必須の操作となるのがrebase
です
rebase
を覚えるとGitの履歴をキレイに保つことができるのでリポジトリの肥大化を抑止する意味でも覚えておいたほうがいいコマンドになります。
会社では JetBrains IDE を使っている人が多いため、gitコマンドと、JetBrains IDEでの操作をそれぞれまとめておきます。
git rebase でできること
git rebase は、コミット履歴を綺麗に整理できる超便利なコマンドです。ブランチの起点を変えたり、複数のコミットをまとめたり、コミットメッセージを修正したりと、履歴を自在に操れちゃいます。
履歴がスッキリするので、チーム開発でも重宝されるコマンドです。
rebase するならやっておいたほうが良い git の設定
$ git config --global rebase.autosquash true
$ git config --global pull.rebase true
$ git config --global rerere.enabled true
git config --global rebase.autosquash true
これはコミットを自動で整理してくれる設定です。
コミットメッセージに "fixup!" とか "squash!" と書いておくと、自動的にそのコミットを前のコミットにくっつけてくれる便利設定。
git config --global pull.rebase true
プルするときに自動でリベースする設定。
マージコミットを減らして履歴をきれいに保つのに役立ちます。
git config --global rerere.enabled true
マージやリベースなどの操作におけるコンフリクト解消の際、コンフリクトが発生したファイルの内容を記録し、将来同じコンフリクトが発生したときに自動的に解決を試みます。
rebase 中に同じようなコンフリクトが再度発生した場合でも、以前に解消した内容を基に自動で解決を試みてくれる便利設定です。
ブランチの分岐元を変える
git rebase
の基本的な使い方です。
例えば、現在のブランチを最新の main ブランチに追従させたいときに使います。
現在のブランチがMR2
というブランチの場合、このままmain
にマージしてしまうと、Linear historyにはならないため、rebase
を使って分岐元を変更し、main
の最新のコミットを取り込む必要があります。
$ git rebase main
JetBrains IDEでは、メニューのGit
->リベース
で画面を表示し、rebase対象のブランチ名やhashを入力します。
MR2
ブランチのコミットがmain
ブランチの最新のコミットの後ろに追加されます。
このあと必要に応じてmain
ブランチにマージすると以下のようにLinear historyになります。
コミットをまとめる
複数のコミットを1つにまとめたいときは、git rebase -i
を使います。
$ git rebase -i HEAD~3 # 直近3つのコミットを整理
や
$ git rebase -i <commit_id> # commit_id より後ろのコミットを整理
のように使います。
JetBrains IDEでは、メニューのGit
->リベース
で画面を表示し、オプションを変更
にて、--interactive
を選択して、rebase対象のブランチ名やhashを入力します。
以下のような状態で、現在のブランチがMR1
の場合、
$ git rebase -i 1000001
とすることで、MR1
ブランチのコミットを整理できます。
エディタが開いたら、まとめたいコミットの行頭を squash
や fixup
に変更します。
-
squash
: コミットメッセージを変更して、直前のコミットにまとめます。 -
fixup
: 直前のコミットにまとめます。コミットメッセージは変更できません。
これで複数のコミットを1つにまとめられます。
JetBrains IDEでは以下のような画面が立ち上がり、画面からsquash
やfixup
を設定できます。
commit 1-2
、commit 1-3
をsquash
やfixup
でcommit 1-1
にまとめると以下のようになります。
履歴に残す必要のないコミットはこのようにしてまとめることでリポジトリの肥大化を抑止できます。
コミットを削除する
不要なコミットを削除したいときも git rebase -i
が使えます。
削除したいコミットの行頭を drop
に変更するだけです。簡単ですね。
動作確認のために入れたデバッグコミットなどを削除するのに便利です。
コミットメッセージを書き換える
コミットメッセージを後から修正したいときも git rebase -i
で対応できます。
修正したいコミットの行頭を edit
に変更します。
その後、git commit --amend
でメッセージを修正し、git rebase --continue
で rebase を続行します。
rebase後のgit push
rebase
で履歴を書き換えた場合、git push
ではpushができません。
git push --force
にて強制pushをする必要があります。
git push --force
は危険な操作でもあるので、以下の記事を参考に--force-with-lease
--force-if-includes
でpushするのが安全です。
JetBrains IDEでは以下のような画面で強制プッシュが可能です。
reflog
git rebase
をミスしたときのリカバリー方法として、reflog が使えます。
$ git reflog
このコマンドで、HEAD の移動履歴が見られます。戻りたいポイントの hash を見つけたら、
$ git reset --hard <hash>
で、そのポイントまで戻れます。
rebase で失敗しても、この方法で元に戻せるので安心してrebase
できます。
このように、git rebase
は履歴を自在に操れる強力なツールです。
使いこなせば、キレイな履歴を保ちながら効率的に開発できますよ。
Discussion