git pullを実行すると次のようなエラーが出て止まることがあります。
error: Pulling is not possible because you have unmerged files. hint: Fix them up in the work tree, and then use 'git add/rm <file>' hint: as appropriate to mark resolution and make a commit. fatal: Exiting because of an unresolved conflict.
このエラーは一見すると「pullできない」と読めますが、実際はマージ操作がすでに進行中で、コンフリクトが未解決のままという状態を伝えています。単にgit commitやgit stashで解消しようとしても先に進めない、特別な解決が必要なエラーです。
この記事では「unmerged files」エラーの正しい意味と、2つの解決ルート(解消して完了/丸ごとabort)を順に解説します。Gitの3層構造(作業ツリー・index・HEAD)で何が起きているかを理解すれば、ヒントに従って安全に脱出できます。
この記事で学べること
- 「unmerged files」エラーが出るときにGitが抱えている状態
git statusでunmerged pathを確認する方法- 解決ルート①:コンフリクトを解消して進める手順
- 解決ルート②:マージ(または rebase/cherry-pick)をabortする手順
- なぜ
git commitやgit stashだけでは解決しないのか - pull後の二次エラー(non-fast-forward/conflict再発)への対処
- 同じエラーを出さないための予防運用(pull –rebase/小さいPR等)
エラーの正体:マージ途中でコンフリクトが未解決
このエラーは「既にマージ/rebase/cherry-pickが走り始めて、コンフリクトが起きたが、まだ解決されていない」状態でgit pullしようとしたときに出ます。Gitは「未解決の戦場を残したまま新しい操作を始められない」として、先の操作を進める前に今の状態を片付けるよう求めています。
ポイント:このエラーは「ローカルに未コミット変更がある」ケースとは別物です。「Please commit your changes or stash them before you merge」エラーは未コミット変更が原因ですが、本エラーはコンフリクト解決の途中で放置されている状態。対処法もコマンドも違うので、混同しないよう注意してください。未コミット変更のケースはコンフリクトしてpullできないときの対処法を参照。
誤情報に注意:「git commitまたはgit stashで解消する」というアドバイスはこのエラーには当てはまりません。git commitはunmerged entryが残っていれば拒否され、git stashもunmerged filesでは原則通用しません。正しい対処は以下のセクションで解説します。
STEP 0:状況を診断する
まず何が進行中なのか、どのファイルが未解決なのかを確認します。git statusのメッセージがほぼ答えを教えてくれます。
# まず何が進行中か確認 git status # 典型的な出力例 # On branch main # You have unmerged paths. # (fix conflicts and run "git commit") # (use "git merge --abort" to abort the merge) # # Unmerged paths: # (use "git add <file>..." to mark resolution) # both modified: src/auth.py # both added: src/utils.py
何のオペレーション中か見極める
Gitが表示するヒントを読む
- 「
use "git merge --abort"」→ マージ進行中 - 「
use "git rebase --abort"」→ rebase進行中 - 「
use "git cherry-pick --abort"」→ cherry-pick進行中 - unmerged paths 配下の「both modified:」「both added:」「deleted by us:」等が競合の種類
.git/MERGE_HEAD・.git/REBASE_HEAD等の有無でも判別可
# unmerged なファイルだけをリストアップ git diff --name-only --diff-filter=U # ステージ状態の詳細(0=通常、1=base、2=ours、3=theirs) git ls-files -u # ファイル内のコンフリクトマーカーを全ファイル検索 git grep -n "<<<<<<< "
解決ルート①:コンフリクトを解消して進める
コンフリクト解消の変更を取り込みたい場合の王道ルートです。該当ファイルを手動で修正してから、ステージ→コミット(完了)の順で進めます。
# STEP 1: 対象ファイルを開いてコンフリクトマーカーを解消 # <<<<<<< HEAD # 自分の変更 # ======= # 取り込みたい変更 # >>>>>>> origin/main # → 必要な状態に手動で編集 # STEP 2: 解決マークを付ける git add src/auth.py # 必要に応じて複数ファイル git add src/utils.py # STEP 3: マージコミットを完成させる git commit # → エディタが開くので、自動生成されたマージメッセージを確認して保存 # STEP 4: 改めて最新を取得 git pull # STEP 5: push git push
rebase / cherry-pick 中の場合
# コンフリクトファイル修正後 git add <修正したファイル> # rebaseの場合(--continue で次のコミットへ) git rebase --continue # cherry-pick の場合 git cherry-pick --continue # 続くコミットでまたコンフリクトが起きたら、同じ手順を繰り返し
解決の手助けになるコマンド
git mergetool:GUI/3-way merge ツールを起動git checkout --ours/--theirs <file>:どちらかを採用して即解決git diff --ours/--theirs/--base:3者のどれかを確認git show :1:<file> / :2:<file> / :3:<file>:base/ours/theirs を表示
解決後のpullで別エラーが出る場合はコンフリクトを解消したのにpullできないときの原因と対策を参照してください。
解決ルート②:進行中の操作をabortする
「よく分からなくなった」「そもそも取り込みを間違えた」場合は、進行中のオペレーションをabortしてpull前の状態に戻せます。安全に「なかったこと」にできる強力な脱出手段です。
# マージ中だった場合 git merge --abort # rebase中だった場合 git rebase --abort # cherry-pick中だった場合 git cherry-pick --abort # revert中だった場合 git revert --abort # どれか分からないときは status でヒントを確認 git status
ポイント:abortは進行中オペレーション開始前の状態に戻します。コミット済みの作業は消えず、作業ツリーも元通り。慌てずに「一旦戻して計画立て直し」ができるので、迷ったらabortしてから動き直すのが安全です。
abort後の再開
# abort で状態が戻ったら改めてpull git pull # ローカル変更があって pull が断られたら一度stashで退避 git stash push -m "before-pull" git pull git stash pop # rebase派なら git pull --rebase
pullの選択肢(merge vs rebase)を整理するにはリモートとローカルの履歴が食い違ったときの同期方法を参照してください。
なぜ「commit / stash で解決」は効かないのか
「未コミット変更があるときにpullで出るエラー」と混同したアドバイスが広まっていますが、本エラーには通用しません。理由を整理しておきます。
commit が通らない理由
git commitはindexにunmergedエントリがあるとコミットできない- 「
U ファイル名」エントリが残っている限りコミット失敗する - 解決するには先に
git addでunmerged → staged に移すか、abortする必要がある
stash が使えない理由
git stash pushはunmerged状態のファイルをstashできない- 「
Cannot save the current index state」のようなエラーで失敗 - マージ途中の状態をstashに退避できないのは仕様
- abort→stash→pull→stash popという順序なら可能
誤ったアドバイスの例:「git add -A && git commit -m …」で進める方法を示す記事もありますが、これはコンフリクトマーカーが残ったままコミットされる危険があります。エディタで<<<<<<<等を消してからaddする/手動で内容を整える、の手順を省略してはいけません。
同じエラーを出さないための予防策
日常運用のコツ
- 小さいブランチ・短いPR:大規模ブランチほどコンフリクトが増える
- 頻繁に本線を取り込む:
git fetch+git rebase origin/mainを習慣化 - pullは rebase派に寄せる:
git config --global pull.rebase trueでマージコミットを増やさない - 作業前に現在のブランチ状態を確認:
git statusとgit branch -vvを習慣化 - エディタのconflict表示を活用:VS Code等はマーカーをハイライトし、accept系ボタンで即解決可
- フォーマッタ・linterを揃える:スタイル差分が減ればコンフリクトも減る
実践シナリオ
シナリオ① pullでconflict、途中で作業を中断していた
git status # → "You have unmerged paths." 表示 # 該当ファイルを開いて conflict マーカーを解消 # VS Codeなら Accept Current / Accept Incoming / Accept Both のボタンが出る git add src/auth.py src/utils.py git commit # マージ完了(エディタが開くので保存) git pull # 改めて最新取り込み git push
シナリオ② 「よく分からない」状態から安全にやり直す
git status # → ヒントに "use git merge --abort" などが出る # 一旦全部無かったことに git merge --abort # 念のため変更を退避してから再度pull git stash push -m "before-retry" git pull --rebase git stash pop
シナリオ③ rebase中に出たunmerged filesエラー
git status # → "You are currently rebasing branch ..." # → "use git rebase --abort" # A: 解決して続行する # 該当ファイル修正 → add → continue git add <file> git rebase --continue # B: 途中放棄 git rebase --abort
rebase途中の他のトラブルはリベース途中でエラーになったときの復旧方法も参考に。
シナリオ④ どちらかの版を丸ごと採用したい
# 自分の版を優先(merge中) git checkout --ours src/auth.py # 相手の版を優先 git checkout --theirs src/auth.py # add してマージを完了 git add src/auth.py git commit
注意:--ours/--theirsはファイル全体をどちらかの版で上書きします。「変更を両方取り込みたい」場合には使わず、手動マージで内容を統合しましょう。特にrebase中では「ours」「theirs」の指す側が逆転するので注意(rebaseでは現在チェックアウト中の側がtheirs)。
GUI・IDEでのコンフリクト解消
主要ツール
- VS Code / Cursor:conflict箇所に「Accept Current/Incoming/Both」ボタン、3-way merge editor
- JetBrains:Git ツールウィンドウ → Conflicts → Merge Dialog(3ペイン)
- GitHub Desktop:Resolve conflicts ボタン → テキストエディタで解消
- SourceTree:ファイル右クリック → Resolve Conflicts
- git mergetool:CLIから3-wayツール(meld, kdiff3, vimdiff等)を起動
やってはいけない落とし穴
conflict マーカーを残したまま git add する
<<<<<<<、=======、>>>>>>>がファイル内に残った状態でgit addするとコンフリクトマーカーごとコミットされ、コードが文字通り壊れます。必ずエディタで全マーカーを消してからaddしてください。git grep -n "<<<<<<< "で取り残しを検索する癖を付けると安全です。
分かっていないのにforce push で脱出しようとする
「pull できないから push で上書きすればいい」と考えてgit push --forceすると、他メンバーの作業を破壊します。まずはabortで現場を片付け、正しく解決・同期してからpushしましょう。
abort と –skip を混同する
rebase中には--skipという「今のコミットだけ飛ばす」オプションもありますが、意図せず自分のコミットを捨ててしまう危険があります。使うのは「どうしても当該コミットを諦める」と決めたときだけ。迷ったら--abortで戻し、計画を立て直すのが安全です。
conflict解消を共有ブランチで直接やって失敗
main/developブランチ上で直接conflict解決すると、レビューを経ないまま本線に入ります。PRベースで取り込む運用にしておけば、「feature側でconflict解消→main取り込み」の流れに統一でき、事故が減ります。
stash pop で再びconflictを起こして同じエラーに戻る
abort→pull→stash popの順序で再開したとき、stashの内容が新たにpullした変更と衝突して再度「unmerged files」状態になることがあります。慌てずgit stashの内容を開いて手動で取り込むか、git stash branch new-branchで別ブランチで分離処理するのが落ち着いた対処です。
よくある質問
git statusで対象ファイルを確認 → エディタでマーカー解消 → git add <file> → git commitの順で進めます。addせずにcommitだけしても解決しません。git merge --abort(またはrebase --abort)で状態を戻してからgit stashを試してください。git diff --name-only --diff-filter=Uで未解決ファイルだけを抽出できます。マーカーを含む行を直接検索したいならgit grep -n "<<<<<<< "が便利です。git statusで再確認してください。詳細はコンフリクトを解消したのにpullできないときの原因と対策を参照。git merge --abortではなくgit rebase --abortを使います。解決して進める場合はgit add <file>→git rebase --continue。pull.rebase = true設定、フォーマッタ・linterを揃える、が基本対策です。履歴同期の詳細はリモートとローカルの履歴が食い違ったときの同期方法を参照。関連記事
- 【Git】コンフリクトしてpullできないときの対処法完全ガイド — 未コミット変更版の対処(本エラーとは別原因)
- 【Git】error: you need to resolve your current index first — index未解決での別コマンド実行エラー
- 【Git】コンフリクトを解消したのにpullできないときの原因と対策 — 解消後の手順抜け
- 【Git】リモートとローカルの履歴が食い違ったときの同期方法 — fetch/pull/rebaseの選び方
- 【Git】マージの取り消し方法 — マージ全体のロールバック
- 【Git】リベース途中でエラーになったときの復旧方法 — rebase –abort/–continue/–skip
- 【Git】pullで「untracked working tree files would be overwritten by merge」の解決方法 — 未追跡ファイル起因のpullエラー
- 【Git】rebaseとmergeの違いと使い分け — pull運用の方針決め
まとめ
- 「unmerged files」エラーはマージ/rebase/cherry-pick進行中でconflict未解決の合図
- 未コミット変更が原因のpullエラーとは別物——混同しない
- 解決ルート①:ファイル編集 →
git add→git commit(または--continue) - 解決ルート②:
git merge/rebase/cherry-pick --abortで一旦戻す git commit/git stash単独では解決しない(unmerged entryが残るため)- マーカーを残したまま
git addしない——git grep "<<<<<<< "で検証 - 予防:小さいPR/頻繁にrebase/
pull.rebase=true/フォーマッタ統一
このエラーは一見怖いメッセージですが、Git自身が「git statusを見て次にどうするか」のヒントをすべて出してくれています。「解消して進める」か「全部abortで戻す」の2択と割り切り、まずはgit statusで状況を読み、次の一手を決めましょう。慣れてしまえば3〜5分で片付く作業です。日常的にはconflictが出ないように小さく早くマージする運用が、もっともコストの低い予防策です。