# 機能設計書 24-parse_git_dirty

## 概要

本ドキュメントは、Oh My Zshの`parse_git_dirty`関数の機能設計を定義するものである。この関数は、Gitリポジトリのワーキングツリーがダーティ（変更あり）かクリーン（変更なし）かを判定し、対応するテーマ変数の値を出力する機能を提供する。

### 本機能の処理概要

`parse_git_dirty`関数は、`git status --porcelain`コマンドの出力を解析し、ワーキングツリーに変更があるかどうかを判定する。変更がある場合は`ZSH_THEME_GIT_PROMPT_DIRTY`、ない場合は`ZSH_THEME_GIT_PROMPT_CLEAN`の値を出力する。

**業務上の目的・背景**：開発者がターミナルで作業する際、ワーキングツリーに未コミットの変更があるかどうかを視覚的に確認できることは重要である。この関数により、プロンプトに表示されるGit情報にダーティ/クリーン状態を示すマーカーを追加できる。

**機能の利用シーン**：
- `git_prompt_info`関数から呼び出され、ブランチ名と共にダーティ状態を表示
- テーマでプロンプトをカスタマイズする際に利用
- コミット前に変更があるかを確認する際の視覚的フィードバック

**主要な処理内容**：
1. `oh-my-zsh.hide-dirty`設定による非表示制御をチェック
2. `DISABLE_UNTRACKED_FILES_DIRTY`設定による未追跡ファイルの除外
3. `GIT_STATUS_IGNORE_SUBMODULES`設定によるサブモジュール制御
4. `git status --porcelain`コマンドでステータスを取得
5. 出力があればダーティ、なければクリーンと判定
6. 対応するテーマ変数の値を出力

**関連システム・外部連携**：
- Gitコマンド（`git status --porcelain`、`git config`）
- `git_prompt_info`関数（No.22）からの呼び出し

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | シェルプロンプト | 主画面 | プロンプト表示時にダーティ/クリーンマーカーを出力 |

## 機能種別

状態判定・フォーマット処理

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- カレントディレクトリのGitリポジトリ情報
- 環境変数・設定
  - `DISABLE_UNTRACKED_FILES_DIRTY`: 未追跡ファイルをダーティ判定から除外
  - `GIT_STATUS_IGNORE_SUBMODULES`: サブモジュールの扱い方を指定
- Git設定（`oh-my-zsh.hide-dirty`）
- テーマ変数（`ZSH_THEME_GIT_PROMPT_DIRTY`、`ZSH_THEME_GIT_PROMPT_CLEAN`）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ダーティマーカー | 文字列 | `ZSH_THEME_GIT_PROMPT_DIRTY`の値（変更がある場合） |
| クリーンマーカー | 文字列 | `ZSH_THEME_GIT_PROMPT_CLEAN`の値（変更がない場合） |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. oh-my-zsh.hide-dirty設定のチェック
   └─ 設定が1の場合は何も出力しない（常にクリーン扱い）
2. FLAGSの初期化
   └─ --porcelainフラグを設定
3. DISABLE_UNTRACKED_FILES_DIRTY設定のチェック
   └─ trueの場合は--untracked-files=noフラグを追加
4. GIT_STATUS_IGNORE_SUBMODULES設定のチェック
   └─ 設定に応じて--ignore-submodulesフラグを追加
5. git status --porcelainコマンドを実行
   └─ 出力の最後の1行を取得
6. 出力の有無を判定
   └─ 出力あり：ダーティマーカーを出力
   └─ 出力なし：クリーンマーカーを出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始: parse_git_dirty] --> B{hide-dirty=1?}
    B -->|Yes| C[クリーンマーカーを出力]
    B -->|No| D[FLAGS=--porcelain]
    D --> E{DISABLE_UNTRACKED_FILES_DIRTY=true?}
    E -->|Yes| F[FLAGS+=--untracked-files=no]
    E -->|No| G{GIT_STATUS_IGNORE_SUBMODULES設定?}
    F --> G
    G -->|git| H[Gitに判断を委ねる]
    G -->|その他| I[FLAGS+=--ignore-submodules=設定値]
    G -->|未設定| J[FLAGS+=--ignore-submodules=dirty]
    H --> K[git status実行]
    I --> K
    J --> K
    K --> L[出力をtail -n 1で取得]
    L --> M{出力あり?}
    M -->|Yes| N[ダーティマーカーを出力]
    M -->|No| C
    N --> O[終了]
    C --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-24-01 | 非表示制御 | `oh-my-zsh.hide-dirty=1`の場合は常にクリーンを返す | hide-dirty設定時 |
| BR-24-02 | 未追跡ファイル除外 | `DISABLE_UNTRACKED_FILES_DIRTY=true`の場合は未追跡ファイルを無視 | 設定時 |
| BR-24-03 | サブモジュール制御 | `GIT_STATUS_IGNORE_SUBMODULES`設定でサブモジュールの扱いを制御 | 常時 |
| BR-24-04 | デフォルトサブモジュール | サブモジュール設定が未定義の場合は`dirty`として扱う | 未設定時 |

