# 機能設計書 23-git_prompt_status

## 概要

本ドキュメントは、Oh My Zshの`git_prompt_status`関数の機能設計を定義するものである。この関数は、Gitリポジトリの詳細なステータス情報（未追跡、追加、変更、削除、マージ、ahead/behind等）をプロンプト表示用のアイコン/文字列として出力する機能を提供する。

### 本機能の処理概要

`git_prompt_status`関数は、`git status --porcelain -b`コマンドの出力を解析し、各種ステータスに対応するテーマ変数のアイコンを組み合わせたプロンプト文字列を生成する。

**業務上の目的・背景**：開発者がターミナルで作業する際、単にブランチ名だけでなく、ワーキングツリーの詳細な状態（どのような変更があるか）を把握することは重要である。この関数により、未追跡ファイル、ステージ済み変更、削除ファイル、マージコンフリクト、リモートとの差分などを視覚的に確認できる。

**機能の利用シーン**：
- プロンプトにGitの詳細ステータスを表示したい場合
- 未追跡ファイルやステージ済み変更の有無を素早く確認したい場合
- リモートブランチとの差分（ahead/behind）を常に把握したい場合
- stashの存在を確認したい場合

**主要な処理内容**：
1. `oh-my-zsh.hide-status`設定による非表示制御をチェック
2. `git status --porcelain -b`コマンドでステータス情報を取得
3. stashの存在をチェック
4. ブランチ行からahead/behind/diverged情報を解析
5. 各ファイルのステータスプレフィックスを解析
6. テーマ変数を使用してステータスアイコンを構築して出力

**関連システム・外部連携**：
- Gitコマンド（`git status`、`git rev-parse --verify refs/stash`）
- 非同期プロンプトシステム（`_omz_register_handler`）との統合

**権限による制御**：特になし。Gitリポジトリへのアクセス権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | シェルプロンプト | 主画面 | プロンプト表示時にGitステータスを出力 |

## 機能種別

情報取得・フォーマット処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | この関数は引数を取らない | - |

### 入力データソース

- カレントディレクトリのGitリポジトリ情報
- テーマ変数（`ZSH_THEME_GIT_PROMPT_UNTRACKED`、`ZSH_THEME_GIT_PROMPT_ADDED`等）
- Git設定（`oh-my-zsh.hide-status`）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ステータス文字列 | 文字列 | 各ステータスに対応するアイコンを連結した文字列 |

### 出力先

標準出力（プロンプト表示用）

### ステータス種別と対応するテーマ変数

| ステータス | Gitプレフィックス | テーマ変数 |
|-----------|-------------------|------------|
| 未追跡 | `?? ` | `ZSH_THEME_GIT_PROMPT_UNTRACKED` |
| 追加済み | `A  ` | `ZSH_THEME_GIT_PROMPT_ADDED` |
| 変更あり | `M  `, `MM `, ` M `, `AM `, ` T ` | `ZSH_THEME_GIT_PROMPT_MODIFIED` |
| 名前変更 | `R  ` | `ZSH_THEME_GIT_PROMPT_RENAMED` |
| 削除 | ` D `, `D  ` | `ZSH_THEME_GIT_PROMPT_DELETED` |
| マージ未解決 | `UU ` | `ZSH_THEME_GIT_PROMPT_UNMERGED` |
| ahead | ブランチ行の`ahead N` | `ZSH_THEME_GIT_PROMPT_AHEAD` |
| behind | ブランチ行の`behind N` | `ZSH_THEME_GIT_PROMPT_BEHIND` |
| diverged | ahead かつ behind | `ZSH_THEME_GIT_PROMPT_DIVERGED` |
| stash有り | refs/stash存在時 | `ZSH_THEME_GIT_PROMPT_STASHED` |

## 処理フロー

### 処理シーケンス

