# 画面設計書 40-コミット一覧

## 概要

本ドキュメントは、GitLabのリポジトリ内のコミット履歴を一覧表示する画面（コミット一覧画面）の設計を記述したものである。

### 本画面の処理概要

本画面は、特定のブランチ、タグ、またはパス配下のコミット履歴を一覧表示する画面である。コミットメッセージによる検索、作成者によるフィルタリング、日付範囲指定などの機能を提供し、無限スクロールによる大量コミットの効率的な表示を実現する。

**業務上の目的・背景**：ソースコード管理において、コミット履歴の確認は開発プロセスの重要な部分である。本画面は、変更履歴の追跡、特定の変更の検索、コードレビューの起点として活用される。また、RSSフィードによるコミット通知も提供する。

**画面へのアクセス方法**：
- ファイルツリー画面の「History」ボタンをクリック
- プロジェクトナビゲーションの「Repository > Commits」
- URL直接入力: `/{namespace}/{project}/-/commits/{ref}`

**主要な操作・処理内容**：
1. コミット履歴の一覧表示
2. コミットメッセージによる検索
3. 作成者によるフィルタリング
4. 日付範囲による絞り込み
5. 参照（ブランチ/タグ）の切り替え
6. コミット詳細画面への遷移
7. マージリクエストの作成
8. RSSフィードの購読

**画面遷移**：
- 遷移元: ファイルツリー画面、プロジェクト概要画面、タグ詳細画面
- 遷移先: コミット詳細画面、ファイルツリー画面、マージリクエスト作成画面

**権限による表示制御**：
- リポジトリ読み取り権限がない場合はアクセス拒否
- パス指定時は認証が必要（設定による）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | コミット履歴 | 主機能 | コミット一覧の表示 |
| 40 | マージリクエスト作成 | 遷移先機能 | MR作成画面への遷移 |

## 画面種別

一覧

## URL/ルーティング

```
GET /{namespace}/{project}/-/commits/{ref}
GET /{namespace}/{project}/-/commits/{ref}/{path}
GET /{namespace}/{project}/-/commits/{ref}.atom
```

**ルート定義**: `config/routes/repository.rb`
```ruby
get '/commits' => 'commits#commits_root'
resources :commits, only: [:show]
```

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| namespace | 入力 | String | Yes | プロジェクトの名前空間 |
| project | 入力 | String | Yes | プロジェクト名 |
| ref | 入力 | String | Yes | 参照（ブランチ名/タグ名/コミットSHA） |
| path | 入力 | String | No | ファイル/ディレクトリパス |
| search | 入力 | String | No | コミットメッセージ検索キーワード |
| author | 入力 | String | No | 作成者フィルター |
| limit | 入力 | Integer | No | 取得件数（デフォルト40） |
| offset | 入力 | Integer | No | オフセット |
| committed_before | 入力 | String | No | 日付上限 |
| committed_after | 入力 | String | No | 日付下限 |
| format | 入力 | String | No | 出力形式（html/atom/json） |

## 表示項目

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| コミットSHA | コミットの短縮SHA | commit.short_id |
| コミットメッセージ | コミットのメッセージ | commit.message |
| コミット作成者 | コミットの作成者 | commit.author |
| コミット日時 | コミット作成日時 | commit.committed_date |
| パイプラインステータス | CIパイプラインの状態 | commit.latest_pipeline |
| 署名情報 | コミットの署名状態 | commit.has_signature? |
| 参照切り替え | ブランチ/タグの切り替え | RefSelector |
| パンくずナビ | ファイルパスの階層 | commits_breadcrumbs |
| マージリクエストリンク | 既存MRまたは作成ボタン | @merge_request |

## イベント仕様

### 1-ページ読み込み

コミット一覧を取得し表示する。

**処理フロー**:
1. 参照（ref）の検証
2. パスの検証（存在確認）
3. コミット一覧の取得
4. タグ情報のロード
5. 作成者の遅延ロード
6. パイプラインステータスの取得
7. 関連MRの検索

### 2-参照切り替え

ブランチまたはタグを切り替える。

**処理**: 選択された参照でコミット一覧を再取得

### 3-コミットメッセージ検索

メッセージで検索する。

**処理**: `repository.find_commits_by_message`で検索

### 4-作成者フィルター

特定の作成者のコミットを表示する。

**処理**: `author`パラメータでフィルタリング

### 5-無限スクロール

追加のコミットを読み込む。

**処理**: JSON形式でページネーション

### 6-コミットSHAクリック

コミット詳細画面へ遷移する。

**遷移先**: `/{namespace}/{project}/-/commit/{sha}`

### 7-Browse filesボタン押下

該当参照のファイルツリー画面へ遷移する。

**遷移先**: `/{namespace}/{project}/-/tree/{ref}/{path}`

### 8-Create merge requestボタン押下

マージリクエスト作成画面へ遷移する。

**条件**: 既存のMRがなく、MR作成権限がある場合に表示

