DevToolBox無料
ブログ

Git Rebase vs Merge:いつ使うべきか

12分by DevToolBox

git rebasegit mergeの違いを理解することは、すべてのGit開発者にとって不可欠です。

Git Mergeの仕組み

Git mergeは2つの親コミットを持つ新しいマージコミットを作成します。

メインブランチでgit merge featureを実行すると、Gitは共通の祖先を見つけます。

Git Rebaseの仕組み

Git rebaseはブランチのコミットを別のブランチの先端に移動して履歴を書き換えます

フィーチャーブランチからgit rebase mainを実行すると、コミットが一つずつ再適用されます。

ビジュアル比較

BEFORE (both branches have diverged from common ancestor C2):

          C5---C6---C7  (feature)
         /
  C1---C2---C3---C4     (main)

AFTER git merge feature (from main):

          C5---C6---C7
         /            \
  C1---C2---C3---C4----M8  (main) ← merge commit M8 has 2 parents
                            (feature still points to C7)

AFTER git rebase main (from feature):

  C1---C2---C3---C4                     (main)
                   \
                    C5'---C6'---C7'     (feature) ← new commits (different SHAs)

  Then fast-forward merge:
  C1---C2---C3---C4---C5'---C6'---C7'  (main, feature) ← linear history

機能比較

項目git mergegit rebase
履歴すべての履歴を保持線形履歴
コミットSHA元のSHAを保持新しいSHAを作成
安全性非破壊的破壊的
コンフリクト解決マージコミットで一度に解決コミットごとに解決
チーム向け共有ブランチに安全共有ブランチに危険
取り消し簡単難しい
git bisectマージコミットでノイズクリーンな履歴で有効
グラフ表示複雑なグラフクリーンな一本線

Git Merge詳細

ファストフォワードマージ

ターゲットブランチに新しいコミットがない場合。

# Fast-forward merge (no merge commit created)
git checkout main
git merge feature

# Before:
# C1---C2 (main)
#        \
#         C3---C4 (feature)

# After:
# C1---C2---C3---C4 (main, feature)
# main pointer simply moved forward

3方向マージ

両方のブランチが分岐した場合。

# Three-way merge (creates merge commit)
git checkout main
git merge feature

# Before:
#        C3---C4 (feature)
#       /
# C1---C2---C5---C6 (main)

# After:
#        C3---C4
#       /       \
# C1---C2---C5---C6---M7 (main)  ← merge commit M7

--no-ff

ファストフォワードが可能でもマージコミットを強制。

# Force merge commit even when fast-forward is possible
git checkout main
git merge --no-ff feature

# Before:
# C1---C2 (main)
#        \
#         C3---C4 (feature)

# After (with --no-ff):
# C1---C2---------M5 (main)  ← merge commit preserves branch history
#        \       /
#         C3---C4 (feature)

# After (without --no-ff, default):
# C1---C2---C3---C4 (main, feature)  ← no evidence of branch

Git Rebase詳細

基本的なRebase

標準的なrebaseはコミットをターゲットブランチの上に再適用します。

# Basic rebase workflow
git checkout feature
git rebase main

# Before:
#        C3---C4 (feature)
#       /
# C1---C2---C5---C6 (main)

# After rebase:
#                     C3'---C4' (feature)  ← new commits!
#                    /
# C1---C2---C5---C6 (main)

# Then merge (fast-forward):
git checkout main
git merge feature
# C1---C2---C5---C6---C3'---C4' (main, feature)  ← linear!

インタラクティブRebase

コミットの変更、スカッシュ、並べ替え、削除が可能。

# Interactive rebase - clean up last 4 commits
git rebase -i HEAD~4

# Editor opens with:
pick abc1234 Add user model
pick def5678 Fix typo in user model
pick ghi9012 Add user validation
pick jkl3456 Fix validation edge case

# Change to:
pick abc1234 Add user model
fixup def5678 Fix typo in user model        # squash into previous, discard message
pick ghi9012 Add user validation
fixup jkl3456 Fix validation edge case      # squash into previous, discard message

# Result: 2 clean commits instead of 4
# "Add user model" (includes typo fix)
# "Add user validation" (includes edge case fix)

# Interactive rebase commands:
# pick   = use commit as-is
# reword = use commit but edit message
# edit   = use commit but stop for amending
# squash = meld into previous commit (keep message)
# fixup  = meld into previous commit (discard message)
# drop   = remove commit entirely

--onto Rebase

コミットのサブセットを別のベースにrebase。

# --onto: Move a branch to a different base
# Scenario: feature-b was branched from feature-a by mistake
#           You want feature-b based on main instead

#        D---E (feature-b)
#       /
# A---B---C (feature-a)
#     |
#     F---G (main)

git rebase --onto main feature-a feature-b

# Result:
#     D'---E' (feature-b)  ← now based on main
#    /
# A---B---C (feature-a)
#     |
#     F---G (main)

コンフリクト解決

mergeとrebaseの両方でコンフリクトが発生する可能性があります。

Mergeコンフリクト

すべてのコンフリクトが一度に表示されます。

