# バッチ設計書 66-Get-OSSConhostLog.ps1

## 概要

本ドキュメントは、Git2Git除外ファイルをフィルタリングしたコミットログを生成するPowerShellスクリプト `Get-OSSConhostLog.ps1` のバッチ設計書である。指定されたリビジョン範囲のgitコミットログから、Git2Git転送対象外のファイル変更を除外し、GitHub PR番号のマングリング処理を行った上でコミットログを出力する。

### 本バッチの処理概要

本スクリプトは、OpenConsole（Windows Terminal）プロジェクトのgitコミット履歴から、Git2Git（Microsoftの内部リポジトリとOSSリポジトリ間の同期ツール）の除外対象ファイルに関する変更をフィルタリングし、整形されたコミットログを生成する。

**業務上の目的・背景**：OpenConsoleプロジェクトはMicrosoftの内部リポジトリとGitHubのOSSリポジトリの間でGit2Gitによるコード同期が行われている。OSSリポジトリに転送する際、特定のファイル（内部ツール、CI設定等）は除外される。本スクリプトは、OSS公開に適したコミットログを生成するために、これらの除外ファイルのみに関するコミットをフィルタリングし、さらにGitHubのPR番号やIssue番号をGit2GitやAzure DevOpsが誤解しない形式（GH-XXX、CC-XXX）に変換する。コミュニティからのコントリビューションはCC-プレフィックスで識別できるようにしている。

**バッチの実行タイミング**：Git2Git転送の準備段階として、または変更ログ作成時に手動で実行される。

**主要な処理内容**：
1. consolegit2gitfilters.jsonから除外フィルタ定義を読み込む
2. フィルタ定義をgitのpathspecの除外形式（:(top,exclude)...）に変換する
3. git logコマンドで指定リビジョン範囲のコミットログを除外パス付きで取得する
4. コミッターのメールアドレスに基づき、Microsoft社員かコミュニティかを判定する
5. PR番号をGH-XXX（MS社員）またはCC-XXX（コミュニティ）に変換する
6. Issue番号（#XXX）をGH-XXXに変換する
7. コミッターごとにグループ化し、マージコミットを除外して出力する

**前後の処理との関連**：Git2Git同期プロセスと連携する。consolegit2gitfilters.jsonはリポジトリルートに配置された除外設定ファイルである。

**影響範囲**：標準出力にのみ影響する。ファイルシステムやデータベースへの変更はない。gitリポジトリの状態も変更しない。

## バッチ種別

ログ生成 / ユーティリティ

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（Git2Git同期時/変更ログ作成時） |
| 実行時刻 | 手動実行に依存 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 手動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| gitリポジトリ内 | OpenConsoleのgitリポジトリ内で実行されること |
| consolegit2gitfilters.json | リポジトリルートにGit2Git除外設定ファイルが存在すること |
| gitコマンド | gitが利用可能であること |

### 実行可否判定

gitリポジトリ内で実行され、consolegit2gitfilters.jsonが存在すること。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| RevisionRange | string | No | なし | gitログの対象リビジョン範囲（例: HEAD~10..HEAD） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| consolegit2gitfilters.json | JSON | Git2Git除外フィルタ定義（ContainsFilters, SuffixFilters, PrefixFilters） |
| gitリポジトリ | git | コミット履歴 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | フィルタリング・マングリング済みのコミットログ |

### 出力ファイル仕様

ファイル出力はなし。標準出力にテキスト形式でコミットログを出力する。

| 項目 | 内容 |
|-----|------|
| ファイル名 | 該当なし（標準出力） |
| 出力先 | 標準出力 |
| 文字コード | UTF-8 |
| 区切り文字 | 該当なし |

出力形式：
```
著者名 (コミット数)
* コミットメッセージ1
* コミットメッセージ2

著者名2 (コミット数)
* コミットメッセージ3
```

## 処理フロー

### 処理シーケンス

```
1. Git2Git除外フィルタ読み込み
   └─ consolegit2gitfilters.jsonをConvertFrom-Jsonでパース
2. pathspec除外式の構築
   └─ ContainsFilters: 先頭"/"を除去
   └─ SuffixFilters: **/*{suffix} と *{suffix} の2パターン生成
   └─ PrefixFilters: **/{prefix}* と {prefix}* の2パターン生成
   └─ 各エントリに ":(top,exclude)" プレフィックスを付与
3. git logコマンド実行
   └─ --first-parent --pretty=format:%an%x1C%ae%x1C%s で著者名・メール・件名を取得
   └─ -- $Excludes で除外パスを指定
4. CSV変換
   └─ ConvertFrom-CSV -Delimiter "\u001C" でパース
5. メールアドレスによるグループ化
   └─ Group Email でコミッターごとにグループ化
6. コミットメッセージのマングリング
   └─ Microsoft社員: PR番号を (GH-XXX) に変換
   └─ コミュニティ: PR番号を (CC-XXX) に変換
   └─ Issue番号 #XXX を GH-XXX に変換
7. マージコミット除外
   └─ "Merge"で始まるコミットをスキップ
8. 整形出力
   └─ 著者名 (コミット数) + 各コミットメッセージをリスト表示
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[consolegit2gitfilters.json読み込み]
    B --> C[pathspec除外式構築]
    C --> D[git log実行（除外パス付き）]
    D --> E[CSV形式でパース]
    E --> F[メールアドレスでグループ化]
    F --> G[各コミットを処理]
    G --> H{マージコミット?}
    H -->|Yes| I[スキップ]
    H -->|No| J{Microsoft社員?}
    J -->|Yes| K[PR番号をGH-XXXに変換]
    J -->|No| L[PR番号をCC-XXXに変換]
    K --> M[Issue番号をGH-XXXに変換]
    L --> M
    M --> N[整形してリスト出力]
    I --> O{次のコミット?}
    N --> O
    O -->|あり| G
    O -->|なし| P[バッチ終了]
```

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

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

データベース操作は行わない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | - | - | - |

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル未検出 | consolegit2gitfilters.jsonが存在しない場合 | リポジトリルートにファイルを配置する |
| - | git実行エラー | gitリポジトリ外で実行した場合 | gitリポジトリ内で実行する |
| - | リビジョン範囲エラー | 不正なリビジョン範囲を指定した場合 | 有効なリビジョン範囲を指定する |

### リトライ仕様

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

### 障害時対応

gitリポジトリの状態を確認し、consolegit2gitfilters.jsonの存在を確認する。RevisionRangeパラメータの妥当性を検証する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | リビジョン範囲に依存（数件〜数百件） |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

排他制御は不要。読み取り専用のgit操作のみを行う。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| Verbose | フィルタ構築時 | `IGNORING: {excludes}` |
| Verbose | ログ取得後 | `{count} unfiltered log entries` |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 該当なし | - | - |

## 備考

- Microsoft社員の判定は `*@microsoft.com` メールアドレスで行う（Test-MicrosoftPerson関数）
- git logの出力区切り文字にUnit Separator（\x1C / U+001C）を使用している
- --first-parentフラグにより、マージコミットの第一親のみを辿る
- consolegit2gitfilters.jsonの3種類のフィルタ:
  - ContainsFilters: パス先頭一致（"/"で始まる）
  - SuffixFilters: ファイル名サフィックス一致
  - PrefixFilters: ファイル名プレフィックス一致
- MITライセンス下のスクリプトである
- ソースファイル: `tools/Get-OSSConhostLog.ps1`
