34.

Git MERGING 状態の解消方法完全ガイド

編集
この記事の要点
  • MERGING 状態 = git merge 中にコンフリクトが発生し、解決待ちの状態
  • 内部的には .git/MERGE_HEAD ファイルが存在し、シェルプロンプトに (MERGING) 表示
  • 進む: 競合解決 → git add .git commit(マージコミット作成)
  • 取り消す: git merge --abort(マージ前の状態に戻る、安全)
  • 強制解除(非推奨): git reset --merge / git reset --hard ORIG_HEAD。関連状態に REBASING / CHERRY-PICKING

MERGING 状態とは

git merge 実行中に、Git が自動マージできないコンフリクトを検出すると、リポジトリは「マージ作業中」を示すMERGING 状態になります。シェルプロンプト (zsh の git-prompt 等) に (main|MERGING) と表示されるのはこの状態です。

$ git merge feature
Auto-merging src/app.php
CONFLICT (content): Merge conflict in src/app.php
Automatic merge failed; fix conflicts and then commit the result.

# プロンプトが MERGING に
(main|MERGING) $

MERGING 状態の判定

# 状態確認
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/app.php

# 内部ファイルの存在
ls .git/MERGE_HEAD .git/MERGE_MSG
# .git/MERGE_HEAD  ← これがあれば MERGING 中
# .git/MERGE_MSG   ← マージコミット用メッセージのドラフト

取りうる 3 つの選択肢

選択肢コマンド結果
① 競合解決して完了編集 → git add → git commitマージコミット作成 (推奨)
② マージを取り消すgit merge --abortマージ前の状態に戻る (安全)
③ マージを強制完了 (空マージ)git commit --allow-empty非推奨。状況限定

選択肢①: 競合解決 → コミット

競合した箇所は次のようなマーカーで示されます:

<<<<<<< HEAD
echo "main branch version";
=======
echo "feature branch version";
>>>>>>> feature

これを「どちらか」または「両方」を残す形に編集します。Git は中身を解釈しないので、自分でロジック的に正しい形を選ぶ必要があります。

# 1. 衝突ファイルを編集してマーカー (<<<, ===, >>>) を消す
$EDITOR src/app.php

# 2. 解決済みとしてステージ
git add src/app.php

# 全衝突解決を一括ステージ
git add .

# 3. マージコミット作成
git commit
# (エディタが開いて、MERGE_MSG の内容で確定)

# メッセージを指定
git commit -m "Merge branch 'feature' into main"

# 状態確認
git status
# nothing to commit, working tree clean
# (main) ← MERGING が消える

衝突解決の支援ツール

# 衝突中のファイル一覧
git diff --name-only --diff-filter=U
# src/app.php

# 各ファイルの衝突箇所
git diff

# GUI マージツール
git mergetool
# vimdiff / kdiff3 / VS Code 等が起動

# VS Code を mergetool に
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'

「相手側」「自分側」をまるごと採用

# ours (現在のブランチ側を採用)
git checkout --ours  src/app.php

# theirs (マージ元側を採用)
git checkout --theirs src/app.php

# ステージして完了
git add src/app.php
git commit

選択肢②: マージを取り消す

これが一番安全な「やり直し」手段です。マージ前の HEAD に戻り、作業ツリーも復元されます:

git merge --abort

# 確認
git status
# On branch main
# nothing to commit, working tree clean

# (Git 2.11 以降推奨。古い Git では git reset --merge と同等)

--abort 前に行った未コミットのローカル変更も復元される点が安全。ただし、マージ衝突中に手動編集した内容は失われます (それは想定通り)。

選択肢③: 強制的に完了 / 強制的にリセット

状況により以下も使われますが、未コミット変更の喪失に注意:

# 全衝突を未解決のまま、現在の状態でマージコミットを作る (危険)
git commit -am "WIP merge"

# マージ作業中の状態を完全に破棄して直前の HEAD へ
git reset --merge

# 直前の HEAD (ORIG_HEAD) へハードリセット
git reset --hard ORIG_HEAD

