33.

gitのマージツール(mergetool)の使い方|コンフリクト解決の手順と設定

編集

gitのマージ中にコンフリクト(競合)が発生したら、git mergetool コマンドを実行することで、設定した差分・マージ専用ツールを起動し、左右の変更を見比べながらコンフリクトを解決できる。マージツールを使えば、手作業でコンフリクトマーカーを削除するよりも安全かつ直感的に統合作業を進められる。

この記事の要点
  • コンフリクト発生後に git mergetool を実行すると、設定済みのマージツールが競合ファイルごとに順番に起動する。
  • 使うツールは git config merge.tool <name> であらかじめ指定する(vimdiff / meld / VS Code など)。
  • ツール上で競合を解消して保存・終了すると、そのファイルは自動的に解決済み(git add 相当)として扱われる。
  • 初期設定のままだと解決後に .orig というバックアップファイルが残るため、mergetool.keepBackup false で抑止できる。
  • 全ファイルを解決したら、最後に git commit でマージを完了させる。

マージコンフリクトとは

マージコンフリクト(競合)は、2つのブランチで同じファイルの同じ箇所がそれぞれ別々に変更されたとき、gitがどちらを採用すべきか自動判断できずに発生する。git mergegit rebasegit pull の途中で起こることが多い。

コンフリクトが起きると、gitは該当ファイルにコンフリクトマーカーを書き込み、マージ作業を一時停止する。利用者はそのファイルを編集して「最終的にどの内容を残すか」を決め、解決した旨をgitに伝える必要がある。この解決作業を支援するのが git mergetool である。

git mergetool の起動

コンフリクトが発生した状態で、リポジトリ内で次のコマンドを実行する。引数なしで実行すると、未解決のコンフリクトを含むすべてのファイルが順番にツールで開かれる。

git mergetool

特定のファイルだけを解決したい場合は、ファイル名を引数に指定する。

git mergetool path/to/file.txt

その場限りで使うツールを変えたい場合は、--tool オプションで上書きできる。

git mergetool --tool=meld

使うツールの設定

git mergetool は、設定された外部ツールを呼び出すための「ランチャー」に過ぎない。どのツールを使うかは merge.tool 設定で指定する。--global を付けると全リポジトリ共通の設定になる。

git config --global merge.tool <name>

<name> には使用するツール名(例: vimdiffmeldvscode 等)を入れる。設定例を以下に示す。

vimdiff(ターミナルのみで完結):

git config --global merge.tool vimdiff

Meld(GUIの差分・マージツール):

git config --global merge.tool meld

Visual Studio Code: 新しめのVS Codeでは、git側のツール名 vscode に対応している。古い環境やうまく動かない場合は、起動コマンドを明示する方法を使う。

git config --global merge.tool vscode

git config --global mergetool.vscode.cmd "code --wait --merge $REMOTE $LOCAL $BASE $MERGED"

使用可能なツール名の一覧は、次のコマンドで確認できる。環境にインストール済みのツールと、まだ使えるよう設定が必要なツールが表示される。

git mergetool --tool-help

実際の解決フロー

マージツールを使った典型的な解決手順は次の通り。

1. コンフリクトの発生。 マージなどを実行するとコンフリクトが報告される。

$ git merge feature

Auto-merging app.js

CONFLICT (content): Merge conflict in app.js

Automatic merge failed; fix conflicts and then commit the result.

2. 状況の確認。 git status で、どのファイルが未解決(Unmerged)かを把握する。

git status

3. マージツールの起動。 git mergetool を実行すると、未解決ファイルが1つずつツールで開かれる。多くのGUIツールでは、画面が3〜4ペインに分かれ、自分側(LOCAL)・相手側(REMOTE)・共通の祖先(BASE)・結果(MERGED)を見比べながら統合できる。

git mergetool

4. 保存して終了。 ツール上で最終的な内容を確定し、保存して終了する。git mergetool は、ツールが正常終了するとそのファイルを自動的に解決済みとして扱う(git add 相当の処理が行われる)ため、解決済みファイルに対して改めて git add を打つ必要は基本的にない。

5. .orig の扱い。 初期設定のままだと、解決したファイルの隣に ファイル名.orig というバックアップが残る。これはコミットすべきものではないので削除する。後述の設定で自動生成自体を止められる。

