# 画面設計書 36-ブランチ新規作成

## 概要

本ドキュメントは、GitLabのリポジトリに新規ブランチを作成する画面（ブランチ新規作成画面）の設計を記述したものである。

### 本画面の処理概要

本画面は、既存のブランチ、タグ、またはコミットSHAを基点として新しいブランチを作成するための画面である。シンプルなフォームでブランチ名と作成元を指定し、新しい開発ブランチを素早く作成できる。

**業務上の目的・背景**：Gitフロー開発では、機能開発やバグ修正のために頻繁にブランチを作成する必要がある。本画面は、ローカル環境やGit CLIを使用せずに、Webインターフェースから直接ブランチを作成できる機能を提供する。特にJira連携やIssue連携によるブランチ作成フローでも活用される。

**画面へのアクセス方法**：
- ブランチ一覧画面の「New branch」ボタンをクリック
- Issue詳細画面の「Create branch」ボタン
- Jira ConnectからのCreate branch
- URL直接入力: `/{namespace}/{project}/-/branches/new`

**主要な操作・処理内容**：
1. 新しいブランチ名の入力
2. 作成元（ブランチ/タグ/コミットSHA）の選択
3. ブランチの作成実行
4. 作成されたブランチのファイルツリーへ遷移

**画面遷移**：
- 遷移元: ブランチ一覧画面、Issue詳細画面、Jira Connect
- 遷移先: 作成されたブランチのファイルツリー画面、（エラー時）同画面

**権限による表示制御**：
- プッシュ権限がない場合はアクセス不可
- 保護ブランチの名前パターンに一致する場合は作成制限

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | ブランチ管理 | 主機能 | 新規ブランチの作成処理 |
| 36 | イシュー作成 | 補助機能 | Issue連携でのブランチ作成 |

## 画面種別

登録

## URL/ルーティング

```
GET  /{namespace}/{project}/-/branches/new
POST /{namespace}/{project}/-/branches
```

**ルート定義**: `config/routes/repository.rb`
```ruby
resources :branches, only: [:index, :new, :create, :destroy]
```

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| namespace | 入力 | String | Yes | プロジェクトの名前空間 |
| project | 入力 | String | Yes | プロジェクト名 |
| branch_name | 入力 | String | Yes | 新しいブランチ名 |
| ref | 入力 | String | Yes | 作成元の参照（ブランチ名/タグ名/コミットSHA） |
| issue_iid | 入力 | Integer | No | 関連Issue IID（Issue連携時） |
| confidential_issue_project_id | 入力 | Integer | No | 機密Issue所属プロジェクトID |

## 表示項目

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| ブランチ名入力欄 | 新しいブランチ名の入力 | 入力項目 |
| 作成元セレクター | ブランチ/タグ/コミットの選択 | リポジトリ情報 |
| デフォルトブランチ名 | 初期選択値 | @project.default_branch / params[:ref] |
| エラーメッセージ | バリデーションエラー | @error |

## イベント仕様

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

ブランチ作成フォームを初期化する。

**処理フロー**:
1. プッシュ権限の確認
2. デフォルトの作成元を設定（params[:ref]またはdefault_branch）
3. 参照セレクターコンポーネントを初期化

### 2-ブランチ名入力

新しいブランチ名を入力する。

**バリデーション**:
- 空文字は不可
- Git参照名として有効な文字のみ
- 既存ブランチ名との重複チェック
- ファイル/ディレクトリ階層との競合チェック

### 3-Create branchボタン押下

新しいブランチを作成する。

**処理フロー**:
1. ブランチ名のサニタイズ（HTMLタグ除去、URIデコード）
2. Branches::CreateServiceを呼び出し
3. 参照の検証
4. ブランチ名の検証
5. リポジトリにブランチを追加
6. 成功時：ファイルツリー画面へリダイレクト
7. エラー時：エラーメッセージ表示して再表示
8. Issue連携時：システムノートを追加

### 4-Cancelボタン押下

ブランチ作成をキャンセルしてブランチ一覧へ戻る。

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

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Create branch | events | INSERT | ブランチ作成イベントの記録 |
| Create branch | push_event_payloads | INSERT | プッシュイベント詳細 |
| Create branch | notes | INSERT | Issue連携時のシステムノート |

### テーブル別更新項目詳細

#### events

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | action | 5 (PUSHED) | プッシュアクション |
| INSERT | author_id | current_user.id | 実行ユーザー |
| INSERT | project_id | @project.id | 対象プロジェクト |

#### push_event_payloads

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | action | 1 (CREATED) | ブランチ作成 |
| INSERT | ref_type | 1 (BRANCH) | ブランチ参照 |
| INSERT | ref | 新ブランチ名 | ブランチ名 |

