🎡
GitのMergeとRebaseの違いを徹底解説:安全な使い分けと実践コマンド集
はじめに
日々の開発で避けて通れないブランチ統合。Git には代表的な統合手段として Merge と Rebase があります。どちらも「あるブランチの変更を別のブランチへ取り込む」点は同じですが、履歴構造 と チーム運用 への影響が大きく異なります。
本記事では、概念の違いに加えて、実務でそのまま使えるコマンド例、コンフリクト解消の流れ、失敗時の復旧などを解説します。
ざっくり結論
-
共有ブランチ(
main/develop)への取り込みは基本的に Merge:既存コミットの コミットIDをそのままの状態で保存でき、後からの追跡・監査がしやすい。 - 自分の作業ブランチの整形には Rebase:PR前に履歴を直線化し、レビューを読みやすくしよう。コミット履歴を一つにまとめるのもおすすめ。
-
公開済みブランチでの
rebaseは原則禁止:履歴を書き換えるため、他メンバーのローカルと乖離し混乱の元になる。
Merge と Rebase の違い(イメージ)
Merge(分岐→統合が残る)

git switch main && git merge feature の後

Rebase(feature を main の先頭へ付け替え)

- Merge は マージコミット を作り、分岐と統合の履歴を残します。
- Rebase は コミットを複製して付け替えるため、コミット ID(SHA) が変わります(リンクや参照が無効になる可能性)。
コマンド例(実務直結)
1) 個人開発:最新 main を取り込んでから PR を出す
目的: コンフリクトを早めに解消し、きれいな履歴で PR を作る。
# 作業ブランチにいる前提(feature/AAA)
# 1. 最新を取得
git fetch origin
# 2. 付け替え(書き換え)
git rebase origin/main
# 3. コンフリクトが出たら解消して…
# 各ファイルを編集 → 解消したファイルを add
git add ファイル名
git add . でも可
# 4. リベース続行
git rebase --continue
# 5. 履歴が変わったので安全な強制プッシュ(ブランチ明示推奨)
git push --force-with-lease origin feature/AAA
--force-with-leaseは、リモート先が自分のローカルが知っている最新と一致している場合のみ 上書きします。誰かが先に push していたら拒否されるため、--forceより安全です。
2) チーム開発:PR を Merge で取り込む(履歴を残す)
目的: いつ、どのブランチが統合されたかを残す。
# 例:GitHub/GitLab 上で「Merge pull request」を実行
# CLI なら:
# 1. main を最新化
git switch main
git fetch origin
# fast-forward 可能なときのみ成功(不可なら失敗)
git pull --ff-only
# 2. feature をマージ(マージコミットを必ず作る)
git merge --no-ff feature/login
# 3. リモートへ反映
git push origin main
git pull --ff-onlyは fast-forward できない場合に失敗します。その際はgit fetch後にgit merge --no-ff origin/mainなど、意図を明示して選択しましょう。
3) ローカルの履歴を整理したい
目的: fixup や squash でコミットをまとめ、レビュー単位に整える。
# 1. 直近の 5 コミットを整理(autosquash で fixup!/squash! を自動畳み込み)
git rebase -i --autosquash HEAD~5
# エディタ例:
# pick 1234 add login form
# fixup abcd fix typo
# squash ef00 add tests
# pick 99aa impl oauth
# pick 77bb docs
# 2. 自分でsquashの付け先を決めて整理する
git log
# 自分の変更の一つ前のコミットID(SHA)をコピー
git rebase -i コミットID(SHA)
マージエディタ内でpick squash fixup などを選択
# エディタ例:
# squash 1234 add login form
# squash abcd fix typo
# squash ef00 add tests
# squash 99aa impl oauth
# pick 77bb docs
コンフリクト解消の実践フロー
- リベース中のコンフリクト発生(
CONFLICT表示) - 該当ファイルを開き、
<<<<<<,======,>>>>>>を解消 -
ビルド/テストを回して確認(例:
pnpm test/go test ./.../bundle exec rspec) - 解消済みファイルのみ
git add <file> -
git rebase --continue(やり直すなら--abort)
git status # どこで止まっているか確認
git diff --cc # 競合箇所の統合差分
git checkout --ours path/to/file # ours/theirs の一括採用
git checkout --theirs path/to/file
git add <file>
git rebase --continue
小技:
git config --global rerere.enabled trueで「過去の解決パターン」を学習・再利用できます。
すこしでも違うと感じたらgit rebase --abort を使用して作業を1からやり直そう。
失敗した時の復旧(超重要)
reflog で過去の位置に戻る
# 直近の HEAD の移動履歴を一覧
git reflog
# 例: HEAD@{3} の位置へ戻す
git reset --hard HEAD@{3}
# 退避用タグ(日付など任意)
git tag safety/2025-10-23
中断・スキップ
git rebase --abort # リベース開始前に戻す
git rebase --skip # 今のコミットを飛ばす(慎重に)
ファイル単位のやり直し
# ステージ解除
git restore --staged <file>
# 変更の取り消し
git restore <file>
Pull 時の方針:merge か rebase か
どちらを既定にするかはチーム方針次第です。
迷うなら設定で明示して事故を減らしましょう。
# Pull は常に rebase(既定化)
git config --global pull.rebase true
# 可能なら fast-forward のみ(不可なら失敗)
git config --global pull.ff only
# merge の既定(可能なら ff / それ以外はマージコミット)
git config --global merge.ff true
# 「統合の事実」を必ず残したい運用では false も検討
よくある落とし穴
-
公開ブランチで
rebase:他メンバーのローカルと履歴が乖離して混乱。 -
push --forceの多用:最悪、他人のコミットを消す。必ず--force-with-leaseを使い、対象ブランチを明示。
使い分け指針(チェックリスト)
| シチュエーション | 推奨 | 理由/補足 |
|---|---|---|
| 共有ブランチに取り込む | merge --no-ff |
統合の事実が残り、監査性・再現性が高い |
| 個人作業を整えて PR |
rebase -i + --autosquash
|
レビュー単位に整理、 |
| Pull の既定統一 |
pull.rebase=true or pull.ff=only
|
方針を明示して事故を減らす |
| 衝突が連続する | 範囲を小さく・段階的に |
HEAD~n を刻む、rerere を有効化 |
付録:実務で使えるスニペット集
# 現在のブランチを main 最新に付け替え
git fetch origin && git rebase origin/main
# 競合後の必須コマンド(解消→個別 add→continue)
git add <resolved-files> && git rebase --continue
# 安全な強制プッシュ(ブランチ明示)
git push --force-with-lease origin feature/xyz
# 直近 10 コミットを整理(インタラクティブ + autosquash)
git rebase -i --autosquash HEAD~10
# PR をマージコミットで取り込む
git switch main && git merge --no-ff feature/xyz
# 失敗しても慌てない:過去位置へ戻す
git reflog && git reset --hard HEAD@{1}
まとめ
-
Merge:履歴を正しく残し、チームで安全に統合するのに向く。
--no-ffで監査性を確保。 - Rebase:個人作業の履歴整理や PR 前の整形に有効。ただし 公開ブランチでは原則禁止。SHA が変わる点を理解して使う。
-
コンフリクト解消と復旧手順(
rebase --continue/--abort/reflog/rerere)を押さえれば怖くない。
Discussion