git rebaseとは?コミット履歴をクリーンに保つ使い方ガイド

フィーチャーブランチで開発を進めていると、mainブランチとの差分が大きくなり、マージ時に複雑なコンフリクトが発生することがありますよね。また、試行錯誤の過程で作成した細かいコミットが履歴に残り、後から見返したときにわかりにくくなることもあります。

git rebaseを使えば、コミット履歴を整理して線形でクリーンな状態に保てます。この記事では、rebaseの基本から実践的な使い方、チーム開発での注意点まで解説します。

目次

git rebaseの概要

git rebaseは、あるブランチのコミットを別のブランチの上に再適用するコマンドです。mergeとは異なり、マージコミットを作成せずにブランチを統合できます。

rebase実行時、Gitは以下の手順で処理を行います。まず両方のブランチの共通祖先を見つけ、現在のブランチの各コミットで導入された差分を抽出します。次にターゲットブランチの先端にHEADをリセットし、抽出した変更を順番に再適用します。

この処理により、元のブランチは新しいコミットに置き換えられます。コミットの内容は同じでも、コミットハッシュは変更される点に注意してください。

基本的な使い方

シンプルなrebase

featureブランチをmainブランチの最新状態に追従させる基本的な例です。

# featureブランチにいる状態で
git checkout feature

# mainブランチの変更を取り込む
git rebase main

rebase後、featureブランチのコミットはmainブランチの先端から始まる形になります。

ブランチを指定したrebase

現在のブランチ以外を対象にrebaseすることもできます。

# featureブランチをmainの上にrebase(現在どのブランチにいても実行可能)
git rebase main feature

–ontoオプションで移植先を指定

特定のブランチの一部を別のベースに移植する際に使用します。

# 構文
git rebase --onto <新しいベース> <古いベース> <対象ブランチ>

# 例:topicブランチをnextからmasterに移植
git rebase --onto master next topic

この例では、topicブランチがnextから分岐した後のコミットだけを、masterブランチの上に移植します。

mergeとrebaseの使い分け

mergeとrebaseはどちらもブランチを統合するコマンドですが、結果が異なります。

観点mergerebase
履歴分岐履歴を保持(マージコミット作成)線形履歴を作成
コミット新しいマージコミットを追加コミットを再作成
元のコミット変更なし新しいハッシュで再作成
追跡性並行開発の経緯がわかるシンプルで読みやすい

mergeはチーム協業でブランチの履歴を保持したい場合や、公開ブランチの統合時に適しています。監査目的でコード変更の完全な追跡性が必要なプロジェクトでも有効です。迷った場合はmergeを選ぶのが安全です。

一方rebaseは、ローカルで作業中のコミットを整理したい場合に適しています。プッシュ前のクリーンアップや、フィーチャーブランチをmainの最新状態に追従させる際に使用します。線形履歴によりgit bisectgit logが使いやすくなります。

インタラクティブモード

インタラクティブモードは、rebaseの最も強力な機能の一つです。コミットの編集、統合、削除、順序変更などを対話的に行えます。

起動方法

# 直近5コミットを編集
git rebase -i HEAD~5

# 特定コミット以降を編集
git rebase -i abc1234

利用可能なコマンド

コマンド短縮形説明
pickpコミットをそのまま使用
rewordrコミットメッセージを編集
editeコミットで停止して編集可能に
squashs前のコミットに統合(メッセージ編集可)
fixupf前のコミットに統合(メッセージ破棄)
dropdコミットを削除
execxシェルコマンドを実行

squashとfixupの違い

squashは複数コミットを1つに統合し、すべてのコミットメッセージを編集できます。fixupも同様に統合しますが、統合されるコミットのメッセージは破棄され、統合先のメッセージのみが残ります。

実践例:コミットの整理

開発中に作成した細かいコミットを整理する例を見てみましょう。

# 編集画面(git rebase -i HEAD~4 を実行)
pick abc1234 Add login feature
squash def5678 Fix typo in login
squash ghi9012 Add validation
pick jkl3456 Add logout feature

この設定でrebaseを実行すると、最初の3つのコミットが1つに統合されます。squashを指定したコミットは、直前のpickまたはsquashコミットに統合されます。

コンフリクトの解決

rebase中にコンフリクトが発生した場合、Gitは処理を中断してユーザーに解決を求めます。

解決の流れ

# 1. コンフリクトしているファイルを編集して解決

# 2. 解決したファイルをステージング
git add <解決したファイル>

# 3. rebaseを続行
git rebase --continue

その他のオプション

# 現在のコミットをスキップして次に進む
git rebase --skip

# rebaseを中止して元の状態に戻す
git rebase --abort

rerereで解決を再利用

git rerere(reuse recorded resolution)を有効にすると、過去に解決したコンフリクトパターンを記録し、同じコンフリクトが発生した際に自動的に再適用できます。

git config --global rerere.enabled true

rebaseを頻繁に行うワークフローでは、rerereを有効にしておくと作業効率が上がります。

ベストプラクティス

やるべきこと

ローカルでの整理に活用しましょう。プッシュ前にコミットを整理してクリーンな履歴を作成できます。squashやfixupで実験的なコミットをまとめることで、レビューしやすい履歴になります。