### 計算ロジック

該当なし

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 非Gitリポジトリ | Gitリポジトリ外で実行 | git statusがエラーを返し、空の出力になる |

### リトライ仕様

リトライ機能なし

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

該当なし

## パフォーマンス要件

- `GIT_OPTIONAL_LOCKS=0`を設定してGitコマンドを実行し、ロック競合を回避
- `tail -n 1`で最後の1行のみを取得し、大量のファイル変更時のパフォーマンスを最適化

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

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

## 備考

- `git_prompt_info`関数から内部的に呼び出されることが多い
- テーマ変数でダーティ/クリーンのマーカー（例：「*」「+」など）をカスタマイズ可能
- 大規模リポジトリでは`DISABLE_UNTRACKED_FILES_DIRTY=true`を設定することでパフォーマンスを改善できる

---

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

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

### 推奨読解順序

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

まず、この機能で使用されるテーマ変数と環境変数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | テーマファイル | `themes/*.zsh-theme` | ZSH_THEME_GIT_PROMPT_DIRTY/CLEAN変数の定義を確認 |

**主要な変数**:
- `ZSH_THEME_GIT_PROMPT_DIRTY`: ダーティ時に表示するマーカー（例：「*」）
- `ZSH_THEME_GIT_PROMPT_CLEAN`: クリーン時に表示するマーカー（例：空文字）
- `DISABLE_UNTRACKED_FILES_DIRTY`: 未追跡ファイルをダーティ判定から除外するフラグ
- `GIT_STATUS_IGNORE_SUBMODULES`: サブモジュールの扱いを制御する設定

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

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

**主要処理フロー**:
1. **209行目**: `parse_git_dirty`関数の定義開始
2. **210-211行目**: ローカル変数の宣言
3. **212行目**: `FLAGS`配列に`--porcelain`を初期設定
4. **213行目**: `hide-dirty`設定のチェック
5. **214-216行目**: `DISABLE_UNTRACKED_FILES_DIRTY`設定のチェックと`--untracked-files=no`フラグ追加
6. **217-226行目**: `GIT_STATUS_IGNORE_SUBMODULES`設定の解析
7. **227行目**: `git status`コマンドの実行と`tail -n 1`で最終行取得
8. **229-233行目**: 出力の有無でダーティ/クリーンを判定して出力

**読解のコツ**:
- `--porcelain`フラグにより、スクリプトで解析しやすい形式の出力を取得
- `tail -n 1`で出力があるかどうかのみを効率的にチェック
- 配列`FLAGS`に動的にフラグを追加していく設計

#### Step 3: 呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | git.zsh | `lib/git.zsh` | _omz_git_prompt_info関数からの呼び出し |

**呼び出し箇所**:
- **39行目**: `$(parse_git_dirty)`として出力文字列に組み込まれている

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

```
git_prompt_info (プロンプト展開)
    │
    └─ _omz_git_prompt_info (lib/git.zsh:14-40)
           │
           └─ parse_git_dirty (lib/git.zsh:209-234)
                  │
                  ├─ __git_prompt_git config --get oh-my-zsh.hide-dirty
                  │      └─ 非表示設定チェック
                  │
                  └─ __git_prompt_git status ${FLAGS}
                         │
                         └─ tail -n 1
                                │
                                └─ 出力有無判定
```

### データフロー図

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

                        ┌─────────────────────┐
oh-my-zsh.hide-dirty ──▶│ 非表示設定チェック    │──▶ hide-dirty=1なら
                        └─────────────────────┘     クリーンを返す
                                  │
                                  ▼
                        ┌─────────────────────┐
DISABLE_UNTRACKED_    ─▶│ フラグ構築           │
FILES_DIRTY             │ --porcelain         │
                        │ --untracked-files   │
GIT_STATUS_IGNORE_    ─▶│ --ignore-submodules │
SUBMODULES              └─────────────────────┘
                                  │
                                  ▼
                        ┌─────────────────────┐
カレントディレクトリ ──▶│ git status ${FLAGS} │
                        │ | tail -n 1         │
                        └─────────────────────┘
                                  │
                                  ▼
                        ┌─────────────────────┐
ZSH_THEME_GIT_PROMPT  ─▶│ 出力判定            │──▶ DIRTY or CLEAN
_DIRTY / _CLEAN         │ 出力あり→DIRTY     │     マーカー
                        │ 出力なし→CLEAN     │
                        └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| git.zsh | `lib/git.zsh` | ソース | parse_git_dirty関数の実装 |
| *.zsh-theme | `themes/*.zsh-theme` | テーマ | DIRTY/CLEANマーカーの定義 |
