🎡

GitのMergeとRebaseの違いを徹底解説:安全な使い分けと実践コマンド集

に公開

はじめに

日々の開発で避けて通れないブランチ統合。Git には代表的な統合手段として MergeRebase があります。どちらも「あるブランチの変更を別のブランチへ取り込む」点は同じですが、履歴構造チーム運用 への影響が大きく異なります。

本記事では、概念の違いに加えて、実務でそのまま使えるコマンド例コンフリクト解消の流れ失敗時の復旧などを解説します。


ざっくり結論

  • 共有ブランチ(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) ローカルの履歴を整理したい

目的: fixupsquash でコミットをまとめ、レビュー単位に整える。

# 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

コンフリクト解消の実践フロー

  1. リベース中のコンフリクト発生(CONFLICT 表示)
  2. 該当ファイルを開き、<<<<<<, ======, >>>>>> を解消
  3. ビルド/テストを回して確認(例: pnpm test / go test ./... / bundle exec rspec
  4. 解消済みファイルのみ git add <file>
  5. 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 時の方針:mergerebase

どちらを既定にするかはチーム方針次第です。
迷うなら設定で明示して事故を減らしましょう。

# 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