# 画面設計書 65-コンフリクト解決

## 概要

本ドキュメントは、GitLabプロジェクトのマージリクエストコンフリクト解決画面の設計仕様を定義するものである。

### 本画面の処理概要

本画面は、マージリクエストにおいてソースブランチとターゲットブランチ間で発生したマージコンフリクトを、Web UI上で解決するための画面である。GitLabのWeb画面から直接コンフリクトを確認し、解決方法を選択してコミットすることができる。

**業務上の目的・背景**：マージリクエストのマージ時にコンフリクトが発生した場合、通常はローカル環境でGitコマンドを使用して解決する必要がある。しかし、簡単なコンフリクト（テキストの競合など）については、Web UI上で視覚的に確認しながら解決できる方が効率的である。本画面は、そのような軽微なコンフリクトをローカル環境を使わずに解決する機能を提供する。

**画面へのアクセス方法**：
1. MR詳細画面のマージウィジェットで「Resolve conflicts」ボタンをクリック
2. URLに直接`/-/merge_requests/:iid/conflicts`を入力

**主要な操作・処理内容**：
1. コンフリクト発生ファイルの一覧確認
2. 各ファイルのコンフリクト箇所の確認
3. 解決方法の選択（ours/theirs/編集）
4. インラインエディタでの手動編集
5. コンフリクト解決のコミット

**画面遷移**：
- 遷移元：MR詳細画面（マージウィジェット）
- 遷移先：MR詳細画面（解決成功時）

**権限による表示制御**：
- コンフリクト解決権限：ソースブランチへのプッシュ権限が必要
- 読み取り専用モード：権限がない場合はボタン非表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 32 | マージコンフリクト解決 | 主機能 | マージコンフリクトの解決処理 |

## 画面種別

詳細/編集

## URL/ルーティング

| メソッド | URL | アクション | 説明 |
|----------|-----|-----------|------|
| GET | `/:namespace_id/:project_id/-/merge_requests/:id/conflicts` | show | コンフリクト解決画面表示 |
| GET | `/:namespace_id/:project_id/-/merge_requests/:id/conflicts.json` | show | コンフリクト情報（JSON） |
| GET | `/:namespace_id/:project_id/-/merge_requests/:id/conflict_for_path` | conflict_for_path | 特定ファイルのコンフリクト |
| POST | `/:namespace_id/:project_id/-/merge_requests/:id/resolve_conflicts` | resolve_conflicts | コンフリクト解決実行 |

## 入出力項目

### 入力項目（解決時）

| 項目名 | データ型 | 必須 | 説明 |
|--------|---------|------|------|
| files | array | ○ | 解決対象ファイル配列 |
| files[].old_path | string | ○ | 元のファイルパス |
| files[].new_path | string | ○ | 新しいファイルパス |
| files[].sections | array | ○ | コンフリクトセクション |
| files[].sections[].conflict | boolean | ○ | コンフリクトかどうか |
| files[].sections[].resolution | string | - | 解決方法（head/origin/content） |
| files[].sections[].content | string | - | 手動編集時のコンテンツ |
| commit_message | string | - | コミットメッセージ |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| MRタイトル | string | マージリクエストのタイトル |
| ソースブランチ | string | マージ元ブランチ名 |
| ターゲットブランチ | string | マージ先ブランチ名 |
| コンフリクトファイル一覧 | array | コンフリクトが発生したファイル |
| コンフリクト内容 | object | 各ファイルのコンフリクト詳細 |
| ours側の内容 | string | ソースブランチ側の内容 |
| theirs側の内容 | string | ターゲットブランチ側の内容 |

## イベント仕様

### 1-ファイル選択

コンフリクトファイル一覧からファイルを選択すると、そのファイルのコンフリクト内容が表示される。

### 2-解決方法選択

各コンフリクトセクションに対して、以下の解決方法を選択できる：
- **Use ours**: ソースブランチ（自分）の変更を採用
- **Use theirs**: ターゲットブランチ（相手）の変更を採用
- **Edit inline**: 手動で内容を編集

### 3-インライン編集

「Edit inline」を選択した場合、テキストエディタが表示され、コンフリクト部分を直接編集できる。

### 4-コンフリクト解決コミット

すべてのコンフリクトに対して解決方法を選択後、「Commit to source branch」ボタンをクリックすると、解決内容がコミットされる。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | merge_requests | SELECT | MR情報の取得 |
| コンフリクト解決 | merge_request_diffs | UPDATE | 差分情報の更新 |
| コンフリクト解決 | events | INSERT | イベント記録 |

