タイトル: リモートとローカルのリポジトリを同期(pull)する方法
SEOタイトル: git pull でローカルをリモートに同期する方法と注意点(fetch + merge の違いまで)
| この記事の要点 |
|
基本: git pull コマンド
リモートリポジトリの最新変更をローカルブランチに取り込む基本コマンド:
# リモート (origin) の main ブランチをローカル main にマージ
git pull origin main
# upstream が設定済なら省略可
git pull
# rebase で取り込む(マージコミット作らない)
git pull --rebase
# fast-forward only(マージできなければエラー)
git pull --ff-only
git pull の中身: fetch + merge
git pull は実は 2 つのコマンドの組み合わせです:
# git pull origin main は内部的に以下と同じ
git fetch origin main # リモート最新を取得(ローカルブランチには反映しない)
git merge origin/main # 取得した内容を現在のブランチにマージ
# --rebase オプションの場合
git fetch origin main
git rebase origin/main
動作の違い:
| コマンド | 動作 | ローカル変更 |
|---|---|---|
git fetch | リモート最新を取得のみ | 影響なし(安全) |
git pull | fetch + merge | 現在のブランチに自動マージ |
git pull --rebase | fetch + rebase | ローカルコミットをリモートの上に積み直す |
典型的な作業フロー
# 1. 作業前にリモート最新を取り込む
git checkout main
git pull origin main
# 2. ブランチを切って作業
git checkout -b feature/new-login
# ... 編集・コミット ...
git add .
git commit -m "Add login feature"
# 3. push 前にリモート最新を取り込む(コンフリクト早期検知)
git pull --rebase origin main
# 4. push
git push origin feature/new-login
未コミット変更があるときの pull
ローカルに未コミット変更があり、リモート最新が同じファイルを変更している場合 → pull できません:
error: Your local changes to the following files would be overwritten by merge:
src/Login.php
Please commit your changes or stash them before you merge.
Aborting
対処2 通り:
# 方法 A: stash で一時退避
git stash # 変更を退避
git pull origin main # pull
git stash pop # 退避を戻す(コンフリクト出る可能性あり)
# 方法 B: 先にコミット
git add .
git commit -m "WIP: 作業中"
git pull --rebase origin main # rebase で履歴を直線化
コンフリクトが出たとき
同じファイルの同じ行を両者が変更していた場合、Git は自動マージできずコンフリクトになります:
Auto-merging src/Login.php
CONFLICT (content): Merge conflict in src/Login.php
Automatic merge failed; fix conflicts and then commit the result.
該当ファイルを開くと:
<<<<<<< HEAD
$user = User::find($id); // ← ローカルの変更
=======
$user = User::findOrFail($id); // ← リモートの変更
>>>>>>> origin/main
解決手順:
# 1. ファイルを編集してマーカーを削除
# どちらか or 両方を残す形に修正
# 2. 解決済としてマーク
git add src/Login.php
# 3. マージコミット作成(merge の場合)
git commit
# rebase 中の場合
git rebase --continue
# rebase をやめたい場合
git rebase --abort
# merge をやめたい場合
git merge --abort
pull の代わりに fetch + merge を分けて実行
慣れてくるとpull せずに fetch + mergeを分けて実行する方が安全と気付きます:
# 1. リモートを取得(ローカルブランチには影響なし)
git fetch origin
# 2. 差分を確認
git log HEAD..origin/main --oneline
git diff HEAD origin/main
# 3. 安全と判断したらマージ
git merge origin/main
# または rebase
git rebase origin/main
よくあるトラブル
| 症状 | 原因 | 対処 |
|---|---|---|
fatal: refusing to merge unrelated histories | 履歴が無関係のリポジトリ | git pull --allow-unrelated-histories |
error: pathspec 'main' did not match | リモートに main ブランチが無い(master の可能性) | git pull origin master |
| 毎回マージコミットが増える | pull がデフォルト merge | git config --global pull.rebase true |
Your branch is ahead of 'origin/main' by N commits | push 忘れ | git push |
FAQ
Q: pull と fetch、どちらを使うべき?
A: 初心者は pull、慣れたら fetch + merge を分けると安全です。チームで運用するなら pull --rebase を推奨。
Q: pull で勝手にマージコミットができるのを防ぎたい
A: git config --global pull.rebase true で常に rebase 動作。または git config --global pull.ff only で fast-forward only。
Q: 強制的にリモートと同じ状態にしたい(ローカル変更全捨て)
A: git fetch origin && git reset --hard origin/main。未コミット変更は消えるので注意。