### 9-RSSフィードボタン押下

コミットのRSSフィードを表示する。

**遷移先**: `/{namespace}/{project}/-/commits/{ref}.atom`

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

本画面は参照専用であり、データベースの更新は行わない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|----------|
| M001 | 情報 | "No commits found" | 検索結果がない |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|------|---------|---------|
| 403 Forbidden | 読み取り権限なし | アクセス拒否画面表示 |
| 404 Not Found | 参照が存在しない | 404エラー画面表示 |
| 404 Not Found | パスが存在しない | ツリールートへリダイレクト |

## 備考

- デフォルトの取得件数は40件（COMMITS_DEFAULT_LIMIT）
- 無限スクロールでJSON APIを使用して追加コミットを取得
- RSSフィードはセッションレス認証に対応
- コミットの署名情報は別途APIで非同期取得
- Feature Flagにより新UIと旧UIが切り替え可能（project_commits_refactor）
- 曖昧な参照（ブランチとタグで同名）の場合は警告モーダルを表示

---

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

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

### 推奨読解順序

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

コミットオブジェクトと関連データを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | commit.rb | `lib/gitlab/git/commit.rb` | コミットオブジェクト |
| 1-2 | repository.rb | `app/models/repository.rb` | コミット取得メソッド |

**読解のコツ**: コミットはGitリポジトリから直接取得される。`commits`メソッドは様々なフィルタリングオプションを受け付け、`find_commits_by_message`はメッセージ検索に特化している。

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

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

**主要処理フロー**:
1. **11行目**: `COMMITS_DEFAULT_LIMIT = 40` - デフォルト取得件数
2. **12行目**: セッションレス認証（RSS用）
3. **16行目**: 参照変数の割り当て
4. **18行目**: 参照の検証
5. **19行目**: パスの検証
6. **21行目**: コミット一覧の設定
7. **31-49行目**: `def show` - メインアクション
8. **32-33行目**: 関連MRの検索
9. **37-48行目**: HTML/ATOM/JSONレスポンス
10. **88-121行目**: `set_commits` - コミット取得ロジック

#### Step 3: ビューテンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/projects/commits/show.html.haml` | メインテンプレート構造 |
| 3-2 | _commits.html.haml | `app/views/projects/commits/_commits.html.haml` | コミットリストパーシャル |

**主要処理フロー**:
- **1-5行目**: パンくず、スタイル、ページタイトル
- **10-11行目**: RSSフィード自動検出
- **13-14行目**: Feature Flagによる新UI
- **17-52行目**: 旧UI（無限スクロール）
- **22行目**: 参照セレクター（Vue.jsコンポーネント）
- **24-25行目**: パンくずナビ
- **26行目**: 作成者フィルタードロップダウン
- **29行目**: Browse filesボタン
- **30-36行目**: MRリンク/作成ボタン
- **39-40行目**: 検索フォーム
- **42行目**: RSSボタン
- **47-52行目**: 無限スクロールコンテナ
- **55行目**: 曖昧参照警告モーダル

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

```
Projects::CommitsController#show
    │
    ├─ assign_ref_vars (ExtractsPath)
    │      └─ Parse ref and path from URL
    │
    ├─ validate_ref!
    │      └─ valid_ref?(@ref)
    │
    ├─ validate_path
    │      └─ repository.blob_at / repository.tree
    │
    ├─ set_commits
    │      │
    │      ├─ repository.find_commits_by_message (if search)
    │      │
    │      └─ repository.commits (options)
    │             │
    │             ├─ commits.load_tags
    │             │
    │             ├─ commits.lazy_author
    │             │
    │             └─ commits.with_latest_pipeline
    │
    └─ MergeRequestsFinder#execute
           └─ Find existing MR for branch
```

### データフロー図

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

URL Parameters ───▶ CommitsController#show ───▶ HTML/ATOM/JSON Response
  - ref              │
  - path             ├─▶ assign_ref_vars
  - search           │
  - author           ├─▶ validate_ref!
  - limit            │
  - offset           ├─▶ set_commits
  - committed_before │      │
  - committed_after  │      ├─▶ repository.commits
                     │      │      └─▶ Git Repository
                     │      │
                     │      └─▶ load_tags / lazy_author / with_latest_pipeline
                     │
                     └─▶ MergeRequestsFinder
                            └─▶ merge_requests table
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| commits_controller.rb | `app/controllers/projects/commits_controller.rb` | コントローラー | リクエスト処理 |
| show.html.haml | `app/views/projects/commits/show.html.haml` | テンプレート | メインビュー |
| _commits.html.haml | `app/views/projects/commits/_commits.html.haml` | パーシャル | コミットリスト |
| _commit.html.haml | `app/views/projects/commits/_commit.html.haml` | パーシャル | コミット行 |
| 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 | 日付パース |
| repository.rb | `config/routes/repository.rb` | ルーティング | URL定義 |
