> ## Documentation Index
> Fetch the complete documentation index at: https://docs.diversion.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 外部マージツール

> UnityYAMLMerge、KDiff3、Meld など、自分のマージツールでマージ競合を解決します。

マージに競合がある場合、Diversion は競合している各ファイルに対して、選択したマージツールを実行できます。ツールがファイルの 2 つのバージョンをマージし、Diversion がその結果をマージに保存します。

特別なマージツールが必要なファイルに使用してください。例:

* Unity のシーンとプレハブは、UnityYAMLMerge (Unity Smart Merge) で
* JSON、YAML、ソースコードは、mergiraf のような構文を理解するツールで
* 手動でマージしたい任意のファイルは、KDiff3 や Meld のようなビジュアルツールで

## クイックスタート

1. マージツールを追加します。コンピューターごとに 1 回だけ必要です。この例は JSON ファイルをマージします:
   ```bash theme={null}
   dv merge-tool add --name mergiraf --pattern '\.json$' --cmd 'mergiraf merge $ANCESTOR $CURRENT $INCOMING -o $RESULT'
   ```
2. 自分のツールでマージします:
   ```bash theme={null}
   dv merge <branch> --conflict_resolution merge-tool
   ```
3. Diversion はまずサーバー上でマージできるものをマージします。残った競合ごとに、ファイルにマッチするツールを実行します。最後まで解決されなかった競合は、Diversion アプリで解決してください。

