Gitのpull設定:merge/rebaseとfast-forwardの違い
主要なポイント
pull.rebase
とpull.ff
は異なる動作を制御する設定pull.ff
はマージ時のfast-forward動作を制御pull.rebase
はプル操作全体をマージかリベースか決定- 互いに影響し合い、特定の組み合わせでは一方が無視される
問題の本質
Gitでgit pull
を実行する際、「変更をどのように統合するか」という設定にはpull.rebase
とpull.ff
の2種類があります。どちらも「可能な場合はfast-forwardする」という挙動を示すため、以下の設定の違いが分かりにくくなっています。
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動作を制御します。
git config pull.ff true # fast-forward可能な場合は実行(デフォルト)
git config pull.ff false # 常にマージコミットを作成
git config pull.ff only # fast-forward可能な場合のみ実行
# fast-forward可能な場合
$ git pull
Updating abc123..def456
Fast-forward
# fast-forward不可能な場合
$ git pull
fatal: 不可能なfast-forwardです。作業を中止します
pull.rebase設定の詳細
pull.rebase
はプル操作全体をマージかリベースのどちらで処理するかを決定します。
git config pull.rebase false # マージを実行(デフォルト)
git config pull.rebase true # 通常のリベースを実行
git config pull.rebase merges # マージコミットを保持しながらリベース
git config pull.rebase interactive # インタラクティブリベース
$ 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
の代わりに以下の手順を推奨します:
# 1. リモート変更を取得(統合はしない)
git fetch origin
# 2. 変更内容を確認(オプション)
git log --oneline --graph HEAD..origin/main
# 3a. リベースで統合
git rebase origin/main
# または 3b. マージで統合
git merge origin/main
この方法では変更内容を確認してから統合方法を選択可能で、安全に操作できます。
エキスパートのワークフロー例
# 安全に更新できるブランチ用エイリアス
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.rebase
とpull.ff
は補完的ではなく競合する設定
リベース設定が優先されるケースがある- チームポリシーに合わせて設定を統一
プロジェクトで一貫した設定を使用 - 安全策として
git fetch + 手動操作
を検討
特に複雑な状況では直接的な操作が確実
最終的には、git pull
の適切な設定は「プロジェクトのワークフロー」と「コミット履歴の好み」によって決定されます。設定変更後は必ず各動作をテストし、期待通りの挙動を確認してください。