# git reset --hard は未コミット変更を消すので注意
# git stash で退避してから実行することも検討

git merge --continue (Git 2.12+)

競合解決 → git add 済の状態で、コミットを完了するには:

git merge --continue
# = git commit (MERGE_MSG をテンプレに)

関連状態: REBASING / CHERRY-PICKING / BISECTING

MERGING と同様に、Git は各操作中の状態をマーカーファイルで管理しています:

状態マーカー進める取り消す
MERGING.git/MERGE_HEADgit merge --continuegit merge --abort
REBASING.git/rebase-merge/ or rebase-apply/git rebase --continuegit rebase --abort
CHERRY-PICKING.git/CHERRY_PICK_HEADgit cherry-pick --continuegit cherry-pick --abort
REVERTING.git/REVERT_HEADgit revert --continuegit revert --abort
BISECTING.git/BISECT_LOGgit bisect good/badgit bisect reset

よくあるシナリオ

1. git pull で MERGING になった

git pull
# Auto-merging ...
# CONFLICT ...

# 解決
$EDITOR conflicting-file
git add .
git commit

# やり直したい
git merge --abort
git pull --rebase    # rebase 方式で取り込み直し

2. MERGING を放置したまま別ブランチに行きたい

# ❌ 直接 checkout は怒られる
git checkout other-branch
# error: you need to resolve your current index first

# 正しい順序
git merge --abort
git checkout other-branch

# どうしても変更を取っておきたい場合
git stash --include-untracked
git merge --abort
git stash pop

3. MERGE_HEAD が残ったまま再起動 → 状態が分からない

# 内部ファイルから判断
ls .git/MERGE_HEAD .git/MERGE_MSG .git/CHERRY_PICK_HEAD .git/REBASE_HEAD 2>/dev/null

# MERGING 中なのが判明したら
git merge --abort

FAQ

Q: git merge --abort しても MERGING が消えない
A: Git のバージョンが古い可能性。git reset --merge または git reset --hard ORIG_HEAD で代用。

Q: マージコミットを残したくない
A: git merge --abort してから git pull --rebase あるいは git rebase target-branch。マージコミットの代わりに線形履歴になります。

Q: 衝突ファイルがバイナリ (画像など)
A: テキストマーカーは入らない。git checkout --ours/--theirs でどちらか丸ごと採用 → git add

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 用語一覧
  2. エラー一覧
  3. git本体のインストール(Linux)
  4. Linuxサーバーへのgit導入とクライアントのセットアップ
  5. リモートリポジトリをローカルリポジトリとしてクローンする方法
  6. リモートとローカルのリポジトリを同期(pull)する方法
  7. 設定の確認
  8. gitユーザー名とemailの設定
  9. リモートリポジトリの作成
  10. ローカルリポジトリの作成
  11. 新規ファイル/ディレクトリをインデックスに登録
  12. インデックスの登録状態を確認
  13. ローカルリポジトリの変更をコミット
  14. コミット履歴の確認
  15. クライアントからリモートリポジトリの接続設定、確認、削除
  16. リポジトリへのプッシュ
  17. リモートリポジトリからクライアントへのSSHクローン
  18. リモートとローカルの差分表示
  19. バージョンの確認
  20. プロキシの設定
  21. ローカルをリモートリポジトリの状態に戻す
  22. ブランチの作成, 一覧表示, 切り替え
  23. ブランチのマージと削除
  24. リベース
  25. .gitignoreの書き方
  26. .gitignoreの設定が反映されない場合
  27. 特定のファイルをgitの管理から外す方法
  28. 参照(ORIG_HEAD, HEAD, FETCH_HEAD)
  29. git rm [-r --cached] の取り消し
  30. 一部のディレクトリ/ファイルのみをリポジトリから復元する方法
  31. ローカルとリモートリポジトリの有無を同期
  32. pushの取消し方法
  33. マージツールの起動方法
  34. Gitで「MERGING」の状態

最近更新/作成されたページ