TL;DR
Gitは、ローカルの変更が取り込むコミットと同じファイルに触れているため、プルを拒否しています。解決方法は3つあります:
# オプション A — 変更をスタッシュして、プルしてから復元する
git stash
git pull
git stash pop
# オプション B — 変更を完全に破棄する
git checkout -- path/to/file
git pull
# オプション C — 先にコミットしてからプルする
git add path/to/file
git commit -m "WIP: save local changes"
git pull
何が起きているのか
git pull を実行すると、内部でマージが発生します。Gitはリモートブランチとローカルブランチを比較し、ローカルで編集したファイルが取り込むコミットでも変更されていた場合、Gitは即座に停止します:
error: Your local changes to the following files would be overwritten by merge:
src/config.js
README.md
Please commit your changes or stash them before you merge.
Aborting
これは意図的な動作です。Gitはあなたの作業を勝手に消去しません。あなたの編集内容はワーキングツリー(またはステージ済みの場合はインデックス)に存在しますが、まだコミットされていないため、マージ中に安全に保存する場所がありません。
修正方法
オプション A: スタッシュ(推奨 — 変更を保持する)
プル後にローカルの編集内容を復元したい場合に最適な選択肢です。たとえば、デバッグログやまだコミットする準備ができていないローカルのAPIキーがある場合などに使います。
# 1. 追跡済みの変更ファイルをすべてスタッシュする
git stash
# 2. 最新の変更をプルする
git pull
# 3. スタッシュした変更を再適用する
git stash pop
stash pop でコンフリクトが発生した場合、Gitは衝突した行を <<<<<<< マーカーで示します。手動で修正してから次を実行します:
git add src/config.js
git stash drop # 解決後にスタッシュエントリを削除する
意味のあるラベルを付けて特定のファイルだけをスタッシュしたい場合は次を使います:
git stash push -m "WIP: local config tweaks" src/config.js
現在スタッシュされている内容はいつでも git stash list で確認できます。
オプション B: ローカルの変更を破棄する(破壊的 — 変更は消えます)
ローカルの編集内容が本当に不要な場合にのみ使用してください。たとえば、調査中に誤ってファイルを変更してしまった場合などです。
# 特定のファイルの変更を破棄する
git checkout -- src/config.js README.md
# またはワーキングツリー内の未コミットの変更をすべて削除する
git restore .
# その後、通常通りプルする
git pull
警告: git checkout -- <file> と git restore はどちらも未コミットの変更に対して永続的です。元に戻すことはできませんし、ごみ箱にも入りません。
オプション C: 先に変更をコミットする
編集内容が履歴に残すべき実際の作業である場合は、プルする前にコミットしましょう。
git add src/config.js README.md
git commit -m "Update config and docs"
git pull
あなたとチームメンバーが同じ行を編集していた場合、プルでマージコンフリクトが発生することがあります。その場合はGitが一時停止し、通常のコンフリクト解決フローを案内してくれます。
オプション D: 強制プル(核オプション — すべてを上書きする)
使い捨てのブランチや、リモートのバージョンを完全に使いたいと確信している場合にのみ使用してください。
git fetch origin
git reset --hard origin/main
これはブランチをリモートと完全に一致するようにハードリセットします。未コミットの変更は消えます。ローカルで作成したがプッシュしていないコミットも消えます。慎重に使用してください。
どのオプションを使うべきか
ローカルの変更に対して何をしたいかに基づいて選択してください:
- スタッシュ — プル後に変更を戻したい場合(一時的なデバッグログ、ローカル環境の調整、実験的な変更など)。
- 破棄 — 変更が偶発的または不要なもので、失っても構わない場合。
- コミット — プロジェクトの履歴に残すべき実際の作業の場合。
- reset --hard — ローカルブランチが混乱しており、リモートと同じ状態にしたい場合。
プル後にスタッシュポップでコンフリクトが発生した場合
プルで取り込んだ変更がスタッシュの内容と全く同じ行に当たることがあります。Gitはすぐに通知します:
$ git stash pop
Auto-merging src/config.js
CONFLICT (content): Merge conflict in src/config.js
The stash entry is kept in case you need it again.
src/config.js を開いて <<<<<<< マーカーを見つけ、正しいバージョンを選択します。その後、後処理を行います:
git add src/config.js
git stash drop # 完全に解決したらスタッシュエントリを削除する
確認
修正を適用した後、すべてが正しく反映されていることを確認します:
# ブランチが最新であることを確認する
git status
# リモートの最新コミットがローカルの履歴に反映されているか確認する
git log --oneline -5
# stash pop を使用した場合、変更が戻ってきているか確認する
git diff HEAD
「Your branch is up to date with 'origin/main'」 と表示されたクリーンな git status が確認できれば、問題ありません。
再発防止策
- 小さく頻繁にコミットする。 頻繁に小さなコミットを行っているブランチは、このエラーにほとんど遭遇しません。
git pull --rebaseを試す。 マージではなく、リモートの上にコミットを再適用します。線形な履歴には整理されたアプローチです。クリーンなワーキングツリーが必要ですが、結果はより整然とします。- スタッシュ→プル→ポップの一連の操作にエイリアスを追加する:
git config --global alias.sync '!git stash && git pull && git stash pop'。これでgit sync一つで完結します。