### テーブル別更新項目詳細

#### merge_request_diffs（間接的）

コンフリクト解決はGitリポジトリへの直接コミットとして実行されるため、データベースへの直接更新はない。後続の差分再計算で自動更新される。

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|---------|
| 成功 | All merge conflicts were resolved. The merge request can now be merged. | 解決成功時 |
| 警告 | The merge conflicts for this merge request have already been resolved. Please return to the merge request. | 既に解決済み |
| エラー | The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally. | UI解決不可 |
| エラー | (各種Git操作エラー) | Git操作失敗時 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| MRが見つからない | 404エラーページを表示 |
| 解決権限がない | 404エラーページを表示 |
| コンフリクトがない | エラーメッセージと詳細画面へのリンク |
| UIで解決不可能なコンフリクト | ローカル解決を促すメッセージ |
| Git操作エラー | エラーメッセージを表示 |

## 備考

- バイナリファイルのコンフリクトはUI解決不可
- 複雑なコンフリクト（3-way mergeが必要な場合等）はUI解決不可
- 解決コミットはソースブランチに対して行われる
- 利用統計がトラッキングされる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | conflicts_controller.rb | `app/controllers/projects/merge_requests/conflicts_controller.rb` | showアクションとresolve_conflictsアクション |

**主要処理フロー**:
1. **行14-40**: `show`アクション - HTML/JSON形式の分岐、解決可否チェック
2. **行42-50**: `conflict_for_path` - 特定ファイルのコンフリクト取得
3. **行52-74**: `resolve_conflicts` - コンフリクト解決実行
4. **行80-84**: `authorize_can_resolve_conflicts!` - 権限チェックと@conflicts_list設定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | list_service.rb | `app/services/merge_requests/conflicts/list_service.rb` | コンフリクト一覧サービス |
| 2-2 | resolve_service.rb | `app/services/merge_requests/conflicts/resolve_service.rb` | コンフリクト解決サービス |

**主要処理フロー**:
- `ListService`: コンフリクトファイルの取得と解決可否判定
- `ResolveService`: コンフリクト解決とコミット実行

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/projects/merge_requests/conflicts/show.html.haml` | メインビュー（行1-17） |

**主要処理フロー**:
- **行8-9**: MRタイトルのレンダリング
- **行13-16**: Vueコンポーネントのマウントポイント（#conflicts）

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

```
HTTP Request (GET /project/-/merge_requests/:id/conflicts)
    │
    ├─ ConflictsController#show
    │      │
    │      ├─ before_action :authorize_can_resolve_conflicts!
    │      │      └─ ListService.new(@merge_request)
    │      │             └─ can_be_resolved_by?(current_user)
    │      │
    │      └─ respond_to
    │             ├─ format.html → render
    │             └─ format.json → @conflicts_list.to_json
    │
    └─ Vue.js コンポーネント (フロントエンド)

HTTP Request (POST /project/-/merge_requests/:id/resolve_conflicts)
    │
    ├─ ConflictsController#resolve_conflicts
    │      │
    │      ├─ can_be_resolved_in_ui? チェック
    │      │
    │      └─ ResolveService#execute
    │             ├─ コンフリクト解決処理
    │             └─ Git commit
    │
    └─ redirect_to MR詳細
```

### データフロー図

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

MR ID ──────────────▶ ConflictsController#show ──────▶ コンフリクト画面
                          │
                          └─ ListService
                                 └─ can_be_resolved_in_ui?
                                            │
                                            ▼
                               ──────────▶ コンフリクト一覧

解決方法選択 ──────▶ resolve_conflicts ──────────▶ 解決結果
                          │
                          └─ ResolveService#execute
                                 ├─ 各ファイル解決
                                 └─ Git commit
                                            │
                                            ▼
                               ──────────▶ MR詳細画面
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| conflicts_controller.rb | `app/controllers/projects/merge_requests/conflicts_controller.rb` | コントローラー | リクエストハンドリング |
| show.html.haml | `app/views/projects/merge_requests/conflicts/show.html.haml` | ビュー | メインビュー |
| list_service.rb | `app/services/merge_requests/conflicts/list_service.rb` | サービス | コンフリクト一覧 |
| resolve_service.rb | `app/services/merge_requests/conflicts/resolve_service.rb` | サービス | コンフリクト解決 |
| merge_requests.rb | `config/routes/merge_requests.rb` | ルーティング | URL定義 |
