# 画面設計書 42-比較画面

## 概要

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

### 本画面の処理概要

比較画面は、2つのブランチ、タグ、またはコミット間の比較対象を選択するための画面である。ユーザーはソース（from）とターゲット（to）を指定し、差分を確認するための比較を開始できる。

**業務上の目的・背景**：ソフトウェア開発において、異なるブランチやコミット間の変更内容を把握することは、マージ前のレビュー、リリース内容の確認、デバッグにおいて重要である。本画面は、比較対象を柔軟に選択できるインターフェースを提供し、開発者が効率的にコード変更を追跡できるようにする。

**画面へのアクセス方法**：以下のいずれかの方法でアクセス可能
1. リポジトリメニューから「Compare」を選択
2. ブランチ一覧画面から「Compare」リンクをクリック
3. 直接URL（`/:namespace/:project/-/compare`）を指定

**主要な操作・処理内容**：
1. ソースブランチ/タグ/コミットの選択（from）
2. ターゲットブランチ/タグ/コミットの選択（to）
3. フォークプロジェクトの選択（from_project）
4. 比較方式の選択（3ドット/2ドット比較）
5. 「Compare」ボタンで比較結果画面へ遷移

**画面遷移**：
- 遷移元: ファイルツリー、ブランチ一覧、コミット一覧
- 遷移先: 比較結果画面

**権限による表示制御**：
- リポジトリ閲覧権限（`read_code`）が必要
- フォークプロジェクトの選択には、対象プロジェクトの閲覧権限が必要

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 22 | 差分表示（Diff） | 主機能 | ブランチ・タグ間の比較設定 |

## 画面種別

設定・検索

## URL/ルーティング

```
GET /:namespace/:project/-/compare
POST /:namespace/:project/-/compare
GET /:namespace/:project/-/compare/target_projects (JSON)
```

## 入出力項目

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

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Source（from）セレクター | Dropdown | ソースリビジョン選択 |
| Target（to）セレクター | Dropdown | ターゲットリビジョン選択 |
| プロジェクトセレクター | Dropdown | フォークプロジェクト選択（該当する場合） |
| 比較方式切り替え | Toggle | 3ドット/2ドット比較の切り替え |
| 既存MRリンク | Link | 同じブランチ間のMRが存在する場合に表示 |

## イベント仕様

### 1-Compareボタン押下

1. fromとtoの値を検証
2. 両方が入力されている場合、比較結果画面へリダイレクト
3. いずれかが未入力の場合、エラーメッセージを表示
4. `straight`パラメータに応じて3ドットまたは2ドット比較URLを生成

### 2-ソース/ターゲットセレクター変更

JavaScriptコンポーネント（`#js-compare-selector`）が動的にリビジョンを取得・表示する。

### 3-プロジェクトセレクター変更

フォークプロジェクトが選択された場合、そのプロジェクトのブランチ・タグが選択肢として表示される。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Compare実行 | なし | SELECT | 比較情報の取得のみ |

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 表示条件 |
|-------------|------|-----------|----------|
| MSG-001 | エラー | "You must select a Source and a Target revision" | from/toが未選択時 |
| MSG-002 | エラー | "Invalid branch name(s): {names}" | 不正なリビジョン名指定時 |

## 例外処理

| 例外状態 | 処理内容 |
|---------|----------|
| 権限不足 | 403 Forbiddenを返却 |
| プロジェクトが存在しない | 404 Not Foundを返却 |
| 不正なブランチ名 | エラーメッセージを表示し、比較画面にリダイレクト |

## 備考

- 3ドット比較（デフォルト）: 共通祖先からの変更を表示
- 2ドット比較: 直接的な差分を表示
- フォークからのプロジェクト間比較に対応

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | compare_service.rb | `app/services/compare_service.rb` | 比較処理のサービスクラス |

**読解のコツ**: `CompareService`が2つのリビジョン間の比較を行い、差分情報を返す。

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

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

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

**主要処理フロー**:
1. **行14-15**: 権限チェック
2. **行23**: バリデーション
3. **行28-30**: indexアクション
4. **行62-74**: createアクション（リダイレクト処理）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/projects/compare/index.html.haml` | メインビュー |

**主要処理フロー**:
- **行5**: JavaScriptコンポーネント`#js-compare-selector`のマウント

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

```
CompareController#index
    │
    └─ render "index"
           └─ #js-compare-selector (Vue component)
                  └─ project_compare_selector_data()

CompareController#create
    │
    ├─ build_from_to_vars()
    │
    └─ redirect_to project_compare_path or project_compare_index_path
```

### データフロー図

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

from/to params ───▶ CompareController#create ───▶ Redirect to show
                           │
                           ├─▶ validate_refs!()
                           │       └─▶ valid_ref?()
                           │
                           └─▶ build_from_to_vars()
                                   └─▶ URL params
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| compare_controller.rb | `app/controllers/projects/compare_controller.rb` | コントローラー | リクエスト処理 |
| index.html.haml | `app/views/projects/compare/index.html.haml` | テンプレート | メインビュー |
| compare_service.rb | `app/services/compare_service.rb` | サービス | 比較処理 |
| repository.rb | `config/routes/repository.rb` | ルーティング | URL定義 |
| compare_helper.rb | `app/helpers/compare_helper.rb` | ヘルパー | ビューヘルパー |
