# 機能設計書 32-マージコンフリクト解決

## 概要

本ドキュメントは、GitLabのマージリクエストにおけるマージコンフリクト解決機能の設計仕様を記載する。本機能はコンフリクトの検出とWeb UI上での解決を提供する。

### 本機能の処理概要

マージコンフリクト解決機能は、ソースブランチとターゲットブランチの間で発生したコンフリクト（競合）を検出し、Web UIを通じて解決することを可能にする機能である。

**業務上の目的・背景**：Git操作に不慣れな開発者でも、コマンドライン操作なしにコンフリクトを解決できるようにすることで、開発効率を向上させる。また、コンフリクト解決のためにローカル環境を準備する手間を省き、迅速なマージを実現する。

**機能の利用シーン**：マージリクエストでコンフリクトが発生した際に、開発者がWeb UIからコンフリクトを確認し、どちらの変更を採用するか、または手動でマージした内容を入力して解決する場面で利用される。

**主要な処理内容**：
1. コンフリクト状態の検出とステータス表示
2. コンフリクトファイル一覧の表示
3. 各ファイルのコンフリクト詳細表示（両方の変更内容）
4. インライン編集またはサイドバイサイド形式での解決方法選択
5. 解決内容のコミットと自動プッシュ

**関連システム・外部連携**：Gitalyサービスによるコンフリクト解決コミットの作成、NotificationServiceを通じた解決完了通知

**権限による制御**：ソースブランチへのプッシュ権限を持つユーザーのみがコンフリクトを解決可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 65 | コンフリクト解決 | 主画面 | マージコンフリクトの解決処理 |
| 63 | MR詳細 | 参照画面 | コンフリクト状態の確認、解決画面への遷移 |

## 機能種別

ワークフロー操作（コンフリクト検出・解決）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| merge_request_id | Integer | Yes | 対象マージリクエストのID | 存在チェック |
| commit_message | String | Yes | 解決コミットのメッセージ | 空文字不可 |
| files | Array | Yes | 解決ファイルの配列 | 各ファイルのセクション選択必須 |
| files[].old_path | String | Yes | 変更前のファイルパス | |
| files[].new_path | String | Yes | 変更後のファイルパス | |
| files[].sections | Array | Yes | セクションごとの解決選択 | |

### 入力データソース

- 画面入力（解決方法の選択、コミットメッセージ）
- マージリクエストの差分データ
- Gitalyからのコンフリクト情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| redirect_to | String | 解決完了後のリダイレクト先URL |
| message | String | エラーメッセージ（エラー時） |
| type | String | メッセージタイプ（error等） |
| conflicts | JSON | コンフリクトファイル情報（表示用） |

### 出力先

- 画面表示（JSON形式でフロントエンドに返却）
- Gitリポジトリ（解決コミット）
- データベース（マージリクエストのステータス更新）

## 処理フロー

### 処理シーケンス

```
1. コンフリクト状態チェック
   └─ ListService#can_be_resolved_in_ui?でUI解決可能か判定
2. コンフリクト一覧表示
   └─ Gitlab::Conflict::FileCollectionでファイル一覧取得
3. 解決方法選択
   └─ ユーザーが各セクションの解決方法を選択
4. 解決実行
   └─ ResolveService#executeで解決コミット作成
5. 完了処理
   └─ フラッシュメッセージ表示、MR詳細画面にリダイレクト
```

### フローチャート

