# 機能設計書 17-Git操作(SPC g)

## 概要

本ドキュメントは、space-vimにおけるGit操作機能（SPC g）の設計仕様を記述する。SPCキーに続いて「g」を押下することで、Gitの基本操作（blame、commit、diff、push等）を提供する機能である。

### 本機能の処理概要

Git操作機能は、vim-fugitiveプラグインと連携し、Vim内からGitの各種操作を実行するためのキーバインディング群を提供する。コミット、差分表示、ログ閲覧、プッシュなどの頻繁に使用するGit操作を統一的なキー体系でアクセス可能にする。

**業務上の目的・背景**：ソフトウェア開発ではGitによるバージョン管理が標準的に行われる。Git操作をVimエディタから離れずに実行できることで、開発ワークフローの効率が大幅に向上する。ターミナルに切り替えることなく、編集中のファイルのblame確認やcommit、pushが可能。

**機能の利用シーン**：
- コード変更をコミットする場合（SPC g c / SPC g C）
- 現在のファイルの変更履歴（blame）を確認する場合（SPC g b）
- 変更差分を確認する場合（SPC g d）
- 変更をリモートにプッシュする場合（SPC g p）
- コミットログを閲覧する場合（SPC g l）
- 集中執筆モード（Goyo）を使用する場合（SPC g y）

**主要な処理内容**：
1. SPC g s：Git status表示（:Git）
2. SPC g d：Git diff表示（:Gdiffsplit）
3. SPC g c：Git commit（:Git commit）
4. SPC g b：Git blame（:Git blame）
5. SPC g l：Git log（:Gclog）
6. SPC g p：Git push（:Git push）
7. SPC g r：Gread - ステージング領域から読み込み
8. SPC g w：Gwrite - ステージングに書き込み
9. SPC g e：Gedit - オブジェクト編集
10. SPC g i：インタラクティブステージング
11. SPC g g：Gitサイン表示トグル

**関連システム・外部連携**：
- vim-fugitive：Git操作の基盤プラグイン
- vim-signify / vim-gitgutter：変更サイン表示
- gv.vim：Gitログビジュアル表示
- goyo.vim：集中執筆モード

**権限による制御**：本機能に権限制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | Fugitive（Git操作画面） | 補助機能 | SPC gによるGit操作（blame、commit、diff、push等） |
| 13 | Signify（差分インジケータ） | 補助機能 | Git差分情報の視覚的フィードバック |

## 機能種別

バージョン管理 / Git操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| キーシーケンス | String | Yes | SPC g に続くキー入力 | 定義済みキーのみ受付 |

### 入力データソース

- ユーザーキー入力
- Gitリポジトリ情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Gitステータス | Vim バッファ | :Gitコマンドの出力 |
| Diff表示 | Vim バッファ | 差分表示ウィンドウ |
| Blame表示 | Vim バッファ | 行ごとの変更履歴 |
| コミット結果 | Git状態 | ローカルコミット |

### 出力先

- Vimバッファ（各種Git情報表示）
- Gitリポジトリ（コミット、プッシュ時）

## 処理フロー

### 処理シーケンス

```
1. SPC g キー入力
   └─ which-keyによるサブキー一覧表示
2. サブキー入力に応じた処理分岐
   ├─ s:  Gitステータス表示（:Git）
   ├─ d:  差分表示（:Gdiffsplit）
   ├─ c:  コミット（:Git commit）
   ├─ b:  Blame表示（:Git blame）
   ├─ l:  ログ表示（:Gclog）
   ├─ p:  プッシュ（:Git push）
   ├─ r:  ステージング読み込み（:Gread）
   ├─ w:  ステージング書き込み（:Gwrite）
   ├─ e:  オブジェクト編集（:Gedit）
   ├─ i:  インタラクティブステージング（:Git add -p %）
   ├─ g:  サイン表示トグル
   └─ y:  Goyoモード（:Goyo）
```

### フローチャート

