git rebaseが難しすぎたので、自動化CLI作った
はじめに
git rebase、怖くないですか?
開発を進めていると、ブランチの歴史をきれいに保つために git rebase
を使いたくなる場面がよくあります。フィーチャーブランチを main
や develop
の最新状態に追従させたいときなどです。
しかし、git rebase
は強力な反面、多くの開発者にとって悩みの種でもあります。
- 大量のコンフリクト: rebaseを実行したら、大量のコンフリクトが発生してしまい、1つ1つ解決するのが大変...
- どのコミットで問題が起きたかわからない: 複数のコミットを一度にrebaseすると、どのコミットが原因で問題が起きたのか追うのが難しい
- マージコミットの存在: rebase中に意図しないマージコミットが含まれていて、歴史が余計に複雑になってしまった
-
そもそもコマンドが難しい:
git rebase --interactive
,git rebase --continue
,git rebase --abort
... 状況に応じたコマンドを正しく使い分けるのは、慣れていないと怖い
こうした git rebase
の難しさや恐怖心から、結局 git merge
を使ってしまい、ブランチの歴史が複雑になってしまう...という経験をした方も多いのではないでしょうか。
そんな悩みを解決するために、git rebase
を安全かつ対話的に実行できるCLIツール agrb
(auto git rebase) を開発しました。
agrb
とは?
agrb
は、現在のブランチを別のブランチ(例:main
)の最新状態へ安全に載せ替える(rebaseする)ためのCLIツールです。
https://github.com/riya-amemiya/agrb
最大の特徴は、2つのrebase戦略をサポートしている点です。
-
cherry-pickベースの安全なrebase(デフォルト): マージコミットを無視し、現在のブランチのコミットだけを1つずつ
cherry-pick
していく方法。コンフリクトが発生したコミットは自動でスキップされるため、安全にrebaseを完了できる -
線形履歴を作る
git rebase
: 従来のgit rebase
を使って、きれいな線形の歴史を作る(コンフリクト発生時に自動で解決を試みるオプションもあります)
また、UIライブラリである Ink を採用しており、rebase先のブランチを対話的に選択できるため、ブランチ名を正確に覚えていなくても直感的に操作できます。
インストールと使い方
インストール
npm経由でグローバルにインストールできます。
npm install --global agrb
使い方
基本的な使い方は、rebaseしたいブランチで agrb
コマンドを実行するだけです。
agrb
ターゲットブランチを指定しない場合、対話的なブランチ選択画面が表示されます。
矢印キーでrebase先のブランチを選んでEnterキーを押すだけで、安全なrebaseが実行されます。
フィルタリング機能もあるので、ブランチ名を正確に覚えていなくても直感的に操作できます。
もちろん、オプションでターゲットブランチを直接指定可能です。
# mainブランチにrebaseする
agrb --target main
きれいな線形履歴を作りたい場合は、--linear
オプションを使います。
# developブランチに対して、線形のgit rebaseを実行
agrb --target develop --linear
# コンフリクトが発生しても、"ours"戦略で自動解決を試みる
agrb --target main --linear --continue-on-conflict
agrb
の内部的な仕組み
agrb
がどのようにして安全なrebaseを実現しているのか、その心臓部を少しだけご紹介します。
1. 安全なcherry-pickモード(デフォルト)
このモードは、git rebase
の複雑さをユーザーから隠蔽し、安全性を最優先に設計されています。
-
下準備: まず、ターゲットブランチ(例:
main
)からtemp-rebase-xxx
のような一時的なブランチを作成 -
差分コミットの特定:
git merge-base <ターゲットブランチ> <現在のブランチ>
コマンドで2つのブランチの共通の祖先を特定し、その祖先から現在のブランチのHEADまでのコミットリストを取得 -
コミットの再生: 取得したコミットリストを1つずつ、一時ブランチに対して
git cherry-pick
- このとき、マージコミットは自動的にスキップ。これにより、rebaseの歴史が不必要に複雑になるのを防ぐ
-
cherry-pick
中にコンフリクトが発生したり、コミットが空(empty)になったりした場合、そのコミットは自動的にスキップ
-
仕上げ: すべてのコミットの
cherry-pick
が完了したら、現在のブランチのHEADを一時ブランチのHEADにgit reset --hard
で移動 - 最後に、一時ブランチを削除して完了
この仕組みにより、git rebase
のように歴史を書き換える際の危険性を最小限に抑えつつ、ブランチを最新の状態に保つことができます。
--linear
)
2. 線形rebaseモード (こちらは、より伝統的な git rebase
を使いたいユーザー向けのモードです。内部的には git rebase origin/<ターゲットブランチ>
を実行します。
--continue-on-conflict
オプションが指定されている場合、コンフリクトが起きても処理を止めず、-X ours
戦略(自分たちの変更を優先する)で自動的にコンフリクトを解決し、git rebase --continue
を試みます。
まとめ
git rebase
はもう怖くありません。agrb
を使えば、日々のブランチ運用がより安全で、より快適になるはずです。
- コンフリクト解決に疲れた...
- もっと気軽にブランチを最新にしたい...
-
git
の複雑なコマンドを覚えたくない...
そんな方は、ぜひ一度 agrb
を試してみてください。
リポジトリはこちらです。IssueやPull Requestも歓迎しています!
コントリビューション方法はCONTRIBUTING.mdをご覧ください。
Discussion