Skip to content

Gitのpull設定:merge/rebaseとfast-forwardの違い

主要なポイント

  • pull.rebasepull.ffは異なる動作を制御する設定
  • pull.ffはマージ時のfast-forward動作を制御
  • pull.rebaseはプル操作全体をマージかリベースか決定
  • 互いに影響し合い、特定の組み合わせでは一方が無視される

問題の本質

Gitでgit pullを実行する際、「変更をどのように統合するか」という設定にはpull.rebasepull.ffの2種類があります。どちらも「可能な場合はfast-forwardする」という挙動を示すため、以下の設定の違いが分かりにくくなっています。

sh
git config pull.rebase false   # デフォルトのマージ戦略
git config pull.ff true        # fast-forwardを許可

この記事では、両設定の技術的な違い実践的な使い分けを明確に解説します。

基本概念の理解

Fast-forwardマージとは

図のようにローカルブランチがリモートブランチの直接の子である場合、ブランチポインタを単純に前に進める(fast-forward)ことで統合可能です。

mergeとrebaseの違い

  • merge:新しいマージコミットを作成して変更を統合
  • rebase:ローカルのコミットをリモート変更の上に「再適用」

pull.ff設定の詳細

pull.ffはマージ操作時のfast-forward動作を制御します。

sh
git config pull.ff true    # fast-forward可能な場合は実行(デフォルト)
git config pull.ff false   # 常にマージコミットを作成
git config pull.ff only    # fast-forward可能な場合のみ実行
sh
# fast-forward可能な場合
$ git pull
Updating abc123..def456
Fast-forward

# fast-forward不可能な場合
$ git pull
fatal: 不可能なfast-forwardです。作業を中止します

pull.rebase設定の詳細

pull.rebaseはプル操作全体をマージリベースのどちらで処理するかを決定します。

sh
git config pull.rebase false       # マージを実行(デフォルト)
git config pull.rebase true        # 通常のリベースを実行
git config pull.rebase merges      # マージコミットを保持しながらリベース
git config pull.rebase interactive # インタラクティブリベース
sh
$ git pull
リモート:  Counting objects: 5, done.
ローカルのコミットを基底 'origin/main' の上にリベース...

両設定の相互作用

重要な相互作用

  • pull.rebase = trueのとき:
    pull.ffの設定は完全に無視されます。リベースが行われるため、マージ関連の設定は不要です。

  • pull.ff = onlyのとき:
    fast-forward不可能な場合、プル操作自体が中止されるため、pull.rebaseの設定は適用されません。

設定優先順位のフロー

ベストプラクティスと推奨設定

ケース別推奨設定

ワークフロー推奨設定理由
個人開発pull.rebase = trueコミット履歴を直線的に保てる
チーム(マージ)pull.ff = onlyマージコミットを明示的に作成
リリースブランチpull.rebase = false
pull.ff = false
全ての統合をマージコミットとして記録

安全な代替操作

多くのエキスパートはgit pullの代わりに以下の手順を推奨します:

sh
# 1. リモート変更を取得(統合はしない)
git fetch origin

# 2. 変更内容を確認(オプション)
git log --oneline --graph HEAD..origin/main

# 3a. リベースで統合
git rebase origin/main

# または 3b. マージで統合
git merge origin/main

この方法では変更内容を確認してから統合方法を選択可能で、安全に操作できます。

エキスパートのワークフロー例

sh
# 安全に更新できるブランチ用エイリアス
git config --global alias.safe-pull '!git pull --ff-only'

# 機能ブランチでの更新
git checkout my-feature
git safe-pull  # fast-forwardのみ実行

# マージが必要な場合
git fetch
git rebase origin/main

結論

  • pull.rebasepull.ffは補完的ではなく競合する設定
    リベース設定が優先されるケースがある
  • チームポリシーに合わせて設定を統一
    プロジェクトで一貫した設定を使用
  • 安全策としてgit fetch + 手動操作を検討
    特に複雑な状況では直接的な操作が確実

最終的には、git pullの適切な設定は「プロジェクトのワークフロー」と「コミット履歴の好み」によって決定されます。設定変更後は必ず各動作をテストし、期待通りの挙動を確認してください。