'git stash pop'が'Your local changes would be overwritten by merge'で失敗する問題を修正する

intermediate📦 Git2026-06-02| Git 2.x(Linux、macOS、Windows — Gitがインストールされている任意のOS)

Error Message

error: Your local changes to the following files would be overwritten by merge: src/main.py Please commit your changes or stash them before you merge. Aborting
#git#stash#stash-pop#マージコンフリクト#作業ツリー

何が起きたのか

作業をスタッシュして別の作業をした後、git stash pop を実行したら、こんなエラーが出た:

error: Your local changes to the following files would be overwritten by merge:
        src/main.py
Please commit your changes or stash them before you merge.
Aborting

スタッシュは適用されなかった。しかし何も失われていない — スタッシュはまだスタックに残っている。src/main.py にコミットされていない変更がすでに存在するため、スタッシュを適用するとそれらが上書きされてしまう。だから Git は処理を中断した。

Git が中断する理由

git stash pop を実行すると、スタッシュされた差分をワーキングツリーにマージしようとする。ファイルにすでにコミットされていない編集がある場合、Git はその上にスタッシュを安全に適用する方法がない — そのままでは作業中の内容がサイレントに消えてしまう。だから早めに処理を中止する。

このエラーが起きる最もよくあるパターン:

  • src/main.py の変更をスタッシュする。
  • 別のブランチに切り替えてちょっとした修正をして、また戻る。
  • あるいは — これがよくある — スタッシュの存在を忘れて src/main.py をまた編集し始める。
  • git stash pop を実行する。エラーが起きる。

まず今の状況を正確に把握しよう:

# スタッシュが触れているファイルを確認する
git stash show

# 現在コミットされていないものを確認する
git status
git diff src/main.py

修正方法 1 — 現在の変更を先にコミットまたはスタッシュする(推奨)

pop の前にワーキングツリーをきれいにする。2つの方法がある:

# オプション A: 今の変更をコミットする
git add src/main.py
git commit -m "WIP: current changes before stash pop"
git stash pop

# オプション B: 今の変更をその上にスタッシュする
git stash          # 現在の変更を stash@{0} として保存する
git stash pop stash@{1}  # 元のスタッシュを取り出す(インデックスが1にシフトされている)
# 競合があれば解決して、次に:
git stash pop      # 先ほど作成した WIP スタッシュを取り出す

オプション B はすべてをスタッシュスタックに保持する。最初の pop の後にマージ競合が発生することがある — それは正常だ。Git は競合箇所に <<<<<<< マーカーを付けるので、手動で解決できる。

修正方法 2 — 現在のワーキングツリーの変更を破棄する

ブロックしている変更が保存する価値のないものの場合もある — 途中で止まった実験、デバッグ用のprint文など。思い切って捨てよう:

# 特定のファイルへの変更を破棄する
git checkout -- src/main.py

# その後リトライする
git stash pop

コミットされていないすべての変更を消したい場合:

git restore .   # Git 2.23以降
# または
git checkout -- .

**警告:**この操作は元に戻せない。破棄されたワーキングツリーの変更は消えてしまう — Git にはゴミ箱がない。いずれかのコマンドを実行する前に git diff で必ず確認すること。

修正方法 3 — git apply で3ウェイマージを強制する

両方の変更が重要なのに git stash pop が中断し続ける場合、スタッシュをパッチとしてエクスポートして Git 自身にマージを試みさせよう:

git stash show -p | git apply --3way

競合で中断する代わりに、--3way を使うと Git は最善を尽くして処理し、自動解決できなかったファイルに競合マーカー(<<<<<<< / >>>>>>>)を残す。それを手動で修正する。

# 対応が必要なファイルを確認する
git status

# src/main.py を編集して競合マーカーを解決し、次に:
git add src/main.py

# スタッシュエントリを削除する — 手動で適用済みのため
git stash drop

修正方法 4 — スタッシュを削除せずに適用する

適用がうまくいくか不安な場合は、pop の代わりに git stash apply を使おう:

# 削除せずに適用する(スタッシュはスタックに残る)
git stash apply

# 競合を解決してから、スタッシュを手動で削除する
git stash drop

pop との唯一の違い:明示的に削除するまでスタッシュエントリが残る。何かおかしくなっても、スタッシュがセーフティネットとして残っている。結果に完全な自信がないときの無難な選択だ。

確認

次に進む前に簡単なサニティチェックをしよう:

# スタッシュスタックが空(またはエントリが1つ減っている)であることを確認する
git stash list

# ワーキングツリーが想定した変更だけを示していることを確認する
git diff HEAD

# 競合マーカーが残っていないことを確認する
grep -r '<<<<<<<' src/

git stash list が空で git status もきれいな状態?完了だ。

次回から防ぐには

これを完全になくすためのいくつかの習慣:

  • **git stash pop の前に git status を実行する。**30秒の確認で、競合の解消に費やす10分を節約できる。
  • **どのスタッシュを取り出すか明示する。**スタックに複数のエントリがある場合、Git に任せるより git stash pop stash@{1} と指定する方がはるかに安全だ。
  • **数分以上の作業にスタッシュを頼らない。**1時間や1日かかるコンテキストの切り替えには、一時ブランチへの WIP コミットの方がずっと信頼できる。
  • スタッシュに名前をつける。git stash push -m "refactor: before adding auth layer" は5秒余分にかかるが、git stash list が格段に読みやすくなる。

Related Error Notes