# 通知設計書 60-Fast-Forwardマージ不能警告

## 概要

本ドキュメントは、LibGit2のマージ操作において、複数のマージヘッドを指定した場合にFast-Forwardマージが実行できない場合に発行される警告通知の設計を記述する。

### 本通知の処理概要

`LibGit2.merge!` 関数（`fastforward` パラメータ付き版）において、マージ分析の結果Fast-Forwardマージが可能と判定されたが、複数のマージヘッド（`length(anns) > 1`）が指定されているためFast-Forwardマージを実行できない場合に、警告を出力して `false` を返す処理である。

**業務上の目的・背景**：GitのFast-Forwardマージは、現在のHEADが対象コミットの祖先である場合に、HEADポインタを対象コミットに単純に移動する操作である。この操作は本質的に1つのコミットに対してのみ意味を持つため、複数のマージヘッドを指定した場合にはFast-Forwardマージは実行できない。この警告は、ユーザーに操作の制約を通知し、代替のマージ方法を検討させるために存在する。

**通知の送信タイミング**：`merge!(repo, anns, fastforward)` 関数内で、`merge_analysis` の結果が `MERGE_ANALYSIS_FASTFORWARD` であり、かつ `length(anns) > 1` の場合にトリガーされる。この条件は、マージ優先度が `MERGE_PREFERENCE_NONE` または `MERGE_PREFERENCE_FASTFORWARD_ONLY` の場合に発生し得る。

**通知の受信者**：LibGit2を通じてGit操作を行っているユーザー。

**通知内容の概要**：「Unable to perform Fast-Forward merge with mith multiple merge heads」というメッセージが表示される。

**期待されるアクション**：ユーザーは、マージヘッドを1つに絞るか、通常マージ（非Fast-Forward）を使用することを検討する。

## 通知種別

ログ（Warn） - Julia標準ロギングフレームワーク `@warn` マクロによるコンソール出力

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（マージ分析後の分岐処理中に出力） |
| 優先度 | 中（Warnレベル、操作制約の通知） |
| リトライ | 無し |

### 送信先決定ロジック

LibGit2を通じてマージ操作を行ったユーザー本人が受信者。`@warn` マクロによりグローバルロガーの設定に従いstderrへ出力される。

## 通知テンプレート

### メール通知の場合

該当なし（コンソールログ出力のみ）

### 本文テンプレート

```
Warning: Unable to perform Fast-Forward merge with mith multiple merge heads
```

注: メッセージ内の "mith" はソースコード上の原文のままであり、"with" のタイプミスと推測される。

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| （なし） | 固定メッセージのため変数なし | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼び出し | `merge!(repo, anns, fastforward)` の実行 | `MERGE_ANALYSIS_FASTFORWARD` かつ `length(anns) > 1` | merge.jl 221-223行目および234-236行目 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `length(anns) == 1` | マージヘッドが1つの場合は `ffmerge!` が実行される |
| 分析結果がFASTFORWARDでない | 通常マージまたはUP_TO_DATEの場合はこの分岐に到達しない |
| `MERGE_PREFERENCE_NO_FASTFORWARD` | Fast-Forwardが禁止されている場合はこの分岐に到達しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[merge! repo anns fastforward 呼び出し] --> B[merge_analysis 実行]
    B --> C{UP_TO_DATE?}
    C -->|Yes| D[return true]
    C -->|No| E[ffpref 決定]
    E --> F{MERGE_ANALYSIS_FASTFORWARD?}
    F -->|No| G[通常マージまたはエラー]
    F -->|Yes| H{length anns > 1?}
    H -->|No| I[ffmerge! 実行]
    H -->|Yes| J[@warn Unable to perform Fast-Forward merge]
    J --> K[return false]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（Git内部データ構造を使用）

### テーブル別参照項目詳細

該当なし

### 更新テーブル一覧

該当なし（マージは実行されないため更新なし）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 複数マージヘッドでのFast-Forward | `length(anns) > 1` かつ Fast-Forward分析結果 | `@warn` で通知し `false` を返却（マージ失敗として扱う） |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

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

本通知には固定メッセージのみが含まれ、リポジトリ情報は含まれない。

## 備考

- この警告は `merge!(repo, anns, fastforward)` 関数内の2箇所で発生し得る：
  1. **221-223行目**: `ffpref == MERGE_PREFERENCE_NONE` かつ `MERGE_ANALYSIS_FASTFORWARD` かつ `length(anns) > 1` の場合
  2. **234-236行目**: `ffpref == MERGE_PREFERENCE_FASTFORWARD_ONLY` かつ `MERGE_ANALYSIS_FASTFORWARD` かつ `length(anns) > 1` の場合
