# 機能設計書 21-コミット閲覧

## 概要

本ドキュメントは、GitLabにおけるコミット閲覧機能の設計を定義する。Gitリポジトリのコミット履歴表示、個別コミットの詳細表示、及び署名検証機能を含む。

### 本機能の処理概要

コミット閲覧機能は、Gitリポジトリ内のコミット履歴を一覧表示し、各コミットの詳細情報（変更内容、作者、日時など）を確認できる機能である。

**業務上の目的・背景**：ソフトウェア開発において、コードの変更履歴を追跡することは品質管理とデバッグの基礎である。本機能により、開発者はいつ・誰が・何のために変更を行ったかを把握し、問題発生時の原因特定やコードレビューを効率的に行える。また、プロジェクトの進捗状況や開発パターンの可視化にも活用される。

**機能の利用シーン**：
- デバッグ時に特定のバグが混入したコミットを特定する
- コードレビュー時に変更履歴を確認する
- プロジェクトの開発進捗を確認する
- 特定の機能がいつ実装されたかを調査する
- マージリクエスト作成前にコミット履歴を確認する

**主要な処理内容**：
1. 指定されたブランチ・タグ・コミットSHAのコミット履歴を取得
2. ページネーションによる大量コミットの分割表示
3. 作者、日付、メッセージ等によるフィルタリング
4. コミット署名（GPG/SSH）の検証と表示
5. 関連するパイプライン情報の表示
6. RSS/Atomフィード形式でのコミット履歴提供

**関連システム・外部連携**：Gitalyサーバーとの連携によるGitリポジトリアクセス、CI/CDパイプラインとの連携（コミットに紐づくパイプライン状態表示）

**権限による制御**：リポジトリへの読み取り権限（read_code）が必要。プライベートプロジェクトではプロジェクトメンバーまたは適切な権限を持つユーザーのみアクセス可能。特定のフィーチャーフラグ（require_login_for_commit_tree）が有効な場合、パス指定時は認証必須となる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 40 | コミット一覧 | 主機能 | コミット履歴の一覧表示 |
| 41 | コミット詳細 | 主機能 | 個別コミットの詳細表示 |

## 機能種別

データ参照・表示処理（SELECT）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ref | String | Yes | ブランチ名、タグ名、またはコミットSHA | 有効なGit参照である必要がある |
| path | String | No | 特定のファイル/ディレクトリパスでフィルタ | リポジトリ内に存在するパス |
| limit | Integer | No | 取得するコミット数（デフォルト40） | 正の整数のみ |
| offset | Integer | No | 取得開始位置（デフォルト0） | 0以上の整数 |
| search | String | No | コミットメッセージでの検索文字列 | - |
| author | String | No | 作者によるフィルタ | - |
| committed_before | Date | No | 指定日以前のコミット | 有効な日付形式 |
| committed_after | Date | No | 指定日以降のコミット | 有効な日付形式 |

### 入力データソース

- URL パス: `/project_namespace/project_name/-/commits/:ref`
- クエリパラメータによるフィルタリング条件

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| commits | Array<Commit> | コミットオブジェクトの配列 |
| commit.sha | String | コミットのSHAハッシュ（40文字） |
| commit.title | String | コミットメッセージの1行目 |
| commit.message | String | コミットメッセージ全文 |
| commit.author_name | String | 作者の名前 |
| commit.author_email | String | 作者のメールアドレス |
| commit.authored_date | DateTime | 作成日時 |
| commit.committer_name | String | コミッターの名前 |
| commit.committed_date | DateTime | コミット日時 |
| commit.signature | Object | 署名情報（存在する場合） |
| commit.pipeline | Object | 関連パイプライン情報 |

### 出力先

- HTML: ブラウザへのレンダリング
- JSON: Ajax リクエストへのレスポンス
- Atom: RSS リーダー向けフィード

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信・認証確認
   └─ authenticate_sessionless_user!（Atomフィード用）
2. プロジェクト・参照の検証
   └─ require_non_empty_project, validate_ref!
3. パス存在確認（パス指定時）
   └─ validate_path でファイル/ディレクトリの存在確認
4. 認証要求判定（パス指定時）
   └─ auth_for_path で認証状態確認
5. コミット一覧取得
   └─ set_commits でGitalyからコミット取得
6. 関連データの事前読み込み
   └─ タグ情報、作者情報、パイプライン情報のプリロード
7. レスポンス形式に応じた出力
   └─ HTML/JSON/Atom形式でレンダリング
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{プロジェクトが空?}
    B -->|Yes| C[404エラー]
    B -->|No| D{参照が有効?}
    D -->|No| C
    D -->|Yes| E{パス指定あり?}
    E -->|Yes| F{パスが存在?}
    F -->|No| G[ルートにリダイレクト]
    F -->|Yes| H{認証必要?}
    E -->|No| I[コミット取得]
    H -->|Yes| J{認証済み?}
    J -->|No| K[ログインページ]
    J -->|Yes| I
    H -->|No| I
    I --> L[関連データ読み込み]
    L --> M{レスポンス形式}
    M -->|HTML| N[HTML出力]
    M -->|JSON| O[JSON出力]
    M -->|Atom| P[Atom出力]
    N --> Q[終了]
    O --> Q
    P --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-21-01 | デフォルト表示件数 | 1ページあたり40件のコミットを表示 | limitパラメータ未指定時 |