早めに頻繁にrebaseすることも重要です。ブランチの分岐期間が長くなるほどコンフリクトが増えます。定期的にmainの変更を取り込むことで、マージ時の問題を軽減できます。

rebase前にブランチのバックアップを作成しておくと安心です。git branch backup-feature featureのようにバックアップブランチを作成しておけば、問題が発生しても元の状態に戻せます。

避けるべきこと

公開済みコミットのrebaseは絶対に避けてください。他の開発者が参照しているコミットをrebaseすると、チーム全体に影響します。共有ブランチでは絶対にrebaseしないでください。

同様に、mainやmaster等の共有ブランチをrebaseすると、全員のリポジトリに不整合が発生します。

force pushの注意点

rebase後のプッシュには--forceが必要ですが、--force-with-leaseを使用する方が安全です。

# 推奨:他者の変更を上書きしない
git push --force-with-lease origin feature-branch

# 非推奨:他者の変更を上書きする危険あり
git push --force origin feature-branch

--force-with-leaseは、ローカルが認識しているリモートの状態と実際のリモートが一致する場合のみプッシュを許可します。他の人がプッシュした変更を誤って上書きすることを防げます。

便利な設定

pull時にrebaseを使用

git config --global pull.rebase true

この設定により、git pull実行時にmergeではなくrebaseが使用されます。ローカルのコミットがリモートの変更の上に再適用されるため、不要なマージコミットを避けられます。

autosquashを有効化

git config --global rebase.autoSquash true

autosquash機能を有効にすると、fixup!squash!で始まるコミットメッセージがインタラクティブrebase時に自動的に適切な位置に配置されます。

# 元のコミット
git commit -m "Add login feature"

# 修正コミット(後でsquash対象になる)
git commit -m "fixup! Add login feature"

# rebase実行時に自動的にfixupとして配置される
git rebase -i HEAD~2

autoStashを有効化

git config --global rebase.autoStash true

この設定により、作業中の変更がある状態でrebaseを実行すると、自動的にstashしてrebase後に復元されます。

よくある質問

rebaseとmergeはどちらを使うべきですか?

基本的な指針として、ローカルで作業中の未プッシュコミットにはrebaseを、公開済みのコミットや共有ブランチにはmergeを使用します。チームのワークフローに従うことが最も重要で、迷った場合はmergeを選ぶのが安全です。

rebase後にpushできないのはなぜですか?

rebaseはコミット履歴を書き換えるため、リモートブランチと履歴が diverge(分岐)した状態になります。git push --force-with-leaseを使用してプッシュしてください。ただし、共有ブランチでは絶対に行わないでください。

rebaseを取り消す方法はありますか?

git reflogを使用して、rebase前の状態を見つけ、git reset --hardで戻すことができます。

# reflogで履歴を確認
git reflog

# rebase前の状態に戻す
git reset --hard HEAD@{2}

–preserve-mergesは使えますか?

--preserve-mergesオプションはGit 2.22で非推奨となり、代わりに--rebase-mergesが導入されました。マージコミットを含むブランチをrebaseする場合は--rebase-mergesを使用してください。

まとめ

git rebaseはコミット履歴を整理してクリーンに保つための強力なツールです。インタラクティブモードを活用すれば、コミットの統合、編集、順序変更が自由に行えます。

ただし、公開済みのコミットをrebaseすることは避け、ローカルでの作業整理に限定して使用することが重要です。チーム開発では、rebaseとmergeを適切に使い分けることで、効率的なワークフローを実現できます。

まずはgit rebase -i HEAD~3でインタラクティブモードを試してみましょう。コミット履歴を整理する感覚をつかめば、日々の開発がより快適になるはずです。

参考リンク

Git – git-rebase Documentation – 公式リファレンス

Git – Rebasing – Git公式ブックの解説

Merging vs. Rebasing | Atlassian Git Tutorial – mergeとrebaseの使い分けガイド

Git interactive rebase, squash, amend | thoughtbot – インタラクティブrebaseの詳細解説

さらに深く学びたい方へ

この記事で紹介した技術をマスターするには、体系的な学習が重要です。独学で挫折しそうな方は、現役
エンジニアから直接学べるプログラミングスクールも検討してみてください。

現場で通用するスキルを身につけるなら

DMM WEBCAMPのカリキュラムは、実際の開発現場を想定したチーム開発も経験できます。ポートフォリオ制作
支援もあり、転職活動で差をつけられます。

未経験から4ヶ月でエンジニアとして活躍できるレベルまで成長可能です。

実務レベルのWeb開発スキルを習得するなら

RUNTEQは、1000時間の圧倒的学習量で、現場で即戦力となるWebエンジニアを育成します。Ruby on
Railsに特化し、実際のWebサービス開発を通じて実践力を養います。

卒業生の多くが自社開発企業への転職に成功している実績があります。

じっくり理解を深めたい方へ

この記事で紹介した内容を確実に身につけるには、分からない点をすぐに質問できる環境が重要です。CodeCa
mpなら、現役エンジニアとのマンツーマンレッスンで、あなたのペースで着実にスキルアップできます。

朝7時〜夜23時まで、365日受講可能なので、仕事や学業と両立しながら学習を進められます。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次