# 画面設計書 43-比較結果

## 概要

本ドキュメントは、GitLabの比較結果画面の設計仕様を記載したものである。

### 本画面の処理概要

比較結果画面は、選択された2つのリビジョン（ブランチ、タグ、コミット）間の差分を表示する画面である。コミット一覧と変更されたファイルの差分を確認でき、マージリクエストを作成するためのリンクも提供される。

**業務上の目的・背景**：開発者がブランチ間の変更内容を詳細に確認し、マージ前のレビューやリリース内容の把握を行うために使用する。プルリクエスト/マージリクエストを作成する前に変更範囲を確認する際にも活用される。

**画面へのアクセス方法**：以下のいずれかの方法でアクセス可能
1. 比較画面から「Compare」ボタンを押下
2. ブランチ一覧から「Compare」リンクをクリック
3. 直接URL（`/:namespace/:project/-/compare/:from...:to`）を指定

**主要な操作・処理内容**：
1. コミット一覧の表示（比較範囲内のコミット）
2. 変更ファイルの差分表示
3. 差分表示形式の切り替え（インライン/サイドバイサイド）
4. マージリクエスト作成への遷移
5. コミット署名の確認
6. 差分のダウンロード（diff/patch形式）

**画面遷移**：
- 遷移元: 比較画面、ブランチ一覧
- 遷移先: マージリクエスト新規作成、コミット詳細、ファイル表示

**権限による表示制御**：
- リポジトリ閲覧権限（`read_code`）が必要
- 差分のダウンロードには`read_code`権限が必要

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 22 | 差分表示（Diff） | 主機能 | 比較結果の差分表示 |

## 画面種別

詳細

## URL/ルーティング

```
GET /:namespace/:project/-/compare/:from...:to (3ドット比較)
GET /:namespace/:project/-/compare/:from..:to (2ドット比較)
GET /:namespace/:project/-/compare (POST結果としてリダイレクト)
GET /:namespace/:project/-/compare/diff_for_path
GET /:namespace/:project/-/compare/signatures (JSON)
```

## 入出力項目

| 項目名 | I/O | 型 | 必須 | 説明 |
|--------|-----|-----|------|------|
| from | 入力 | String | 必須 | ソースリビジョン |
| to | 入力 | String | 必須 | ターゲットリビジョン |
| from_project_id | 入力 | Integer | 任意 | フォーク元プロジェクトID |
| straight | 入力 | String | 任意 | 2ドット比較フラグ |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| リビジョンセレクター | Component | ソース/ターゲットの再選択 |
| コミット一覧 | Array | 比較範囲内のコミット |
| コミット署名 | Object | 各コミットの署名状態 |
| 差分統計 | Object | 追加/削除行数のサマリー |
| 変更ファイル一覧 | Array | 変更されたファイルの差分 |
| MR作成リンク | Link | 既存MRまたは新規作成リンク |
| 差分表示切り替え | Toggle | インライン/サイドバイサイド |

## イベント仕様

### 1-MR作成ボタン押下

既存のMRが存在する場合はそのMRへ遷移、存在しない場合はMR新規作成画面へ遷移する。

### 2-コミットクリック

コミット詳細画面（`/:namespace/:project/-/commit/:sha`）へ遷移する。

### 3-差分表示切り替え

`apply_diff_view_cookie!`によりCookieに設定を保存し、インライン/サイドバイサイド表示を切り替える。

### 4-Downloadボタン押下

- diff形式: `format: :diff`でレスポンスを取得
- patch形式: `format: :patch`でレスポンスを取得

### 5-署名表示

JavaScriptでsignaturesエンドポイントを呼び出し、各コミットの署名状態を非同期で取得・表示する。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 比較表示 | なし | SELECT | Gitリポジトリからの読み取りのみ |

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

本画面ではデータベースへの書き込み操作は発生しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 表示条件 |
|-------------|------|-----------|----------|
| MSG-001 | 情報 | "There isn't anything to compare" | from/toが同一の場合 |
| MSG-002 | 情報 | "{source} and {target} are the same." | from/toが同一の場合（詳細） |
| MSG-003 | 情報 | "To get a valid comparison, select two different branches." | 比較不可時 |

## 例外処理

| 例外状態 | 処理内容 |
|---------|----------|
| リビジョンが存在しない | 404 Not Foundを返却 |
| from/toが同一 | 空状態メッセージを表示 |
| 権限不足 | 403 Forbiddenを返却 |

## 備考

- Rapid Diffs機能が有効な場合、`RapidDiffs::ComparePresenter`を使用した新しい差分表示UIが適用される
- コミット数が`MergeRequestDiff::COMMITS_SAFE_SIZE`未満の場合のみパイプライン情報を取得
- 差分表示は全幅レイアウト（`@no_container = true`）

---

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

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

### 推奨読解順序

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

比較処理の結果オブジェクトを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | compare.rb | `lib/gitlab/git/compare.rb` | Git比較の基本構造 |
| 1-2 | compare_service.rb | `app/services/compare_service.rb` | 比較サービスの実装 |

**読解のコツ**: `Compare`オブジェクトはコミット一覧と差分情報を保持する。

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

コントローラーの`show`アクションが処理の起点。

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

**主要処理フロー**:
1. **行32-53**: showアクション
2. **行142-146**: compare メソッド（CompareService呼び出し）
3. **行162-177**: コミット一覧の取得

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/projects/compare/show.html.haml` | メインビュー |
| 3-2 | _commit_list.html.haml | `app/views/projects/commits/_commit_list.html.haml` | コミット一覧 |

**主要処理フロー**:
- **行13-17**: 差分が存在する場合のコミット一覧と差分表示
- **行19-32**: 差分が存在しない場合の空状態表示

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

```
CompareController#show
    │
    ├─ before_action :define_commits
    │      ├─ compare.commits
    │      └─ limited_commits()
    │
    ├─ before_action :define_environment
    │      └─ EnvironmentsByDeploymentsFinder
    │
    └─ render "show"
           ├─ render "_commit_list"
           └─ render RapidDiffs::AppComponent (or _diffs)
```

### データフロー図

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

from/to params ───▶ CompareController#show ───▶ HTML Response
                           │
                           ├─▶ CompareService#execute()
                           │       └─▶ Compare Object
                           │
                           ├─▶ compare.commits
                           │       └─▶ Commit Array
                           │
                           └─▶ compare.diffs
                                   └─▶ Diff Collection
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| compare_controller.rb | `app/controllers/projects/compare_controller.rb` | コントローラー | リクエスト処理 |
| show.html.haml | `app/views/projects/compare/show.html.haml` | テンプレート | メインビュー |
| compare_service.rb | `app/services/compare_service.rb` | サービス | 比較処理 |
| compare.rb | `lib/gitlab/git/compare.rb` | ライブラリ | Git比較 |
| repository.rb | `config/routes/repository.rb` | ルーティング | URL定義 |
| rapid_diffs/compare_presenter.rb | `app/presenters/rapid_diffs/compare_presenter.rb` | プレゼンター | 差分表示 |