# Merge conflict workflow
git checkout main
git merge feature
# CONFLICT (content): Merge conflict in src/app.ts
# Automatic merge failed; fix conflicts and then commit

# 1. Open conflicting files and resolve
# 2. Stage resolved files
git add src/app.ts
# 3. Complete the merge
git commit  # creates merge commit with conflict resolution

# Abort merge if needed
git merge --abort

Rebaseコンフリクト

コミットごとにコンフリクトが発生する可能性があります。

# Rebase conflict workflow
git checkout feature
git rebase main
# CONFLICT in commit C3: Merge conflict in src/app.ts

# 1. Resolve conflict in src/app.ts
git add src/app.ts
# 2. Continue rebase to next commit
git rebase --continue
# May hit another conflict in C4...

# CONFLICT in commit C4: Merge conflict in src/utils.ts
git add src/utils.ts
git rebase --continue

# Abort rebase if it gets too complex
git rebase --abort  # returns to pre-rebase state

# Skip a problematic commit during rebase
git rebase --skip

チームワークフロー

Mergeベースのワークフロー

最も一般的なチームワークフロー。

# GitHub Flow (merge-based)
git checkout -b feature/add-auth
# ... make commits ...
git push -u origin feature/add-auth
# Open PR on GitHub
# Review + approve
# Click "Merge pull request" (creates merge commit)
# Or "Squash and merge" (single commit)

Rebase後Mergeワークフロー

rebaseで更新してからmerge。

# Rebase-before-merge workflow
git checkout feature/add-auth
# ... make commits ...

# Before opening PR, update with latest main
git fetch origin
git rebase origin/main

# Force push (safe because it's your own branch)
git push --force-with-lease origin feature/add-auth

# Open PR on GitHub
# Merge with --no-ff to record integration point
git checkout main
git merge --no-ff feature/add-auth

Squash and Mergeワークフロー

すべてのコミットを1つにまとめます。

# Squash and merge (via GitHub UI or CLI)
git checkout main
git merge --squash feature/add-auth
git commit -m "feat: add authentication system"

# Before:
# main: A---B---C
# feature: A---B---D---E---F---G

# After squash-merge:
# main: A---B---C---H  ← H contains all changes from D+E+F+G
# (feature branch can be deleted)

Rebaseの黄金律

共有リモートブランチにプッシュ済みのコミットをrebaseしないでください。

# DANGEROUS: Rebasing a shared branch
git checkout shared-feature
git rebase main
git push --force  # !! This rewrites history for everyone!

# SAFE: Rebasing your own local branch
git checkout my-local-feature
git rebase main
# No push yet, or push --force-with-lease to your own branch

# SAFE: Using --force-with-lease instead of --force
git push --force-with-lease origin my-feature
# Fails if remote has commits you haven't seen

ベストプラクティス

Git Rebase vs Merge Best Practices:

1. Use merge for integrating feature branches into main
   - Creates clear integration points
   - Safe for shared branches
   - Easy to revert entire features

2. Use rebase to keep feature branches up-to-date
   - git rebase main (before opening PR)
   - Creates clean, linear history
   - Makes code review easier

3. Use interactive rebase to clean up before PR
   - Squash fixup commits
   - Reword unclear commit messages
   - Drop debugging commits

4. Use git pull --rebase as default
   - Avoids unnecessary merge commits
   - git config --global pull.rebase true

5. Never rebase shared/pushed commits
   - Only rebase your own unpushed work
   - Use --force-with-lease, never --force

6. Use squash-merge for feature branches
   - One clean commit per feature on main
   - Detailed commits preserved in PR history

7. Use --no-ff for important merges
   - Preserves the fact that a branch existed
   - Makes git log --first-parent useful

よくある質問

rebaseとmergeのどちらを使うべき?

ローカルブランチの更新にrebase、メインブランチへの統合にmergeを使用。

rebaseは危険?

共有ブランチでは危険。ローカルの未プッシュコミットには安全。

squash and mergeとは?

すべてのコミットを1つにまとめてマージ。

rebaseを取り消せる?

はい。git reflogを使用。

チームはrebaseとmergeのどちら?

ハイブリッドアプローチが最適。

git pull --rebaseとは?

マージコミットの代わりにrebaseで更新を取得。

関連ツールとガイド

𝕏 Twitterin LinkedIn
この記事は役に立ちましたか?

最新情報を受け取る

毎週の開発ヒントと新ツール情報。

スパムなし。いつでも解除可能。

Try These Related Tools

{ }JSON Formatter

Related Articles

Git Rebase vs Merge:どちらをいつ使うべきか(図解付き)

git rebase と merge の違いを理解する。使い分け方、よくある落とし穴の回避法を解説。

Git コマンドチートシート:開発者必須のコマンド一覧

包括的な Git コマンドチートシート:セットアップ、ブランチ、マージ、リベース、スタッシュ、高度なワークフロー。

Gitブランチ戦略:GitFlow vs トランクベース vs GitHub Flow

GitFlow、トランクベース開発、GitHub Flowのブランチ戦略を比較。ブランチ構造、マージワークフロー、CI/CD統合、チームに最適な戦略の選び方。