```mermaid
flowchart TD
    A[MR詳細画面] --> B{コンフリクト発生?}
    B -->|No| C[マージ可能]
    B -->|Yes| D{UI解決可能?}
    D -->|No| E[ローカル解決を促す]
    D -->|Yes| F[コンフリクト解決画面表示]
    F --> G[ファイル一覧表示]
    G --> H[各ファイルの解決方法選択]
    H --> I{全ファイル解決済み?}
    I -->|No| H
    I -->|Yes| J[コミットメッセージ入力]
    J --> K[解決コミット作成]
    K --> L{成功?}
    L -->|Yes| M[MR詳細にリダイレクト]
    L -->|No| N[エラーメッセージ表示]
    N --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-32-01 | UI解決可否判定 | cannot_be_merged?かつcomplete_diff_refs存在かつブランチ存在の場合のみUI解決可能 | コンフリクト画面表示時 |
| BR-32-02 | 権限チェック | ソースブランチへのプッシュ権限が必要 | 解決実行時 |
| BR-32-03 | 既解決チェック | 既にマージ可能になった場合はエラー | 解決実行時 |
| BR-32-04 | ツリーコンフリクト | ファイル追加/削除のコンフリクトはUI解決不可 | UI解決可否判定時 |

### 計算ロジック

特になし

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ステータス更新 | merge_requests | UPDATE | merge_statusの更新 |
| diff更新 | merge_request_diffs | INSERT | 新しいdiff作成 |

### テーブル別操作詳細

#### merge_requests

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | merge_status | 'can_be_merged' | 解決成功時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 400 | BadRequest | 既にマージ可能な状態 | 解決済みメッセージ表示 |
| 400 | BadRequest | 解決エラー（ResolutionError） | エラーメッセージ表示 |
| 404 | NotFound | UI解決不可能な場合 | 404画面表示 |

### リトライ仕様

エラー発生時はユーザーに再操作を促す。Gitaly通信エラーの場合は自動リトライなし。

## トランザクション仕様

Gitalyへのコミット作成は外部サービス呼び出しのため、Railsトランザクション外で実行。

## パフォーマンス要件

- urgency :low指定（低優先度、応答時間制約緩和）
- 大量のコンフリクトファイルがある場合は処理時間増加の可能性

## セキュリティ考慮事項

- authorize_can_resolve_conflicts!によるソースブランチプッシュ権限チェック
- UserAccessクラスによる詳細な権限検証

## 備考

- ツリーコンフリクト（ファイルの追加/削除が競合）はUI解決不可のため、ローカルでの解決が必要
- バイナリファイルのコンフリクトもUI解決不可

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

コンフリクト情報を保持するクラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | file_collection.rb | `lib/gitlab/conflict/file_collection.rb` | コンフリクトファイルのコレクション |
| 1-2 | file.rb | `lib/gitlab/conflict/file.rb` | 個別コンフリクトファイルの構造 |
| 1-3 | merge_request.rb | `app/models/merge_request.rb` | コンフリクト関連メソッド |

**読解のコツ**: Gitlab::Conflict名前空間のクラスがコンフリクト処理の中核。

#### Step 2: エントリーポイントを理解する

コントローラーが処理の起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | conflicts_controller.rb | `app/controllers/projects/merge_requests/conflicts_controller.rb` | 全アクションの概要 |

**主要処理フロー**:
1. **14-39行目**: showアクション - コンフリクト一覧表示、HTML/JSON両対応
2. **42-49行目**: conflict_for_pathアクション - 個別ファイルのコンフリクト詳細
3. **52-74行目**: resolve_conflictsアクション - 解決処理実行

#### Step 3: サービス層を理解する

ビジネスロジックはサービスクラスに実装されている。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | list_service.rb | `app/services/merge_requests/conflicts/list_service.rb` | コンフリクト一覧取得、UI解決可否判定 |
| 3-2 | resolve_service.rb | `app/services/merge_requests/conflicts/resolve_service.rb` | 解決処理実行 |

**主要処理フロー**:
- **list_service.rb 8-13行目**: can_be_resolved_by?でユーザー権限チェック
- **list_service.rb 15-27行目**: can_be_resolved_in_ui?でUI解決可否判定
- **resolve_service.rb 6-10行目**: 解決処理の実行

#### Step 4: Gitaly連携を理解する

実際のGit操作はGitalyを通じて行われる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | file_collection.rb | `lib/gitlab/conflict/file_collection.rb` | resolve メソッド |
| 4-2 | resolver.rb | `lib/gitlab/git/conflict/resolver.rb` | Gitaly呼び出し |

### プログラム呼び出し階層図

```
ConflictsController
    │
    ├─ show
    │      └─ ListService#can_be_resolved_in_ui?
    │              └─ Gitlab::Conflict::FileCollection#can_be_resolved_in_ui?
    │
    ├─ conflict_for_path
    │      └─ ListService#file_for_path
    │              └─ Gitlab::Conflict::FileCollection#file_for_path
    │
    └─ resolve_conflicts
           └─ ResolveService#execute
                  └─ Gitlab::Conflict::FileCollection#resolve
                         └─ Gitlab::Git::Conflict::Resolver#resolve_conflicts
```

### データフロー図

```
[入力]                    [処理]                              [出力]

MRアクセス ───▶ ConflictsController#show
                    │
                    ▼
              ListService
                    │
                    ▼
              FileCollection ───▶ コンフリクト一覧JSON

解決選択 ───▶ ConflictsController#resolve_conflicts
                    │
                    ▼
              ResolveService
                    │
                    ▼
              FileCollection#resolve
                    │
                    ▼
              Gitaly (Resolver) ───▶ 解決コミット作成
                    │
                    ▼
              リダイレクト ───▶ MR詳細画面
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| conflicts_controller.rb | `app/controllers/projects/merge_requests/conflicts_controller.rb` | コントローラー | コンフリクト関連アクション |
| list_service.rb | `app/services/merge_requests/conflicts/list_service.rb` | サービス | コンフリクト一覧・判定 |
| resolve_service.rb | `app/services/merge_requests/conflicts/resolve_service.rb` | サービス | 解決処理実行 |
| base_service.rb | `app/services/merge_requests/conflicts/base_service.rb` | サービス | 基底クラス |
| file_collection.rb | `lib/gitlab/conflict/file_collection.rb` | ライブラリ | コンフリクトファイル管理 |
| file.rb | `lib/gitlab/conflict/file.rb` | ライブラリ | 個別ファイル情報 |
| resolver.rb | `lib/gitlab/git/conflict/resolver.rb` | ライブラリ | Gitaly連携 |
| merge_request.rb | `app/models/merge_request.rb` | モデル | MRモデル |
