# 画面設計書 34-Blame表示

## 概要

本ドキュメントは、GitLabのリポジトリ内ファイルのBlame情報（行ごとの変更履歴）を表示する画面（Blame表示画面）の設計を記述したものである。

### 本画面の処理概要

本画面は、ファイルの各行がいつ、誰によって、どのコミットで変更されたかを表示するBlame機能を提供する。コードレビュー、バグ調査、変更履歴の追跡において重要な役割を果たし、特定の行の変更理由やコンテキストを理解するのに役立つ。

**業務上の目的・背景**：ソフトウェア開発において、特定のコード行がなぜそのように書かれたのかを理解することは非常に重要である。本画面は、各行の最終変更者、変更日時、関連コミットを一覧表示することで、コードの経緯を把握し、バグの原因特定や変更の影響範囲の理解を支援する。また、.git-blame-ignore-revsファイルを使用して、コードフォーマット変更などのノイズを除外する機能も提供する。

**画面へのアクセス方法**：
- ファイル表示画面の「Blame」ボタンをクリック
- URL直接入力: `/{namespace}/{project}/-/blame/{ref}/{path}`
- コミット詳細画面からのリンク

**主要な操作・処理内容**：
1. ファイル各行のBlame情報表示（コミットSHA、著者、日時）
2. 色分けによる変更時期の可視化（新しい/古い）
3. コミット詳細へのリンク
4. ページネーションまたはストリーミング表示
5. .git-blame-ignore-revs対応
6. 全Blame表示オプション

**画面遷移**：
- 遷移元: ファイル表示画面、コミット詳細画面
- 遷移先: コミット詳細画面、ファイル表示画面、ユーザープロフィール画面

**権限による表示制御**：
- リポジトリ読み取り権限がない場合はアクセス拒否
- バイナリファイルの場合はBlame表示不可

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 23 | Blame表示 | 主機能 | ファイルの行ごとの変更履歴表示 |
| 21 | コミット閲覧 | 遷移先機能 | コミット詳細画面への遷移 |
| 15 | ファイル閲覧 | 遷移先機能 | ファイル表示画面への遷移 |

## 画面種別

詳細

## URL/ルーティング

```
GET /{namespace}/{project}/-/blame/{ref}/{*path}
GET /{namespace}/{project}/-/blame/{ref}/{*path}/streaming
GET /{namespace}/{project}/-/blame_page/{ref}/{*path}
```

**ルート定義**: `config/routes/repository.rb`
```ruby
get '/blame_page/*id', to: 'blame#page', as: :blame_page
get '/blame/*id/streaming', to: 'blame#streaming', as: :blame_streaming, defaults: { streaming: true }
get '/blame/*id', to: 'blame#show', as: :blame
```

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| namespace | 入力 | String | Yes | プロジェクトの名前空間 |
| project | 入力 | String | Yes | プロジェクト名 |
| ref | 入力 | String | Yes | ブランチ名/タグ名/コミットSHA |
| path | 入力 | String | Yes | ファイルパス |
| page | 入力 | Integer | No | ページ番号（ページネーション時） |
| no_pagination | 入力 | Boolean | No | ページネーション無効化フラグ |
| streaming | 入力 | Boolean | No | ストリーミングモードフラグ |
| ignore_revs | 入力 | Boolean | No | .git-blame-ignore-revs使用フラグ |

## 表示項目

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| ファイルパス | 表示中のファイルパス | @blob.path |
| ブランチ/タグ名 | 現在の参照 | @ref |
| Blame凡例 | 新しい/古いの色分け説明 | 固定表示 |
| 行番号 | ファイルの行番号 | @blame |
| コード行 | ファイルの各行内容 | @blob.data |
| コミットSHA | 変更したコミットの短縮SHA | blame.commit.short_id |
| 著者名 | 変更した著者 | blame.commit.author_name |
| 変更日時 | コミット日時 | blame.commit.authored_date |
| 変更時期インジケータ | 色分けバー（0-9段階） | 計算値 |

## イベント仕様

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

Blame情報を取得し表示する。

**処理フロー**:
1. URLからref、pathを抽出
2. ファイルの存在確認
3. バイナリファイルチェック（バイナリは非対応）
4. Blameモードとページネーションの設定
5. Gitlab::Blameでblame情報を取得
6. Presenterで表示用データに変換

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

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

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

### 3-著者名クリック

著者のユーザープロフィール画面へ遷移する。

**遷移先**: `/{username}`

### 4-Show full blameボタン押下

ページネーションなしで全Blameを表示する。

**処理**: `no_pagination=true`パラメータでリロード

### 5-ページネーション操作

別ページのBlame情報を取得する。

**処理**: `page`パラメータを更新してリクエスト

### 6-ストリーミング表示

大きなファイルの場合、段階的にBlame情報を読み込む。

**処理**: Fetch APIでストリーミングデータを取得

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Blame表示 | - | SELECT | データベース更新なし（Gitリポジトリから直接読み取り） |

