【Git】コンフリクトしてpullできないときの対処法完全ガイド|stash・commit・reset・コンフリクト解消まで

【Git】コンフリクトしてpullできないときの対処法 Git

Git で git pull を実行したとき、「Please commit your changes or stash them before you merge」というエラーが出て pull できないことがあります。これはローカルに未コミットの変更がある状態で pull しようとしたときに発生します。

この記事では、エラーの原因と 3つの対処方法(commit・stash・reset)を解説し、pull 後にコンフリクトが発生した場合の解消手順まで説明します。

この記事でわかること

  • 「Please commit your changes before you merge」エラーの原因
  • 対処法1: 変更をコミットしてから pull する
  • 対処法2: git stash で一時退避してから pull する
  • 対処法3: git reset –hard で変更を破棄してから pull する
  • pull 後にコンフリクトが発生した場合の解消手順
  • git merge –abort でマージを取り消す方法
スポンサーリンク

エラーの原因

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

git pull は内部的に fetch(リモートの変更を取得)+ merge(現在のブランチにマージ) の2ステップで動作します。ローカルに未コミットの変更があると、マージ時に上書きが発生する可能性があるため、Git が pull を拒否します。

状況の確認

# まず現在の状況を確認
git status

# 出力例
# Changes not staged for commit:
#   modified:   src/main.js
#   modified:   src/app.css

git status で未コミットの変更ファイルが確認できます。これらのファイルがある状態では pull できません。

対処法1:変更をコミットしてから pull する

変更内容が作業途中で保存したい場合は、コミットしてから pull します。

# ① 変更をステージング
git add .

# ② コミット(作業途中のコミットにはメッセージで明示)
git commit -m "WIP: 作業中の変更を保存"

# ③ pull を実行
git pull

# pull 後にコミットが2つになるため、必要に応じて rebase
# git pull --rebase origin main
pull –rebase で履歴をきれいに保つ
git pull --rebase を使うと、自分のコミットをリモートの変更の「上」に積み直します。不要なマージコミットが作られず、履歴がきれいになります。

対処法2:git stash で一時退避してから pull する(推奨)

変更をまだコミットしたくない場合は git stash で一時退避してから pull します。pull 後に git stash pop で変更を戻せます。

# ① 変更を一時退避
git stash
# → Saved working directory and index state WIP on main: a1b2c3d ...

# ② pull を実行
git pull

# ③ 退避した変更を戻す
git stash pop
# → 変更が戻り、コンフリクトがなければ完了
# stash の一覧を確認
git stash list
# stash@{0}: WIP on main: a1b2c3d ...

# 特定の stash だけを適用
git stash apply stash@{0}

# stash を削除
git stash drop stash@{0}
git stash pop でコンフリクトが発生することがある
git pull 後に git stash pop したとき、リモートの変更とスタッシュの変更が同じ箇所を修正していた場合、コンフリクトが発生します。その場合は後述の「コンフリクトの解消手順」で解決してください。

対処法3:git reset –hard で変更を破棄してから pull する

ローカルの変更が不要な場合(ファイルを元の状態に戻したい場合)は、git reset --hard で変更を破棄してから pull します。

# ⚠ 未コミットの変更がすべて消える(元に戻せない)
git reset --hard

# ② pull を実行
git pull
git reset –hard は元に戻せない
git reset --hard を実行すると、未コミットの変更がすべて消えます。コミットしていない作業内容は復元できません。本当に不要な変更のみに使ってください。迷ったら git stash で退避する方が安全です。

pull 後にコンフリクトが発生した場合の解消手順

上記の対処をして pull を実行しても、リモートとローカルの変更が同じ箇所を変更していた場合は コンフリクト(競合) が発生します。

Auto-merging src/main.js
CONFLICT (content): Merge conflict in src/main.js
Automatic merge failed; fix conflicts and then commit the result.

ステップ1:コンフリクトしているファイルを確認する

# コンフリクトしているファイルの確認
git status

# Unmerged paths: の箇所にコンフリクトしたファイルが表示される
# both modified:   src/main.js

ステップ2:コンフリクトマーカーを読んで手動解決する

コンフリクトが発生したファイルを開くと、以下のようなコンフリクトマーカーが表示されます。

<<<<<<< HEAD
// ローカルの変更(現在のブランチの内容)
const greeting = "Hello";
=======
// リモートの変更(マージしようとしたブランチの内容)
const greeting = "Hi";
>>>>>>> origin/main

マーカーの意味を理解して、正しいコードに書き直してください。

マーカー 意味
<<<<<<< HEAD ここから下が現在のブランチ(自分のローカル)の変更
======= 区切り線
>>>>>>> origin/main ここまでがリモートブランチの変更

ステップ3:解決後に add して commit する

# ① コンフリクトを手動で解決してファイルを保存

# ② 解決済みとしてステージング
git add src/main.js

# ③ 全てのコンフリクトが解決できたか確認
git status

# ④ マージを完了させるコミット
git commit -m "Merge: コンフリクトを解決"

マージを取り消して元に戻す(git merge –abort)

コンフリクトの解決が難しい場合や、pull 自体をやり直したい場合は git merge --abort でマージ前の状態に戻せます。

# マージ中の状態を確認
git status
# → You have unmerged paths.

# マージを取り消して元に戻す
git merge --abort

# pull --rebase を使った場合は --abort 方法が異なる
git rebase --abort

よくある質問

Q. git stash したファイルはどうなりますか?
A. スタッシュした変更はローカルに保存され、git stash list で確認できます。git stash pop でスタッシュを戻せます。ブランチを切り替えてから git stash pop することも可能なので、一時退避として非常に便利です。
Q. git stash pop でもコンフリクトが発生しました。
A. git stash pop でコンフリクトが発生した場合、スタッシュはまだ削除されていません(git stash apply と同じ動作になります)。通常のマージコンフリクトと同様に手動で解決し、git addgit stash drop で完了させてください。
Q. コンフリクトを VSCode や IDE で解決できますか?
A. はい、VSCode では「ソース管理」パネルからコンフリクトファイルを開き、「現在の変更を使用」「着信した変更を使用」「両方を使用」から選択できます。GitHub Desktop も同様のUI操作に対応しています。ターミナルで直接編集するより直感的に解決できます。
Q. 毎回コンフリクトが起きるのを防ぐ方法はありますか?
A. こまめに git pull(または git fetch + git rebase)してリモートの変更を取り込む習慣をつけることが最も効果的です。また、同じファイルを複数人が同時に編集しないようにタスク管理を工夫する、ファイルを小さく分割して変更範囲を限定するなどの設計面での対策も有効です。
Q. git pull –rebase と git pull の違いは何ですか?
A. git pull(デフォルト)はマージコミットを作ります。git pull --rebase は自分のコミットをリモートの変更の「上」に積み直すため、余分なマージコミットが作られず、履歴がきれいになります。チームのルールに従って使い分けてください。

まとめ

pull できないときの対処フロー

  • まず git status で未コミットの変更を確認
  • 変更を保存したい → git stash で退避 → git pullgit stash pop
  • 変更をコミットしたい → git add . && git commitgit pull
  • 変更を捨てていい → git reset --hardgit pull
  • pull 後コンフリクト → ファイル編集で解決 → git addgit commit
  • 解決を中止したい → git merge --abort でやり直し

あわせて読みたい