```
1. 非表示設定チェック
   └─ oh-my-zsh.hide-status が1の場合は何も出力しない
2. git status --porcelain -b でステータス情報を取得
   └─ 取得失敗（コード128）の場合はエラーリターン
3. stashの存在チェック
   └─ git rev-parse --verify refs/stash
4. ブランチ行の解析
   └─ ahead/behind/diverged情報を抽出
5. ファイルステータスの解析
   └─ 各行のプレフィックスをチェック
6. ステータス定数に基づいてアイコン文字列を構築
   └─ 決められた順序でアイコンを連結
7. 結果を出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始: git_prompt_status] --> B{hide-status=1?}
    B -->|Yes| C[何も出力せず終了]
    B -->|No| D[git status --porcelain -b 実行]
    D --> E{終了コード=128?}
    E -->|Yes| F[エラーリターン]
    E -->|No| G[refs/stash存在チェック]
    G --> H{stash存在?}
    H -->|Yes| I[STASHED=1を記録]
    H -->|No| J[ブランチ行を解析]
    I --> J
    J --> K{ahead/behind情報あり?}
    K -->|Yes| L[ahead/behind/diverged情報を記録]
    K -->|No| M[各ファイル行を解析]
    L --> M
    M --> N[ステータスプレフィックスを正規表現でマッチ]
    N --> O[対応するステータスを記録]
    O --> P[ステータス定数の順序でアイコンを連結]
    P --> Q[結果を出力]
    Q --> R[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-23-01 | 非表示制御 | `oh-my-zsh.hide-status=1`の場合は何も出力しない | hide-status設定時 |
| BR-23-02 | ステータス表示順序 | UNTRACKED, ADDED, MODIFIED, RENAMED, DELETED, STASHED, UNMERGED, AHEAD, BEHIND, DIVERGEDの順で表示 | 常時 |
| BR-23-03 | 重複排除 | 同じステータスは1回のみ表示（複数ファイルに同じステータスがあっても） | 常時 |
| BR-23-04 | diverged判定 | aheadかつbehindの場合はDIVERGEDとして扱う | ahead > 0 かつ behind > 0 |

### 計算ロジック

該当なし

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

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

該当なし（データベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 128 | 致命的エラー | Gitリポジトリでない、または重大なエラー | 戻り値1で終了 |

### リトライ仕様

リトライ機能なし

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

該当なし

## パフォーマンス要件

- `GIT_OPTIONAL_LOCKS=0`を設定してGitコマンドを実行し、ロック競合を回避
- 非同期プロンプトモードでの実行をサポートし、プロンプト表示の遅延を防止

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

- 読み取り専用のGit操作のみを実行
- `GIT_OPTIONAL_LOCKS=0`によりファイルロックを取得しない

## 備考

- zsh 5.0.6以上では非同期プロンプトモードがデフォルトで有効
- テーマ変数で各ステータスのアイコンをカスタマイズ可能
- ステータスアイコンが未定義の場合は該当ステータスは表示されない

---

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

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

### 推奨読解順序

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

まず、この機能で使用される内部定数とテーマ変数のマッピングを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | git.zsh | `lib/git.zsh` | prefix_constant_mapとconstant_prompt_mapの定義 |

**主要なデータ構造**:
- **47-64行目**: `prefix_constant_map` - Gitステータスプレフィックスから内部定数へのマッピング
- **67-79行目**: `constant_prompt_map` - 内部定数からテーマ変数へのマッピング
- **82-86行目**: `status_constants` - ステータス表示の順序を定義

**読解のコツ**: 2段階のマッピング（Git出力→内部定数→テーマ変数）により、テーマ変数が空の場合でも内部処理は正常に動作する設計になっている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | git.zsh | `lib/git.zsh` | _omz_git_prompt_status関数の実装を確認 |

**主要処理フロー**:
1. **42-43行目**: hide-status設定のチェック
2. **88-89行目**: `git status --porcelain -b`でステータス取得
3. **92-94行目**: エラーコード128のチェック
4. **99-101行目**: stashの存在チェック
5. **103-104行目**: ステータス出力を行ごとに分割
6. **106-117行目**: ブランチ行からahead/behind情報を解析
7. **119-127行目**: 各ファイル行のステータスプレフィックスを解析
8. **130-136行目**: ステータス定数の順序でアイコンを連結

#### Step 3: 非同期プロンプト対応を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | git.zsh | `lib/git.zsh` | 非同期/同期の切り替えロジック |

**主要処理フロー**:
- **155-159行目**: 非同期モードの`git_prompt_status`関数定義
- **171-174行目**: プロンプト変数に`$(git_prompt_status)`が含まれる場合にハンドラ登録
- **203-205行目**: 同期モードの`git_prompt_status`関数定義

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

```
git_prompt_status (ユーザー呼び出し/プロンプト展開)
    │
    ├─【非同期モード】
    │   └─ _OMZ_ASYNC_OUTPUT[_omz_git_prompt_status] から結果を取得
    │
    └─【同期モード】
        └─ _omz_git_prompt_status (lib/git.zsh:42-139)
               │
               ├─ __git_prompt_git config --get oh-my-zsh.hide-status
               │      └─ 非表示設定チェック
               │
               ├─ __git_prompt_git status --porcelain -b
               │      └─ ステータス情報取得
               │
               ├─ __git_prompt_git rev-parse --verify refs/stash
               │      └─ stash存在チェック
               │
               └─ ステータスアイコン構築
                      └─ prefix_constant_map → constant_prompt_map
```

### データフロー図

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

                        ┌─────────────────────┐
git status --porcelain ─▶│ ブランチ行解析       │──▶ ahead/behind/diverged
                        │ ## branch [ahead N] │
                        └─────────────────────┘
                                  │
                                  ▼
                        ┌─────────────────────┐
git status --porcelain ─▶│ ファイル行解析       │──▶ UNTRACKED/ADDED/
                        │ ?? file.txt        │     MODIFIED/RENAMED/
                        │ M  file2.txt       │     DELETED/UNMERGED
                        └─────────────────────┘
                                  │
                                  ▼
refs/stash ───────────▶ │ stash存在チェック   │──▶ STASHED
                                  │
                                  ▼
                        ┌─────────────────────┐
テーマ変数 ────────────▶│ アイコン構築         │──▶ "?+M..."
constant_prompt_map     │                     │
                        └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| git.zsh | `lib/git.zsh` | ソース | Git関連プロンプト関数の実装 |
| async_prompt.zsh | `lib/async_prompt.zsh` | ソース | 非同期プロンプト処理の基盤 |
| *.zsh-theme | `themes/*.zsh-theme` | テーマ | テーマ変数の定義とプロンプトでの使用 |