#### notes（Issue連携時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | noteable_type | 'Issue' | 関連Issue |
| INSERT | noteable_id | issue.id | Issue ID |
| INSERT | author_id | current_user.id | 実行ユーザー |
| INSERT | system | true | システムノート |
| INSERT | note | "created branch..." | ブランチ作成通知 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|----------|
| M001 | エラー | "Ref is missing" | 作成元が未指定 |
| M002 | エラー | "Failed to create branch '...': invalid reference name '...'" | 無効な参照名 |
| M003 | エラー | "Failed to create branch '...': Branch name conflicts with existing branch hierarchy." | ファイル/ディレクトリ競合 |
| M004 | エラー | "Branch already exists" | 既存ブランチとの重複 |
| M005 | エラー | "Invalid branch name" | 不正なブランチ名 |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|------|---------|---------|
| 403 Forbidden | プッシュ権限なし | アクセス拒否画面表示 |
| InvalidRef | 存在しない参照 | エラーメッセージ表示 |
| PreReceiveError | pre-receiveフック失敗 | エラーメッセージ表示 |
| CommandError | Git操作失敗 | エラーメッセージ表示 |

## 備考

- 空のリポジトリの場合、ブランチ作成時に自動的にデフォルトブランチとREADME.mdが作成される
- デプロイプラットフォームが設定されている場合、autodeploy設定画面へリダイレクト
- ブランチ名はHTMLタグが除去され、URIエンコードが解除される

---

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

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

### 推奨読解順序

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

ブランチ作成で使用されるパラメータと検証ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | create_service.rb | `app/services/branches/create_service.rb` | ブランチ作成ロジック |
| 1-2 | validate_new_service.rb | `app/services/branches/validate_new_service.rb` | ブランチ名検証 |

**読解のコツ**: `Branches::CreateService`は参照検証とブランチ名検証を行った後、`repository.add_branch`を呼び出す。検証は`Branches::ValidateNewService`に委譲される。

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

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

**主要処理フロー**:
1. **76行目**: `def create` - メインアクション
2. **77-78行目**: ブランチ名のサニタイズ
3. **80行目**: 空リポジトリ時のリダイレクト判定
4. **82-83行目**: `Branches::CreateService`の呼び出し
5. **87-93行目**: Issue連携時のシステムノート追加
6. **97-107行目**: 成功時のリダイレクト処理
7. **106-108行目**: エラー時の再表示

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | new.html.haml | `app/views/projects/branches/new.html.haml` | フォーム全体構造 |

**主要処理フロー**:
- **5-8行目**: エラーメッセージ表示
- **9行目**: ページヘッダー
- **11行目**: form_tag - POSTリクエスト先
- **12-15行目**: ブランチ名入力欄
- **16-18行目**: 作成元セレクター（Vue.js コンポーネント）
- **21-23行目**: アクションボタン群

#### Step 4: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | create_service.rb | `app/services/branches/create_service.rb` | ブランチ作成 |

**主要処理フロー**:
- **11-21行目**: `execute` - メイン処理
- **78-104行目**: `create_branch` - 実際のブランチ追加
- **106-110行目**: `validate_ref` - 参照検証
- **112-120行目**: `create_default_branch` - 空リポジトリ時の処理

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

```
Projects::BranchesController#create
    │
    ├─ strip_tags/sanitize (branch_name)
    │
    ├─ Addressable::URI.unescape
    │
    └─ Branches::CreateService#execute
           │
           ├─ validate_ref
           │
           ├─ create_default_branch (if empty repo)
           │      └─ repository.create_file
           │
           ├─ branch_validation_service.execute
           │      └─ Branches::ValidateNewService
           │
           └─ create_branch
                  └─ repository.add_branch
                         └─ Gitlab::Git::Repository#create_branch
```

### データフロー図

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

Form Parameters ───▶ BranchesController#create ───▶ Redirect / Error
  - branch_name       │
  - ref               ├─▶ Sanitize branch_name
  - issue_iid         │
                      ├─▶ Branches::CreateService
                      │      │
                      │      ├─▶ ValidateNewService
                      │      │
                      │      └─▶ Repository#add_branch
                      │             │
                      │             └─▶ Git Repository
                      │
                      └─▶ SystemNoteService (if issue_iid)
                             └─▶ Notes table
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| branches_controller.rb | `app/controllers/projects/branches_controller.rb` | コントローラー | リクエスト処理 |
| new.html.haml | `app/views/projects/branches/new.html.haml` | テンプレート | フォームビュー |
| create_service.rb | `app/services/branches/create_service.rb` | サービス | ブランチ作成ロジック |
| validate_new_service.rb | `app/services/branches/validate_new_service.rb` | サービス | ブランチ名検証 |
| system_note_service.rb | `app/services/system_note_service.rb` | サービス | システムノート作成 |
| repository.rb | `config/routes/repository.rb` | ルーティング | URL定義 |