| BR-21-02 | 参照検証 | 無効な参照に対しては404を返す | 常時 |
| BR-21-03 | パス検証 | 存在しないパスはルートにリダイレクト | パス指定時 |
| BR-21-04 | 認証要求 | パス指定時は認証を要求可能（フィーチャーフラグ） | require_login_for_commit_tree有効時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| コミット取得 | - | - | Gitalyから直接取得（DBアクセスなし） |
| MR検索 | merge_requests | SELECT | ソースブランチに関連するMRを検索 |
| タグ取得 | - | - | Gitalyから直接取得 |
| パイプライン取得 | ci_pipelines | SELECT | コミットに紐づくパイプライン情報 |

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

#### merge_requests

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | source_branch, target_branch等 | source_project=current_project, source_branch=ref, target_branch=root_ref | オープン状態のMRのみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | NotFound | プロジェクトが空の場合 | エラーページ表示 |
| 404 | NotFound | 無効な参照の場合 | エラーページ表示 |
| 302 | Redirect | パスが存在しない場合 | ルートにリダイレクト |
| 401 | Unauthorized | 認証が必要なアクセス | ログインページへリダイレクト |

### リトライ仕様

特になし（読み取り専用操作）

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

読み取り専用のため、トランザクション管理は不要

## パフォーマンス要件

- デフォルトの40件表示は1秒以内にレスポンス
- Gitalyキャッシュ（allow_gitaly_ref_name_caching）を活用
- 作者情報の遅延読み込み（lazy_author）によるN+1クエリ回避
- パイプライン情報のバッチ取得（with_latest_pipeline）

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

- authorize_read_code! による読み取り権限の確認
- セッションレス認証のサポート（RSS用トークン認証）
- フィーチャーフラグによる追加認証要求機能
- コミット署名の検証と表示

## 備考

- バイナリファイルのコミット差分は内容非表示
- 大量のコミット履歴はページネーションで分割
- コミットに紐づくタグ情報も併せて表示

---

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

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

### 推奨読解順序

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

コミット情報を扱うための基本的なデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | commit.rb | `lib/gitlab/git/commit.rb` | Gitコミットのラッパークラス、属性定義 |
| 1-2 | commit.rb | `app/models/commit.rb` | アプリケーション層でのコミットモデル |

**読解のコツ**: Gitalyから取得した生のコミットデータがどのようにRubyオブジェクトとして扱われるかを理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | commits_controller.rb | `app/controllers/projects/commits_controller.rb` | コントローラーの主要アクション |

**主要処理フロー**:
1. **26-28行目**: commits_root - デフォルトブランチへのリダイレクト
2. **31-49行目**: show - コミット一覧表示のメインアクション
3. **52-65行目**: signatures - コミット署名情報のJSON取得
4. **88-121行目**: set_commits - コミット一覧の取得・フィルタリング処理

#### Step 3: フィルタリング処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parse_commit_date.rb | `app/controllers/concerns/parse_commit_date.rb` | 日付パラメータの変換処理 |
| 3-2 | extracts_path.rb | `app/controllers/concerns/extracts_path.rb` | パス・参照の抽出処理 |
| 3-3 | renders_commits.rb | `app/controllers/concerns/renders_commits.rb` | コミット描画用ヘルパー |

**主要処理フロー**:
- **94-95行目**: convert_date_to_epoch - 日付文字列をUNIXエポックに変換

#### Step 4: リポジトリアクセスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | repository.rb | `app/models/repository.rb` | リポジトリのコミット取得メソッド |

**主要処理フロー**:
- commits メソッド - 通常のコミット取得
- find_commits_by_message メソッド - メッセージ検索でのコミット取得

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

```
CommitsController#show
    │
    ├─ ExtractsPath#assign_ref_vars
    │      └─ Repository#find_branch / find_tag
    │
    ├─ validate_ref!
    │      └─ valid_ref? - 参照の有効性確認
    │
    ├─ validate_path
    │      └─ Repository#blob_at / tree
    │
    ├─ set_commits
    │      ├─ Repository#commits
    │      │      └─ Gitaly::CommitService
    │      ├─ Repository#find_commits_by_message（検索時）
    │      │      └─ Gitaly::CommitService
    │      ├─ Commit#load_tags
    │      ├─ Commit#lazy_author
    │      └─ with_markdown_cache / with_latest_pipeline
    │
    └─ respond_to (HTML/JSON/Atom)
```

### データフロー図

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

URL パラメータ    ───▶  CommitsController       ───▶  HTML/JSON/Atom
(ref, path等)           │
                        ▼
                   ExtractsPath
                   (参照解決)
                        │
                        ▼
                   Repository#commits
                        │
                        ▼
                   Gitaly Server ──────────────────▶  コミット一覧
                   (Git操作)
                        │
                        ▼
                   Commit#with_latest_pipeline ────▶  パイプライン情報
                   (DB照会)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| commits_controller.rb | `app/controllers/projects/commits_controller.rb` | コントローラー | コミット閲覧のエントリーポイント |
| extracts_path.rb | `app/controllers/concerns/extracts_path.rb` | Concern | パス・参照の抽出 |
| renders_commits.rb | `app/controllers/concerns/renders_commits.rb` | Concern | コミット描画ヘルパー |
| parse_commit_date.rb | `app/controllers/concerns/parse_commit_date.rb` | Concern | 日付パースユーティリティ |
| commit.rb | `app/models/commit.rb` | モデル | コミットのアプリケーションモデル |
| repository.rb | `app/models/repository.rb` | モデル | リポジトリアクセス |
| _commits.html.haml | `app/views/projects/commits/_commits.html.haml` | ビュー | コミット一覧表示テンプレート |
| show.html.haml | `app/views/projects/commits/show.html.haml` | ビュー | コミット一覧ページテンプレート |
| show.atom.builder | `app/views/projects/commits/show.atom.builder` | ビュー | Atomフィードテンプレート |