```mermaid
flowchart TD
    A[SPC g 入力] --> B{サブキー?}
    B -->|s| C[Git status]
    B -->|d| D[Git diff]
    B -->|c| E[Git commit]
    B -->|b| F[Git blame]
    B -->|l| G[Git log]
    B -->|p| H[Git push]
    B -->|r| I[Gread]
    B -->|w| J[Gwrite]
    B -->|e| K[Gedit]
    B -->|i| L[Git add -p]
    B -->|g| M[サイン表示トグル]
    B -->|y| N[Goyoモード]
    C --> O[fugitiveバッファ表示]
    D --> P[diffウィンドウ表示]
    E --> Q[コミット画面]
    F --> R[blameバッファ表示]
    G --> S[ログバッファ表示]
    H --> T[リモートへプッシュ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | Gitリポジトリ必須 | Git操作はGitリポジトリ内でのみ有効 | 常時 |
| BR-002 | fugitive依存 | vim-fugitiveプラグインが必要 | Git操作コマンド実行時 |
| BR-003 | signify/gitgutter | サイン表示はどちらかのプラグインを使用 | SPC g g / SPC t g 実行時 |
| BR-004 | goyo連携 | SPC g yでGoyo集中モードを起動 | goyo.vimが読み込まれている場合 |

### 計算ロジック

該当なし

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Gitリポジトリ外 | Gitリポジトリでないディレクトリで実行 | エラーメッセージ表示 |
| - | コミット競合 | マージコンフリクトがある状態でコミット | コンフリクト解消後に再実行 |

### リトライ仕様

該当なし

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

該当なし（Gitトランザクションに委譲）

## パフォーマンス要件

- Git操作はGitコマンドの速度に依存
- blameは大規模ファイルで数秒かかる場合あり

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

- Git認証情報は~/.gitconfigに依存
- pushはリモートリポジトリへの書き込み権限が必要

## 備考

- vim-fugitiveの詳細は:help fugitiveを参照
- Goyoは集中執筆モードでGit操作とは直接関係ないが、歴史的経緯でSPC gに配置

---

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

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

### 推奨読解順序

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

Git操作のキーマッピング定義を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | leader.vim | `core/autoload/spacevim/map/leader.vim` | s:leader_map['g']の構造を理解 |

**読解のコツ**: Git操作はvim-fugitiveのコマンドを直接呼び出す形式。

**主要データ構造**:
- **93行目**: `let s:leader_map['g'] = {` - Git操作グループ開始
- **94行目**: `'name' : '+git/version-control'` - グループ名
- **95行目**: `'b' : ['Gblame', 'fugitive-blame']` - blame
- **96行目**: `'c' : ['BCommits', 'commits-for-current-buffer']` - fzfコミット
- **97行目**: `'C' : ['Gcommit', 'fugitive-commit']` - コミット
- **98行目**: `'d' : ['Gdiff', 'fugitive-diff']` - diff
- **99行目**: `'e' : ['Gedit', 'fugitive-edit']` - edit
- **100行目**: `'l' : ['Glog', 'fugitive-log']` - log
- **101行目**: `'r' : ['Gread', 'fugitive-read']` - read
- **102行目**: `'s' : ['Gstatus', 'fugitive-status']` - status
- **103行目**: `'w' : ['Gwrite', 'fugitive-write']` - write
- **104行目**: `'p' : ['Git push', 'fugitive-push']` - push
- **105行目**: `'y' : ['Goyo', 'goyo-mode']` - Goyo

#### Step 2: レイヤー設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.vim | `layers/+version-control/git/config.vim` | 実際のキーマッピング |

**主要処理フロー**:
- **4行目**: `nnoremap <silent> <Leader>gs :Git<CR>` - status
- **5行目**: `nnoremap <silent> <Leader>gd :Gdiffsplit<CR>` - diff
- **6行目**: `nnoremap <silent> <Leader>gc :Git commit<CR>` - commit
- **7行目**: `nnoremap <silent> <Leader>gb :Git blame<CR>` - blame
- **8行目**: `nnoremap <silent> <Leader>gl :Gclog<CR>` - log
- **9行目**: `nnoremap <silent> <Leader>gp :Git push<CR>` - push
- **14行目**: `nnoremap <silent> <Leader>gi :Git add -p %<CR>` - インタラクティブ
- **15行目**: `nnoremap <silent> <Leader>gg :call spacevim#plug#toggle#Git()<CR>` - トグル
- **34行目**: `nnoremap <silent> <Leader>tg :call spacevim#plug#toggle#Git()<CR>` - トグル（SPC t g）

#### Step 3: トグル関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | toggle.vim | `core/autoload/spacevim/plug/toggle.vim` | Gitサイン表示トグル |

**主要処理フロー**:
- **1-9行目**: `spacevim#plug#toggle#Git()` - SignifyToggle/GitGutterToggle

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

```
SPC g キー入力
    │
    ├─ SPC g s
    │      └─ :Git 実行
    │             └─ vim-fugitive Gitステータス表示
    │
    ├─ SPC g d
    │      └─ :Gdiffsplit 実行
    │             └─ vim-fugitive 差分表示
    │
    ├─ SPC g c
    │      └─ :Git commit 実行
    │             └─ vim-fugitive コミット画面
    │
    ├─ SPC g b
    │      └─ :Git blame 実行
    │             └─ vim-fugitive blame表示
    │
    ├─ SPC g l
    │      └─ :Gclog 実行
    │             └─ vim-fugitive ログ表示
    │
    ├─ SPC g p
    │      └─ :Git push 実行
    │             └─ リモートへプッシュ
    │
    ├─ SPC g g
    │      └─ spacevim#plug#toggle#Git()
    │             ├─ SignifyToggle (vim-signifyの場合)
    │             └─ GitGutterToggle (vim-gitgutterの場合)
    │
    └─ SPC g y
           └─ :Goyo 実行
                  └─ goyo.vim 集中モード
```

### データフロー図

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

ユーザーキー入力 ────▶ which-keyディスパッチ ───▶ サブキー選択UI
    │                       │
    ▼                       ▼
SPC g + サブキー ────▶ fugitiveコマンド実行 ───▶ Git操作実行
                            │
                            ├─▶ :Git ───────────▶ ステータス表示
                            ├─▶ :Gdiffsplit ────▶ 差分ウィンドウ
                            ├─▶ :Git commit ────▶ コミット画面
                            ├─▶ :Git blame ─────▶ blame表示
                            ├─▶ :Gclog ─────────▶ ログ表示
                            └─▶ :Git push ──────▶ リモートプッシュ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| leader.vim | `core/autoload/spacevim/map/leader.vim` | ソース | Git操作キーマッピング定義 |
| config.vim | `layers/+version-control/git/config.vim` | 設定 | vim-fugitiveキーマッピング |
| packages.vim | `layers/+version-control/git/packages.vim` | 設定 | vim-fugitiveプラグイン登録 |
| toggle.vim | `core/autoload/spacevim/plug/toggle.vim` | ソース | Gitサイン表示トグル関数 |
