はじめに
こんにちは。anyでエンジニアをしている @koukibuu3 です。
この記事はanyプロダクトチームAdventCalendar2025、#3 の10日目です。
この記事では Git のコマンドの1つである rebase の使い方とメリット/デメリット、チーム開発で運用する場合の注意点について触れていきます。
筆者は rebase 推奨派ですが、いついかなる時も rebase を使うべき!と主張するつもりはありません。この記事で紹介する内容は、用法用量を守って適切に運用してもらえると幸いです。
git merge と git rebase の違い
merge は、ベースブランチの変更を取り込む際に マージコミットを1つ生成して履歴を統合する コマンドです。一方で git rebase は、現在のベースブランチの先端に、自分のコミットを「付け替える」 動作をします。
結果として、履歴が一本の直線になり、merge のようなマージコミットは発生しません。
ただし、rebase は「コミットを書き換える」性質を持つため、履歴を改変する点が大きな違いです。実務上はこの特性を理解して使う必要があります。
git pull のデフォルト動作について
ちなみに git pull コマンドは初めて実行した際に以下のメッセージが出ます。
git config pull.rebase false # merge (the default strategy)
git config pull.rebase true # rebase
git config pull.ff only # fast-forward only
デフォルトでは、
git pull = git fetch + git merge
という動作をします。
一方で、
git config pull.rebase true
を設定しておくと、git pull は、
git fetch + git rebase
として動作するようになります。
rebase を使って履歴の整理をする
日常的に活用しやすい rebase の使い方として、PR を出す前に過去のコミットへ修正をまとめたい場面があります。
例えば、ある機能の実装を進めている途中で「前のコミットの修正が必要だった」と気づき、つい fix: ◯◯の修正 のような追記コミットを重ねてしまうことがあります。
もちろん動作としては問題ありませんが、他者がコミット履歴を順に追って差分を確認する際、本来1つのまとまりとして完成しているはずの機能修正が「途中の未完成状態 → 追加修正 → さらに微調整」のように分断されて並ぶという状態は、理解の負荷が高くなります。
そこで役に立つのが rebase です。
修正対象のコミットを選択し、追加したい内容をそのコミットへ 統合することで、一つの意味単位としてまとめることができます。
これにより、履歴がスッキリし、レビューする側にも意図が伝わりやすくなります。
コミットを「意味のある単位」に整理することは、単に履歴を綺麗にするだけでなく実装者自身が抜け漏れを見直す機会にもなります。
- 本当にこのコミットで機能が完結しているか
- 不要な変更が紛れ込んでいないか
- 説明可能な粒度になっているか
こうした観点で見直せるため、品質向上の効果が意外と大きい点も重要です。
ちなみに、VSCode 派生のエディタで GitLens — Git supercharged の拡張機能を入れると、Git周りのサポートが大幅に強化され、rebase の GUI も提供されます。
複雑な履歴を操作したい場合は GUI を使うのが便利です。

▲ 対象のコミットを右クリックして「Rebase Current Branch onto Commit...」を選択

▲ GUI で rebase のインタラクティブモードが開く
rebase に付随して抑えるコマンド
rebase を日常的に使うなら、あわせて抑えておくと便利なコマンドをいくつか紹介します。
git push --force-with-lease
ローカルで rebase を実行すると、書き換えられた履歴とリモートの履歴が一致しなくなるため、そのままではプッシュが拒否されます。この差分を上書き反映するために使うのが --force-with-lease オプションです。
git push --force-with-lease
--force と違い、リモート側で自分の知らない更新が発生していないかを安全に確認したうえで強制プッシュを行ってくれるため、他人の作業を誤って消してしまうリスクを下げられます。
レビュー中のブランチに対して git push --force-with-lease を実行すると、レビュアーが見ていた差分が書き換わり、指摘やコメントが対応関係を失うことがあります。レビュー負荷を無駄に増やさないためにも、基本的には Draft の段階で履歴整理を済ませ、以降は必要があるときだけ事前に共有して行うと安全です。
git commit --fixup
git commit --fixup は、特定のコミットに対して「この修正を後で統合してほしい」という印を付けるコマンドです。
dfc67acb feat: 一覧コントローラーの新規作成
1f315272 feat: 一覧ビューの新規作成
もし、一覧コントローラー(dfc67acb)に修正が必要になった場合、次のように fixup コミットを作成できます。
git commit --fixup dfc67acb
すると、コミットメッセージとしては、以下のようになります。
この fixup! が統合対象を示す印です。
4320bf0d fixup! feat: 一覧コントローラーの新規作成
この段階ではただ「印を付けただけ」ですが、次に紹介する autosquash と組み合わせると一気に威力を発揮します。
git rebase --autosquash
--fixup で印を付けたあとは git rebase --autosquash の出番です。
git rebase --autosquash -i 1f315272
--autosquash のオプションを付けて実行すると、自動的に位置調整 & 修正コミット統合をしてくれます。
本来なら vi 上で「このコミットをここに移動して…」という作業が必要ですが、それらをほぼ自動化してくれるため、履歴整理が格段に楽になります。
fixup + autosquash は、rebase 運用の強い味方です。
git commit --amend
「わざわざ fixup して rebase するほどではないが、直前のコミットだけ微修正したい」という場面では --amend が便利です。
git commit --amend
これは 直前のコミットを置き換えるコマンドで、現在ステージに上がっている変更を含めて再コミットします。小さな修正なら、fixup よりこちらのほうが手軽です。
ただし、コミットを新しく作り直すため、コミットハッシュは必ず変わります。
rebase と同じく公開済みブランチに対して不用意に実行すると混乱の元になるため、基本的にはローカルの作業ブランチで使うのが安全です。
まとめ
rebase は、履歴を読みやすく整えたり、コミットを意味のある単位にまとめたりするうえで、とても強力なツールです。--fixup や --autosquash、--amend といった関連オプションを組み合わせることで、実装者自身が変更内容を振り返りやすくなり、レビューする側にとっても理解しやすい履歴を提供できます。
一方、履歴を書き換えるという性質上、使いどころを誤るとチーム全体の作業を妨げる可能性があります。レビューの進行状況や、誰がどのブランチを利用しているかを意識しながら、適切なタイミングで活用しましょう。
履歴を整える目的と、チーム開発の安全性。この2つのバランスをうまく取りながら運用していけば、rebase は日常的に使える頼れる味方になります。