本画面は参照専用であり、データベースへの書き込みは発生しない。Blame情報はGitリポジトリから直接計算される。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|----------|
| M001 | 情報 | "Blame for binary files is not supported." | バイナリファイルでアクセス時 |
| M002 | 情報 | "Loading full blame..." | ストリーミング読み込み中 |
| M003 | 警告 | "Malformed .git-blame-ignore-revs" | ignore-revsファイル形式エラー |
| M004 | 警告 | ".git-blame-ignore-revs is not a file" | ignore-revsがファイルでない |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|------|---------|---------|
| 404 Not Found | ファイルが存在しない | 404エラーページ表示 |
| 403 Forbidden | 読み取り権限なし | アクセス拒否画面表示 |
| バイナリファイル | テキスト以外のファイル | ファイル表示画面へリダイレクト |
| IgnoreRevsFormatError | ignore-revsファイル形式不正 | 警告表示してリダイレクト |
| IgnoreRevsFileError | ignore-revsがファイルでない | 警告表示してリダイレクト |

## 備考

- 大きなファイルではストリーミングモードが自動的に有効化される
- 色分けは10段階（legend-box-0〜9）で、新しいほど明るい色
- .git-blame-ignore-revsファイルでフォーマット変更等のコミットを除外可能
- パフォーマンス最適化のためページネーションがデフォルト

---

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

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

### 推奨読解順序

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

Blame情報の構造とページネーションの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | blame.rb | `lib/gitlab/blame.rb` | Blameクラスの基本構造 |
| 1-2 | blame_mode.rb | `lib/gitlab/git/blame_mode.rb` | 表示モード（pagination/streaming） |
| 1-3 | blame_pagination.rb | `lib/gitlab/git/blame_pagination.rb` | ページネーションロジック |

**読解のコツ**: Blame表示には3つのモード（pagination、streaming、full）があり、ファイルサイズとユーザー設定により自動選択される。

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

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

**主要処理フロー**:
1. **17-25行目**: `def show` - メインアクション、例外処理
2. **40-47行目**: `load_blob` - ファイル読み込みと存在確認
3. **49-53行目**: `require_non_binary_blob` - バイナリチェック
4. **66-81行目**: `load_blame` - Blame情報の取得とPresenter作成

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/projects/blame/show.html.haml` | メインテンプレート構造 |
| 3-2 | _page.html.haml | `app/views/projects/blame/_page.html.haml` | Blame行表示パーシャル |

**主要処理フロー**:
- **6-14行目**: ストリーミングモード時のJavaScript初期化
- **23-38行目**: 色分け凡例の表示
- **42-43行目**: Blameテーブル本体
- **46-47行目**: ストリーミングコンテナ
- **49-52行目**: 全Blame表示ボタン
- **61-62行目**: ページネーション

#### Step 4: Blameロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | blame.rb | `lib/gitlab/blame.rb` | Blameデータ取得ロジック |
| 4-2 | blame_presenter.rb | `app/presenters/blame_presenter.rb` | 表示用データ変換 |

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

```
Projects::BlameController#show
    │
    ├─ assign_ref_vars (ExtractsPath)
    │
    ├─ load_blob
    │      └─ @repository.blob_at(@commit.id, @path)
    │
    ├─ require_non_binary_blob
    │      └─ redirect_to blob_path (if binary)
    │
    ├─ load_environment
    │      └─ Environments::EnvironmentsByDeploymentsFinder
    │
    └─ load_blame
           ├─ Gitlab::Git::BlameMode.new
           ├─ Gitlab::Git::BlamePagination.new
           ├─ Gitlab::Blame.new
           │      └─ Git blame calculation
           └─ Gitlab::View::Presenter::Factory
                  └─ BlamePresenter
```

### データフロー図

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

URL Parameters ───▶ BlameController#show ───▶ HTML Response
  - ref                │
  - path               ├─▶ Repository.blob_at ───▶ Blob Object
  - page               │
  - streaming          ├─▶ Gitlab::Blame ───▶ Blame Data
                       │      │
                       │      └─▶ Git Repository (git blame)
                       │
                       └─▶ BlamePresenter ───▶ View Data
                              │
                              └─▶ Color calculation (age)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| blame_controller.rb | `app/controllers/projects/blame_controller.rb` | コントローラー | リクエスト処理 |
| show.html.haml | `app/views/projects/blame/show.html.haml` | テンプレート | メインビュー |
| _page.html.haml | `app/views/projects/blame/_page.html.haml` | パーシャル | Blame行表示 |
| blame.rb | `lib/gitlab/blame.rb` | ライブラリ | Blame計算ロジック |
| blame_mode.rb | `lib/gitlab/git/blame_mode.rb` | ライブラリ | 表示モード管理 |
| blame_pagination.rb | `lib/gitlab/git/blame_pagination.rb` | ライブラリ | ページネーション |
| blame_presenter.rb | `app/presenters/blame_presenter.rb` | プレゼンター | 表示用データ変換 |
| repository.rb | `config/routes/repository.rb` | ルーティング | URL定義 |