- メッセージ内の "mith" は "with" のタイプミスと推測される（ソースコード原文のまま）
- 関連する警告として、No.61「Fast-Forwardマージ不可警告」（`@warn "Cannot perform fast-forward merge"`）がある。こちらはFast-Forwardのみが許可されているが分析結果がFast-Forwardでない場合に発生する（241行目）

---

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

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

### 推奨読解順序

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

マージ分析の結果型とマージ優先度を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | merge.jl | `stdlib/LibGit2/src/merge.jl` | 57-97行目: `merge_analysis` 関数のdocstring。`MERGE_ANALYSIS_*` と `MERGE_PREFERENCE_*` の定数の意味 |

**読解のコツ**: `merge_analysis` は2つの値を返す。`analysis` はマージの種類（Fast-Forward、通常、UP_TO_DATE等）、`preference` はGit設定に基づくマージ方法の優先度である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | merge.jl | `stdlib/LibGit2/src/merge.jl` | 199-254行目: `merge!(repo, anns, fastforward)` 関数全体 |

**主要処理フロー**:
1. **202行目**: `merge_analysis(repo, anns)` でマージ分析
2. **203-205行目**: `MERGE_ANALYSIS_UP_TO_DATE` なら即座に `true` 返却
3. **207-217行目**: `ffpref`（Fast-Forward優先度）の決定
4. **219-231行目**: `MERGE_PREFERENCE_NONE` の場合の分岐
5. **221-223行目**: Fast-Forward可能だが複数ヘッドの場合 - **本通知（1箇所目）**
6. **232-243行目**: `MERGE_PREFERENCE_FASTFORWARD_ONLY` の場合の分岐
7. **234-236行目**: Fast-Forward可能だが複数ヘッドの場合 - **本通知（2箇所目）**

#### Step 3: Fast-Forwardマージの実体を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | merge.jl | `stdlib/LibGit2/src/merge.jl` | 106-121行目: `ffmerge!` 関数。正常なFast-Forwardマージの実装 |

**主要処理フロー**:
- **108行目**: `GitCommit(repo, GitHash(ann))` でコミットオブジェクト取得
- **109行目**: `checkout_tree` でワーキングツリー更新
- **110-119行目**: HEADリファレンスの更新

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

```
merge!(repo, anns, fastforward)  [merge.jl:199]
    |
    +-- merge_analysis(repo, anns)  [merge.jl:85]
    |
    +-- [ffpref 決定]
    |
    +-- [分岐: MERGE_PREFERENCE_NONE]
    |       |
    |       +-- [MERGE_ANALYSIS_FASTFORWARD]
    |       |       |
    |       |       +-- [length(anns) > 1]
    |       |       |       +-- @warn "Unable to perform Fast-Forward merge..."  [merge.jl:222]
    |       |       |       +-- return false
    |       |       |
    |       |       +-- [length(anns) == 1]
    |       |               +-- ffmerge!(repo, anns[1])  [merge.jl:106]
    |       |
    |       +-- [MERGE_ANALYSIS_NORMAL]
    |               +-- merge!(repo, anns; ...)  [merge.jl:147]
    |
    +-- [分岐: MERGE_PREFERENCE_FASTFORWARD_ONLY]
            |
            +-- [MERGE_ANALYSIS_FASTFORWARD]
            |       |
            |       +-- [length(anns) > 1]
            |       |       +-- @warn "Unable to perform Fast-Forward merge..."  [merge.jl:235]
            |       |       +-- return false
            |       |
            |       +-- [length(anns) == 1]
            |               +-- ffmerge!(repo, anns[1])
            |
            +-- [その他]
                    +-- @warn "Cannot perform fast-forward merge"  [merge.jl:241]
                    +-- return false
```

### データフロー図

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

GitRepo +                  merge!(repo, anns, fastforward)
GitAnnotated[] +                   |
fastforward::Bool -------->        +-> merge_analysis
                                   |       |
                                   |       +-> analysis, preference
                                   |
                                   +-> [FASTFORWARD + 複数ヘッド]
                                   |       +-> @warn ---------> stderr (警告)
                                   |       +-> return false --> 呼び出し元
                                   |
                                   +-> [FASTFORWARD + 単一ヘッド]
                                   |       +-> ffmerge! ------> Gitリポジトリ更新
                                   |       +-> return true
                                   |
                                   +-> [NORMAL]
                                           +-> merge! (通常版) -> Gitリポジトリ更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| merge.jl | `stdlib/LibGit2/src/merge.jl` | ソース | merge! 関数群、ffmerge!、merge_analysis（全体） |
