5分で理解するgit-absorb
実際のプロジェクトで、タイポ修正やロジックの微調整といった細かなコミットを、git rebase -iを使ってメイン의コミットにまとめる作業は日常茶飯事でしょう。しかし、これまでの手順はかなり面倒でした。過去のコミットのハッシュ値を探し、git commit --fixup <hash>を入力し、それからautosquashを実行する。ハッシュ値をコピー&ペーストするだけでも、積み重なるとストレスになります。
git-absorbは、そんな手作業をスキップさせてくれるソリューションです。ハッシュ値を自分で探す代わりに、ツールが現在の変更内容を最近のコミット履歴と自動で照合します。そして、そのコードが元々書かれたコミットに対して、自動的に修正を「吸収(absorb)」させてくれるのです。
クイックスタート:
- コードを修正してバグを直す、または変更を追加する。
git add .でファイルをステージングする。git absorbを入力する。git rebase -i --autosquash @{u}を実行してクリーンアップを完了させる。
# 10秒で完了する実際の例
$ git add src/services/auth.py
$ git absorb
# ツールが自動で過去のコミットを見つけ、即座にfixupコミットを作成します
$ git rebase -i --autosquash @{u}
なぜ従来の方法ではなくgit-absorbを使うべきなのか?
想像してみてください。PR(プルリクエスト)にすでに10〜15個のコミットが積み重なっている状態で、シニアエンジニアから最初のコミットに含まれる小さなバグを指摘されたとします。どのコードがどのコミットに属しているかを履歴から探し出すのは、非常に時間がかかり、ミスも起きやすい作業です。
基本的に、git-absorbはgit blameに似た仕組みで賢く動作します。インデックスにステージングされた各行をスキャンし、その行がHEAD..@{u}の範囲内のどのコミットで最後に変更されたかを特定します。安全なターゲットコミットが1つだけ特定できれば、対応するfixup!コミットを自動的に作成します。
主なメリット:
- 生産性の向上: 手動でハッシュを入力する方法に比べ、PRのクリーンアップごとに約2〜3分を節約できます。
- 圧倒的な正確さ: 修正先を間違えることがなくなり、リベース時のコンフリクト発生を抑えられます。
- レビュアーへの配慮: PRを出す前にコミット履歴を常に美しく保てます。大量の「fix typo」のような無駄なコミットが並んでいるよりも、整理された履歴の方がレビュアーも確認しやすくなります。
git-absorbのインストール
このツールはRustで書かれているため、非常に軽量で高速です。cargoや主要なパッケージマネージャーからインストールできます。
macOSの場合:
brew install git-absorb
Linux (Ubuntu/Debian)の場合:
sudo apt install git-absorb
# または、ディストリビューションにパッケージがない場合はcargoを使用します
cargo install git-absorb
Windowsの場合:
RustとCargoをインストールした後、以下のコマンドを実行します:
cargo install git-absorb
実践的なワークフロー
私は毎日この組み合わせを使って、PRを常に整った状態にしています。例えば、ログイン機能を開発中で、3つのコミットがあるとします:1. Init Database、2. Add Auth Service、3. Update UI。
突然、1番目のコミットにある変数 user_token の名前が間違っていることに気づきました。「fix: rename variable」のような新しいコミットを作る代わりに、次のようにします:
- コード内の変数名を正しく修正する。
git add .を実行する。git absorbを入力する。この時、ツールはこの変更が「Init Database」コミットに属することを自動的に理解し、その直後にfixupコミットを作成します。- 最後に、
git rebase -i --autosquash @{u}を実行します。すべて自動で配置されているので、保存して終了するだけです。
注意: git-absorbはgit addされた変更のみを対象にします。ステージングを忘れると、処理するものがないと報告されます。
教訓:Force Pushによる事故を防ぐ
git-absorbを使ってリベースした後は、履歴が書き換わるため強制プッシュ(force push)が必要になります。安全のために、--forceではなく常にgit push --force-with-leaseを使用しましょう。
このコマンドは、自分がリベースしている間に同僚が同じブランチに新しいコードをプッシュしていないかを確認してくれます。もしプッシュされていた場合、上書きを防ぎ、他人のコードを消してしまう事故を回避できます。小さな習慣ですが、チーム内での信頼を守るために重要です。
個人的には、このツールは「コーディングフロー」に乗っている時に非常に役立つと感じています。別の作業中に小さなミスを見つけても、サッと直してgit add、git absorbするだけ. 思考を中断することなく、すぐにメインのロジックに戻ることができます。
プロのための上級テクニック
1. エイリアスを設定してさらに高速化
速度を最大化するために、.gitconfigファイルにエイリアスを追加しましょう:
[alias]
ab = absorb
ri = rebase -i --autosquash
これで、最強のクリーンアップコンボは git ab と git ri @{u} だけになります。爆速です!
2. スキャン範囲の制限
デフォルトでは直近10コミットを遡ってスキャンします。より深く遡りたい場合は、特定の地点を指定できます:
git absorb --base <commit-hash>
3. git-absorbが苦手なケース
万能ではありません。修正した行が複数の異なるコミットに関連し、競合が発生する場合、ツールは「multi-candidate」エラーを出します。最初からコミットを細かく分けていれば稀なケースですが、もし遭遇した場合は、手動でリベースする必要があります。
まとめ
git-absorbを使うことは、仕事のスタイルをアップグレードすることに繋がります。面倒なGitの手続きはツールに任せ、自分はコードに集中しましょう。ジュニアエンジニアの皆さんにとって、こうした「小さくても強力なツール」を使いこなすことは、シニアエンジニアから見てプロフェッショナルで洗練された印象を与えるはずです。
ぜひ今のプロジェクトに導入してみてください。一度使えば、もう手動リベースの時代には戻れなくなるはずです!