Unity やその他のツールについては、[例](#例) を参照してください。

## 仕組み

1. `merge-tool` の競合解決を指定して、マージ、更新、またはリバートを開始します。
2. Diversion はまずサーバー上でマージできるものをマージします。テキストファイルの異なる部分を両側が変更した場合、Diversion が自動的にマージするため、ツールは実行されません。
3. 残った競合ごとに、Diversion はファイルパスにパターンがマッチする最初のツールを見つけます。ファイルの各バージョンを一時ファイルにダウンロードし、ツールを実行します。
4. ツールがすべての競合を解決すると、Diversion はマージを完了してコミットを作成します。
5. 一部の競合が解決されなかった場合、マージは開いたままになります。残りは Diversion アプリで解決します。ツールが解決した競合は、解決済みのまま保持されます。

<Note>
  マージツールはあなたのコンピューター上で実行されます。ツールの設定はリポジトリではなく、このコンピューターのあなたのユーザーに保存されるため、チームメンバーはそれぞれ自分のツールをセットアップします。
</Note>

## マージツールをセットアップする

<Steps>
  <Step title="ツールをインストールする">
    マージツールをインストールし、そのプログラムへのフルパスを確認します。プログラムが `PATH` 上にある場合は、プログラム名だけで十分です。
  </Step>

  <Step title="ツールを Diversion に追加する">
    どのファイルをそのツールで処理し、どう実行するかを Diversion に指定します:

    ```bash theme={null}
    dv merge-tool add --name <name> --pattern '<regex>' --cmd '<command>'
    ```

    すぐに使えるコマンドは [例](#例) を参照してください。
  </Step>

  <Step title="セットアップを確認する">
    Diversion がマッチングする順序で、ツールを一覧表示します:

    ```bash theme={null}
    dv merge-tool
    ```
  </Step>
</Steps>

### コマンドプレースホルダー

`--cmd` では、ファイルパスとして以下のプレースホルダーを使用します。Diversion はツールを実行する前に、これらを一時ファイルに置き換えます。

| プレースホルダー | 置き換えられる内容 |
| - | - |
| `$ANCESTOR` | 共通の祖先: どちらの側も変更する前のファイル |
| `$CURRENT` | 自分の側: マージ先のブランチ、または `update` と `revert` の場合はワークスペース |
| `$INCOMING` | 受け入れる側: マージするブランチまたはコミット、`update` の場合はブランチの最新バージョン、`revert` の場合はリバートされた内容 |
| `$RESULT` | 出力ファイル。ツールはマージ結果をここに書き込む必要があります。最初は空です。 |

コマンドのルール:

* `--cmd` には `$RESULT` を含める必要があります。
* コマンドはシェルを介さず直接実行されます。パイプ (`|`)、リダイレクト (`>`)、環境変数は機能しません。必要な場合は、手順をスクリプトにまとめ、そのスクリプトをコマンドに設定してください。
* スペースを含むプログラムパスは二重引用符で囲んでください。
* Mac と Linux では、`--cmd` の値全体を単一引用符で囲んでください。そうしないと、Diversion に届く前にシェルが `$ANCESTOR` などのプレースホルダーを置き換えてしまいます。

一時ファイルは元のファイル拡張子を保持します (例: `local.prefab`)。これは、UnityYAMLMerge や mergiraf のように、拡張子からマージ方法を決めるツールで重要です。

### ファイルパターン

`--pattern` は正規表現です。Diversion はリポジトリ内のファイルパスに対してマッチングします。

| パターン | マッチするもの |
| - | - |
| `\.prefab$` | `.prefab` で終わるファイル |
| `\.(unity\|prefab)$` | `.unity` または `.prefab` で終わるファイル |
| `Characters/.*\.prefab$` | 任意の `Characters` フォルダー内の `.prefab` ファイル |
| `.*` | すべてのファイル |

複数のツールがファイルにマッチする場合、**リストの最初のツールが優先されます**。`dv merge-tool add` は新しいツールをリストの末尾に追加します。順序は `dv merge-tool` で確認してください。

どのツールにもマッチしないファイルは、Diversion アプリで解決するために残されます。

### 終了コードとビジュアルツール

デフォルトでは、`git mergetool` と同じように、ツールの終了コードが結果を決めます:

| 終了コード | 結果 |
| - | - |
| `0` | 解決済み。Diversion は `$RESULT` の内容を保存します。 |
| `1` から `127` | ツールが競合を未解決のまま残しました。Diversion アプリで解決します。 |
| `128` 以上 | ツールが失敗しました。 |

一部のビジュアルツールは、保存せずに閉じても `0` で終了します。そのようなツールには `--no-trust-exit-code` を追加してください。Diversion は終了コードを無視して `$RESULT` を確認します:

* ツールが `$RESULT` に書き込み、ファイルに競合マーカー (`<<<<<<<`) がなければ、競合は解決済みです。
* そうでない場合、Diversion は `Was the merge successful? [y/n]` と確認します。
* CI ジョブなど、確認するターミナルがない場合、競合は未解決のままになります。

## 例

### Unity Smart Merge (UnityYAMLMerge)

UnityYAMLMerge は Unity Editor に付属しています。Unity のシーン、プレハブ、その他の YAML アセットをマージします。テキストとして保存されたアセットでのみ機能するため、先に **Asset Serialization Mode** を `Force Text` に設定してください ([Unity ベストプラクティス](/ja/unity/unity-best-practices#初期セットアップ) を参照)。

`6000.0.23f1` はお使いの Unity バージョンに変更してください:

<CodeGroup>
  ```bash macOS theme={null}
  dv merge-tool add --name unity-yaml \
    --pattern '\.(unity|prefab|asset|mat|anim|controller)$' \
    --cmd '"/Applications/Unity/Hub/Editor/6000.0.23f1/Unity.app/Contents/Tools/UnityYAMLMerge" merge -p $ANCESTOR $INCOMING $CURRENT $RESULT'
  ```

  ```bat Windows (Command Prompt) theme={null}
  dv merge-tool add --name unity-yaml --pattern "\.(unity|prefab|asset|mat|anim|controller)$" --cmd "\"C:\Program Files\Unity\Hub\Editor\6000.0.23f1\Editor\Data\Tools\UnityYAMLMerge.exe\" merge -p $ANCESTOR $INCOMING $CURRENT $RESULT"
  ```
</CodeGroup>

<Note>
  UnityYAMLMerge はファイルを base、remote、local、merged の順序で受け取ります。これは他の多くのツールとは異なります。
</Note>

<Tip>
  Windows では、この例を Command Prompt で実行してください。PowerShell はバージョンによって引数内の引用符の扱いが異なるため、引用符で囲んだプログラムパスが壊れることがあります。
</Tip>

### mergiraf (JSON、YAML、コード)

[mergiraf](https://mergiraf.org) は多くのファイルタイプの構文を理解します。1 つの JSON オブジェクトに追加された 2 つの新しいキーのように、同じ行に対する 2 つの変更をマージできます。

```bash theme={null}
dv merge-tool add --name mergiraf \
  --pattern '\.(json|ya?ml|toml)$' \
  --cmd 'mergiraf merge $ANCESTOR $CURRENT $INCOMING -o $RESULT'
```

### KDiff3

KDiff3 は、マージできるものは自動でマージします。あなたの対応が必要な競合が残ったときにだけウィンドウを開きます。

```bash theme={null}
dv merge-tool add --name kdiff3 \
  --pattern '\.(ini|cfg)$' \
  --cmd 'kdiff3 $ANCESTOR $CURRENT $INCOMING -o $RESULT --auto'
```

### Meld

Meld は保存せずに閉じても `0` で終了するため、`--no-trust-exit-code` を追加します:

```bash theme={null}
dv merge-tool add --name meld \
  --pattern '\.txt$' \
  --cmd 'meld $CURRENT $ANCESTOR $INCOMING -o $RESULT' \
  --no-trust-exit-code
```

## マージツールで競合を解決する

### CLI から

[`dv merge`](/ja/cmd-ref/merge)、[`dv update`](/ja/cmd-ref/update)、または [`dv revert`](/ja/cmd-ref/revert) に `--conflict_resolution merge-tool` を追加します:

```bash theme={null}
dv merge feature/new-level --conflict_resolution merge-tool
dv update --conflict_resolution merge-tool
dv revert <commit_id> --conflict_resolution merge-tool
```

ツールが 1 つもセットアップされていない場合、コマンドはマージを開始する前に停止します。

ツールは競合を 1 つずつ処理します。その後、CLI はファイルごとの結果を出力します:

```text theme={null}
merge encountered conflicts, resolving with external merge tools
Resolved 1 conflict(s) with external tools:
  - Assets/Prefabs/Player.prefab (unity-yaml)
Skipped 1 conflict(s), left for manual resolution:
  - Assets/Textures/Hero.psd: no merge tool is configured for this file
Not all conflicts were resolved. Please resolve the rest manually:
https://app.diversion.dev/repo/<repo_id>/merges/<merge_id>
```

| 結果 | 意味 | 対応 |
| - | - | - |
| **Resolved** | ツールがファイルをマージし、Diversion が結果をマージに保存しました。 | 不要です。 |
| **Skipped** | ファイルにマッチするツールがない、ツールが競合を未解決のまま残した、または `n` と回答した場合です。 | 出力されたリンクを開き、Diversion アプリでファイルを解決します。 |
| **Failed** | ツールが起動しなかった、終了コード `128` 以上で終了した、またはファイルのダウンロードやアップロードが失敗した場合です。 | `dv merge-tool` でツールを確認してから、Diversion アプリでファイルを解決します。 |

Diversion は、すべての競合が解決されたときにのみマージを完了します。いずれかの競合が Skipped または Failed になった場合、マージは開いたままになり、コマンドはゼロ以外の終了コードで終了するため、スクリプトから検知できます。

## マージツールを管理する

```bash theme={null}
dv merge-tool            # ツールをマッチング順に一覧表示
dv merge-tool add ...    # ツールを追加、または同名のツールを更新
dv merge-tool -d <name>  # ツールを削除
```

すでに存在する名前でツールを追加すると、Diversion はそのツールを置き換え、リスト内の位置を保持します。

Diversion はツールを `~/.diversion/merge_tools.json` (Windows では `%USERPROFILE%\.diversion\merge_tools.json`) に保存します。ファイルを直接編集する代わりに、`dv merge-tool` で変更してください。

すべてのオプションは [`dv merge-tool`](/ja/cmd-ref/merge-tool) を参照してください。

## トラブルシューティング

| メッセージ | 原因と対処 |
| - | - |
| `no merge tools configured` | ツールがありません。`dv merge-tool add` で追加してください。 |
| `no merge tool is configured for this file` | ファイルパスにマッチするパターンがありません。`dv merge-tool` でパターンを確認してください。 |
| `the tool exited with code N and left the conflict unresolved` | ツールが自力でファイルをマージできませんでした。Diversion アプリで解決してください。 |
| `the tool wrote an empty file while a side still had content` | ツールが結果を `$RESULT` に書き込みませんでした。たとえば `-o $RESULT` のように、コマンドが `$RESULT` に書き込むことを確認してください。 |
| `the two sides differ only in metadata` | ファイルの内容は同じですが、ファイル名など他の何かが変更されています。マージツールでは対応できません。Diversion アプリで解決してください。 |
| `failed to run merge tool` | Diversion がプログラムを起動できませんでした。プログラムへのフルパスを使用し、スペースが含まれる場合は二重引用符で囲んでください。 |
| ビジュアルツールで、保存せずに閉じてもファイルが解決済みになる | `--no-trust-exit-code` を付けてツールを追加し直してください。 |

## 関連

* [`dv merge-tool`](/ja/cmd-ref/merge-tool) -- マージツールを管理する CLI リファレンス
* [競合](/ja/concepts/conflicts) -- 競合の種類と解決方法
* [ブランチとマージ](/ja/core-concepts/branching-merging)
* [Unity ベストプラクティス](/ja/unity/unity-best-practices)