git clean -i # 不要ファイルを対話的に削除(.orig含む)

6. マージの完了。 すべてのコンフリクトを解決したら、git status で未解決が残っていないことを確認し、コミットしてマージを確定する。

git commit

コンフリクトマーカーの見方

マージツールを使わず手作業で解決する場合や、ツールがマーカー付きファイルを表示する場合に備えて、コンフリクトマーカーの読み方を押さえておく。コンフリクトが起きたファイルには、次のような記号が挿入される。

<<<<<<< HEAD

現在のブランチ(自分側)の内容

=======

マージしようとしている相手側の内容

>>>>>>> feature

  • <<<<<<< HEAD======= の間が、現在チェックアウト中のブランチ(自分側 / LOCAL)の変更。
  • =======>>>>>>> の間が、マージしてくる相手側(REMOTE)の変更。>>>>>>> の後ろにはブランチ名やコミットIDが付く。
  • 手作業の場合、最終的に残す内容を決めて、3種類のマーカー行(<<<<<<< / ======= / >>>>>>>)をすべて削除する。マーカーの消し忘れはバグの原因になる。

共通の祖先(BASE)も表示する diff3 スタイルを設定しておくと、「もとは何だったか」が分かり判断しやすくなる。

git config --global merge.conflictStyle diff3

主なマージツール比較

ツール名 種別 対応OS 特徴
vimdiff CUI Win / Mac / Linux Vim内蔵。追加インストール不要で、サーバー上でも使える。操作にVimの知識が必要。
Meld GUI Win / Mac / Linux 3ペイン表示が見やすい定番の無料ツール。直感的で初心者にも扱いやすい。
VS Code GUI Win / Mac / Linux 普段のエディタをそのまま利用可能。3-way Merge Editorで競合をボタン操作で取り込める。
KDiff3 GUI Win / Mac / Linux 3-way比較に強く、自動マージ機能が優秀。やや画面情報量が多い。
Beyond Compare GUI Win / Mac / Linux 高機能な有償ツール。大きなファイルやフォルダ単位の比較に強い。

落とし穴・注意点

よくあるトラブルと対策
  • .orig ファイルが大量に残る: git mergetool は標準でバックアップ(*.orig)を残す。次の設定で自動生成を止められる。
    git config --global mergetool.keepBackup false
  • 解決後の git add 忘れ: ツールを正常終了せず途中で閉じたり、手作業で直した場合は解決済みにならない。その場合は git add <file> を明示的に実行する。git status でUnmergedが残っていないか必ず確認する。
  • マーカーの消し忘れ: 手作業で直したとき <<<<<<<======= を消し忘れると、その文字列がそのままソースに混入する。コミット前に検索して残っていないか確認する。
  • ツールが起動しない: merge.tool が未設定、またはツール本体が未インストールだとエラーになる。git mergetool --tool-help で利用可能なツールを確認する。
  • 間違えてマージを進めてしまった: 解決前にマージ自体を取りやめたい場合は git merge --abort でマージ開始前の状態に戻せる。

よくある質問(FAQ)

Q. git mergetool を実行しても何も起きません。
A. 未解決のコンフリクトが存在しない場合、何も起動せず終了する。まず git status でUnmergedファイルがあるかを確認する。コンフリクトがあるのに起動しない場合は、merge.tool の設定漏れかツール未インストールが原因なので、git mergetool --tool-help で対応状況を確認する。

Q. マージツールを使わずに解決してもよいですか。
A. 問題ない。コンフリクトの内容が単純なら、ファイルを直接エディタで開いてマーカーを編集し、git addgit commit でも解決できる。git mergetool は、3つの内容を見比べたい場合や競合が複雑な場合に特に有効である。

Q. 解決の途中でやり直したくなりました。
A. マージ作業全体を取りやめてよいなら git merge --abort でマージ前に戻せる。特定ファイルだけ最初のコンフリクト状態に戻したい場合は git checkout --merge <file> を使う。

Q. .orig ファイルはコミットすべきですか。
A. しない。*.orig はマージツールが作るバックアップであり、リポジトリに含めるべきではない。削除するか、mergetool.keepBackup false で生成自体を止める。誤ってコミットしないよう .gitignore*.orig を追加しておくとよい。

編集
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」の状態

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