mcpField
M
multi-repo-git-ops

multi-repo-git-ops

github.com/bmad-labs開発1995 回インストール6 日前に更新
リポジトリ

multi-repo-git-ops について

multi-repo-git-opsは、親リポジトリとGitサブモジュールで構成されたプロジェクト向けのスキルです。リポジトリの把握、サービスごとのブランチやコミット管理を案内し、該当する場合はBMADのストーリー運用にも対応します。

主な機能

  1. 01サブモジュールと追跡ブランチの検出
  2. 02変更対象リポジトリの特定
  3. 03複数サービス間のブランチ調整
  4. 04コミット・プッシュ・プルリクエストの案内
  5. 05BMADストーリーに沿ったGit操作

活用シーン

  1. 01複数サービスリポジトリでの作業開始
  2. 02複数サービスにまたがるBMADストーリーの実装
  3. 03サービス変更のレビューとマージ準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bmad-labs/skills --skill multi-repo-git-ops

インストール後、Claude Code で/multi-repo-git-opsを入力して読み込まれたか確認します。

詳細

マルチリポジトリの Git 操作

このスキルは、Git サブモジュールを使用するマルチリポジトリシステムでの Git 操作を扱います。親リポジトリが複数のサービスリポジトリを統括します。各サービスリポジトリは、それぞれ独自のブランチ、履歴、CI/CD を持つ独立した Git リポジトリです。

この構造を理解することが重要です。ここでの Git 操作では、どのリポジトリに影響するかを判断し、それぞれで正しく操作する必要があります。

検出プロトコル

Git 操作を実行する前に、プロジェクトの構造を動的に検出してください。サービス名、ブランチの対応関係、ディレクトリ構成を決めつけず、必ず .gitmodules を読み取ってください。

手順 1:サブモジュールとそのパスを特定する
# List all submodules with their paths
git config -f .gitmodules --get-regexp '\.path$'
手順 2:各サブモジュールが追跡するブランチを特定する
# List all submodule branch mappings
git config -f .gitmodules --get-regexp '\.branch$'

# Get a specific service's default branch
git config -f .gitmodules submodule."{submodule-path}".branch

サブモジュールのブランチが .gitmodules に設定されていない場合は、リモートを確認してください。

cd {submodule-path}
git remote show origin | grep 'HEAD branch'
手順 3:プロジェクトの手法を検出する
  • BMAD:_bmad-output/implementation-artifacts/ ディレクトリが存在するか確認します
  • BMAD が検出された場合は、BMAD 統合のセクションを適用します
手順 4:検出した情報をセッション中にキャッシュする

検出後、エージェントは以下を把握します。

  • すべてのサブモジュール名とパス
  • 各サブモジュールのデフォルトブランチ
  • BMAD が使用されているかどうか
  • サブモジュールのディレクトリ接頭辞(一般的には services/)

セッション中の以降のすべての操作では、このキャッシュ済み情報を使用してください。

リポジトリ構成

一般的なマルチリポジトリプロジェクトは、次のような構成です。

{parent-repo}/                       (parent repo — planning & orchestration only)
├── .gitmodules                      (submodule definitions with tracked branches)
├── services/                        (submodule repos — directory name may vary)
│   ├── auth-service/                (branch: develop)
│   ├── booking-service/             (branch: dev)
│   ├── config-repo/                 (branch: main)
│   └── ...
└── [project methodology dirs]       (e.g., _bmad-output/ if using BMAD)

重要な原則:親リポジトリが追跡するのは、各サブモジュールのコードそのものではなく、コミットへのポインターです。サービスのコードを変更した場合は、サービスリポジトリでコミットしてから、親リポジトリのポインターを更新します。

ブランチの規約

サービスごとのデフォルトブランチ

サービスごとに追跡するデフォルトブランチが異なる場合があります。ブランチを作成する前に、必ず正しいブランチを確認してください。

# Get a service's default branch (always use this — never assume)
git config -f .gitmodules submodule."{submodule-path}".branch

同じプロジェクト内でも、サービスによって異なるデフォルトブランチ(例:develop、dev、main)を使用することがよくあります。信頼できる唯一の情報源は .gitmodules です。

フィーチャーブランチの命名

チケットベースの作業(JIRA/プロジェクトトラッカー)の場合:

{type}/{TICKET-ID}-{short-description}

例:feat/PROJ-1234-add-search-by-date、bugfix/PROJ-5678-fix-null-pointer

BMAD ストーリーの作業(ストーリーファイル名に基づく)の場合:

feat/{story-key}

ストーリーキーはストーリーファイル名から取得します。1-2-user-authentication.md という名前のストーリーファイル(エピック 1、ストーリー 2 を表す)の場合、ブランチ名は feat/1-2-user-authentication になります。

ブランチ種別の接頭辞:feat/、fix/、bugfix/、chore/、base/

BMAD 統合(該当する場合)

このセクションは、プロジェクトで BMAD の手法を使用している場合にのみ適用されます。_bmad-output/implementation-artifacts/ ディレクトリがあるか確認して検出してください。

BMAD では、ストーリーファイルとスプリントステータスの追跡によって作業を管理します。このセクションでは、Git 操作と BMAD のライフサイクルの対応について説明します。

ストーリーがサービスを参照する方法

BMAD のストーリーファイルは _bmad-output/implementation-artifacts/{story-key}.md にあります。ストーリーでは、影響を受けるサービスがいくつかの方法で記載されているため、以下をすべて確認してください。

  1. ストーリーのタイトルまたは本文にあるサービスのタグ:[auth-service]、[scheduler-service]
  2. Dev Notes セクション:「変更対象となるソースツリーのコンポーネント」をサービスのパスとともに記載
  3. Project Structure Notes:services/{service-name}/src/... のようなパスを参照
  4. Tasks/Subtasks:個別のタスクで異なるサービスを参照する場合があります

ストーリーにサービスが明示的にタグ付けされていない場合は、Dev Notes と Tasks に記載されたファイルパスを確認し、どのサブモジュールディレクトリが関係するかを判断してください。

BMAD のステータスと Git 操作の対応

BMAD は _bmad-output/implementation-artifacts/sprint-status.yaml でストーリーのステータスを追跡します。ステータスの各遷移には、対応する Git 操作があります。

ストーリーのステータス変更必要な Git 操作
backlog → ready-for-devGit 操作なし(ストーリーファイルの作成のみ)
ready-for-dev → in-progress影響を受けるサービスでフィーチャーブランチを作成
in-progress(作業中)サービスのリポジトリで変更をコミット
in-progress → reviewすべてのサービスブランチをプッシュし、クリーンな状態であることを確認
review → in-progress(修正)同じブランチで作業を続け、修正をコミット
review → donePR をマージし、親のサブモジュールポインターを更新
BMAD ストーリーの開始(Git のセットアップ)

BMAD ストーリーの作業を始めるときは、次の Git 操作を行います。

ステップ 1:ストーリーを読み、サービスを特定する

# Story files follow pattern: {epic_num}-{story_num}-{slug}.md
# Example: _bmad-output/implementation-artifacts/1-2-user-authentication.md

ストーリーファイルを読みます。次の情報から、影響を受けるサービスを抽出します。

  • [auth-service] のようなサービスのタグ
  • Dev Notes 内のファイルパス(例:services/{service-name}/src/...)
  • 特定のサービスを参照するタスクの説明

ステップ 2:ストーリーキーからブランチ名を決める

# Story file: 1-2-user-authentication.md → branch: feat/1-2-user-authentication
STORY_KEY="1-2-user-authentication"  # from the story file name (without .md)
BRANCH_NAME="feat/${STORY_KEY}"

ステップ 3:影響を受けるすべてのサービスでブランチを作成する

# For each affected service (replace with actual discovered service names):
for SERVICE in auth-service scheduler-service; do
  DEFAULT_BRANCH=$(git config -f .gitmodules submodule."services/$SERVICE".branch)
  cd services/$SERVICE
  git checkout $DEFAULT_BRANCH
  git pull origin $DEFAULT_BRANCH
  git checkout -b $BRANCH_NAME
  git push -u origin $BRANCH_NAME
  cd ../..
done

追跡しやすいように、影響を受けるすべてのサービスで同じブランチ名を使用します。これにより、システム全体でストーリーに関連するすべての変更を簡単に見つけられます。

ステップ 4:セットアップを確認する

# Confirm all affected services are on the correct branch
git submodule foreach --quiet 'BRANCH=$(git branch --show-current); echo "$(basename $(pwd)): $BRANCH"'
ストーリーの実装中

変更のコミット — 必ずサービスのディレクトリ内でコミットします。

cd services/{service-name}
git add {specific-files}
git commit -m "feat({scope}): add validation for booking dates

Story: {story-key}"

複数のサービスにまたがる作業 — 各サービスで個別にコミットします。

# Service A
cd services/auth-service
git add src/auth/jwt.service.ts src/auth/jwt.service.spec.ts
git commit -m "feat(auth): add JWT validation endpoint

Story: 1-2-user-authentication"

# Service B
cd ../bff-service
git add src/middleware/auth.middleware.ts
git commit -m "feat(middleware): add JWT auth middleware

Story: 1-2-user-authentication"

すべてのコミットは、以下のコミットメッセージ形式に従う必要があります。release-please が正しい変更履歴とバージョン更新を生成するために重要です。

ストーリーの完了(プッシュと PR)

ストーリーのレビュー準備ができたら、次の手順を実行します。

ステップ 1:影響を受ける各サービスで品質チェックを実行する

cd services/{service-name}
npm run lint
npm run format
npm run typecheck
npm test

ステップ 2:各サービスのフィーチャーブランチをプッシュする

# Push services first — always before parent
cd services/{service-name}
git push origin feat/{story-key}

ステップ 3:サービスごとに PR を作成する サービスごとに個別の PR を作成します:feat/{story-key} → サービスのデフォルトブランチ。

PR のタイトル形式:feat({story-key}): {story title} PR の本文ではストーリーを参照します:Story: {epic_num}.{story_num} - {title}

ステップ 4:PR のマージ後、親を更新する

# For each merged service:
cd services/{service-name}
git checkout {default-branch}
git pull origin {default-branch}
cd ../..

# Update parent pointers (use actual discovered service paths)
git add services/auth-service services/bff-service
git commit -m "chore: update submodule pointers after story {story-key}

Services updated:
- auth-service
- bff-service"

コミットメッセージ形式(release-please 互換)

プロジェクトで、バージョン管理と変更履歴の生成を自動化するために release-please を使用している場合は、release-please がバージョン更新を正しく判定し、意味のある変更履歴を生成できるよう、すべてのコミットメッセージが Conventional Commits の仕様に従う必要があります。

release-please を使用していない場合でも、多数のリポジトリにわたって整然とした解析可能な Git 履歴を作成できるため、複数リポジトリのシステムでは Conventional Commits が推奨形式です。

AI の共著者トレーラーは禁止

AI エージェントのコミットメッセージに Co-Authored-By トレーラーを絶対に追加しないでください。 つまり、次のような行を追加してはいけません。

Co-Authored-By: Claude <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

コミットメッセージには、以下で説明する Conventional Commit の構造のみを含めてください。コミットへの AI の帰属情報は変更履歴を汚し、Git 履歴にノイズを加えるだけで、何の価値もありません。このルールは、機能追加、修正、雑務、その他あらゆるコミットに適用されます。

構造
<type>(<scope>): <description>

[optional body]

[optional footer(s)]

ヘッダーのルール:

  • type — 必須(以下の type テーブルを参照)
  • scope — 任意。影響を受けるコードのセクションを表す名詞を括弧内に記述します
  • description — 必須。: の直後に記述します
    • 命令形の現在形を使います。"added" や "adds" ではなく "add" とします
    • 先頭の文字を大文字にしません
    • 末尾にピリオドを付けません
    • 約 100 文字以内に収めます

本文 — 任意。ヘッダーとの間に空行を入れます。「何を」「なぜ」を説明する自由形式のテキストです。

フッター — 任意。本文との間に空行を入れます。破壊的変更、ストーリーの参照、その他のメタデータに使用します。

コミットの種類とバージョンの更新

Release-please は、バージョン更新に対応する種類のコミット、つまりリリース対象となる単位を検出した場合にのみリリースを作成します。適切な種類を選ぶことが重要です。リリースされるバージョンと変更履歴に表示される内容が直接決まるためです。

リリース対象の種類(リリースをトリガーします)
種類SemVer の更新使用する場面
featマイナー(0.x.0)新しい機能、エンドポイント、UI コンポーネント
fixパッチ(0.0.x)既存機能のバグ修正
depsパッチ(0.0.x)依存関係の更新(package.json、ロックファイル)
リリース対象外の種類(単独ではリリースをトリガーしません)
種類使用する場面
refactor動作を変えないコードの再構成
perfパフォーマンスの改善(特別なリファクタリング)
testテストの追加または修正
docsドキュメントのみの変更
styleコードスタイル(フォーマット、空白、セミコロン)
choreメンテナンスタスク(.gitignore、設定、ツール)
buildビルドシステム、依存関係、プロジェクトのバージョン
ciCI/CD パイプラインとワークフローの変更

前回のリリース以降、リリース対象外の種類のコミットしかない場合、リリース PR は作成されません。種類は意図的に選んでください。実際には feat: や fix: に当たる変更に chore: を使わないでください。

適切な種類の選び方
New capability or feature?           → feat
Fixing a bug?                        → fix
Dependency update?                   → deps
Performance improvement?             → perf
Code restructuring, no behavior Δ?   → refactor
Documentation only?                  → docs
Tests only?                          → test
CI/CD or build changes?              → ci / build
Everything else (configs, tooling)?  → chore
破壊的変更(メジャー更新)

破壊的変更を含むコミットは、種類にかかわらずメジャーバージョンへの更新をトリガーします。形式は 2 種類あります。

オプション A — ヘッダーに ! を付ける:

feat(api)!: redesign authentication flow

BREAKING CHANGE: the /auth/login endpoint now requires OAuth2 tokens
instead of API keys. All existing integrations must migrate.

オプション B — フッターのみ:

refactor(database): migrate from MongoDB to PostgreSQL

BREAKING CHANGE: all database connection strings must be updated.
The MongoDB driver is no longer included.

フッターでは BREAKING CHANGE(スペース)と BREAKING-CHANGE(ハイフン)の両方が認識されます。

破壊的変更を示す場合は、! 形式を使う場合でも、移行への影響を説明する BREAKING CHANGE: フッターを必ず含めてください。利用者が変更すべき内容を把握するために読むのは、このフッターです。

スコープ

スコープは、影響を受けるコード領域を示します。変更履歴の整理に役立ち、モノレポ構成では変更を適切なパッケージに振り分けるためにも使われます。

適切なスコープ(コード領域を示すもの):

feat(auth): add JWT validation
fix(scheduler): correct cron expression parsing
refactor(booking): extract date utility

不適切なスコープ(アンチパターン):

fix(PROJ-1234): ...          ← ticket IDs are not scopes
feat(john): ...               ← people are not scopes

スコープにはドメイン名またはモジュール名(例:auth、booking、scheduler、middleware、config、migration)を使ってください。

ストーリーへの参照

BMAD を使用する場合、ストーリーキーはスコープではなく、コミットの本文またはフッターに含めてください。

feat(auth): add JWT validation endpoint

Implement token validation with RS256 signing.

Story: 1-2-user-authentication
Release-Please 専用フッター
フッター用途
BREAKING CHANGE: <desc>メジャーバージョンへの更新をトリガーします
Release-As: x.x.x特定のバージョン番号を指定します

Release-As の例 — 初回リリースや、複数のバージョンを連携して更新する場合に便利です。

chore: prepare v3.0.0 release

Release-As: 3.0.0
完全な例

シンプルな機能(マイナー更新):

feat(booking): add search by date range endpoint

詳細を含むバグ修正(パッチ更新):

fix(auth): resolve token refresh race condition

The refresh token was being invalidated before the new access token
was issued, causing a brief window where requests would fail.

Story: 2-3-auth-improvements

破壊的変更(メジャー更新):

feat(api)!: remove deprecated v1 booking endpoints

BREAKING CHANGE: all /api/v1/bookings/* endpoints are removed.
Consumers must migrate to /api/v2/bookings/* which uses the new
pagination format.

Story: 3-1-api-v2-migration

依存関係の更新(パッチ更新):

deps: upgrade @nestjs/core to v11.0.0

テストのみの変更(リリースなし):

test(scheduler): add unit tests for cron expression parser

雑務(リリースなし):

chore: update .gitignore to exclude coverage reports
親リポジトリのコミットメッセージ

親リポジトリでサブモジュールのポインターを更新する場合、親リポジトリ自体の機能変更ではないため、chore: を使ってください。

chore: update submodule pointers after story 1-2-user-authentication

Services updated:
- auth-service
- bff-service

一般的な操作のリファレンス

機能ブランチの作成(BMAD 以外)

BMAD ストーリーに紐づかないアドホックな作業の場合:

DEFAULT_BRANCH=$(git config -f .gitmodules submodule."{submodule-path}".branch)
cd {submodule-path}
git checkout $DEFAULT_BRANCH
git pull origin $DEFAULT_BRANCH
git checkout -b feat/{TICKET-ID}-{description}
git push -u origin feat/{TICKET-ID}-{description}
すべてのサブモジュールを同期
# Pull parent and update all submodule pointers
git pull origin main
git submodule update --recursive

# OR: Pull latest from each submodule's tracked branch
git submodule foreach 'git pull origin $(git config -f $toplevel/.gitmodules submodule.$name.branch)'
すべてのリポジトリのステータスを確認
# Quick status: show only services with changes or non-default branches
git submodule foreach --quiet \
  'STATUS=$(git status --porcelain); BRANCH=$(git branch --show-current); DEFAULT=$(git config -f $toplevel/.gitmodules submodule.$name.branch); if [ -n "$STATUS" ] || [ "$BRANCH" != "$DEFAULT" ]; then echo "$(basename $(pwd)) [$BRANCH]: $([ -n "$STATUS" ] && echo "has changes" || echo "clean, non-default branch")"; fi'
サービスをデフォルトブランチに戻す
DEFAULT_BRANCH=$(git config -f .gitmodules submodule."{submodule-path}".branch)
cd {submodule-path}
git checkout $DEFAULT_BRANCH
git pull origin $DEFAULT_BRANCH

CI/CD の把握

マルチリポジトリシステムでは、プッシュ時に何が起きるかを理解することが重要です。一般的なブランチとデプロイ先の対応関係は次のとおりです。

ブランチプッシュ時の一般的な影響
develop / dev開発環境に自動デプロイされる可能性があります — 必ず事前にユーザーに確認してください
main安定版の参照先 — デプロイワークフローを利用できます
test、stage、releaseworkflow_dispatch による手動デプロイ
feat/*、base/*CI が実行されます(lint、テスト、ビルド)が、デプロイは行われません

実際のデプロイ動作は、プロジェクトの CI/CD 設定によって異なります。サブモジュールに共通の CI/CD ワークフローリポジトリが含まれているかを確認し、どのブランチがデプロイを開始するのかをユーザーに確認してください。

安全規則

以下の規則に従うことで、マルチリポジトリシステムでよくあるミスを防げます。

  1. 必ず親リポジトリより先にサービスリポジトリをプッシュしてください — 親リポジトリを先にプッシュすると、サブモジュールのポインターが壊れ、他の開発者のチェックアウトに支障が出ます
  2. 共有のデフォルトブランチ(develop、dev、main)には絶対に強制プッシュしないでください — これらは共有ブランチです
  3. デプロイを開始するブランチにプッシュする前に、必ずユーザーに確認してください
  4. フィーチャーブランチを作成する前に、サービスのデフォルトブランチを確認してください — サービスごとに異なり、誤ったベースからブランチを作成するとマージコンフリクトが発生します
  5. サービスリポジトリでは、git add . や git add -A を絶対に使用しないでください — シークレットやビルド成果物のコミットを避けるため、必ず特定のファイルを追加してください
  6. どのリポジトリでも、.env、認証情報、シークレット、node_modules を絶対にコミットしないでください
  7. 複数サービスにまたがるストーリーでは、すべてのサービスで同じブランチ名を使用してください — これにより追跡が容易になります
  8. Git 操作によってストーリーの状態が変わった場合(ブランチ作成 → in-progress、レビュー用にプッシュ → review)、sprint-status.yaml を更新してください — BMAD を使用している場合のみ
  9. コミットメッセージに AI エージェントの Co-Authored-By トレーラーを絶対に追加しないでください — Claude、Copilot、その他の AI による帰属表示は避けてください。これらは変更履歴や Git 履歴を汚します。コミットメッセージには、Conventional Commits の形式(type、scope、description、body、破壊的変更/ストーリー参照用の footers)のみを含めてください
  10. すべてのコミットメッセージは Conventional Commits 形式にしてください — release-please は自動バージョン管理と変更履歴の生成にこの形式を使用します。不正な形式のコミットメッセージは、リリースの漏れや誤ったバージョン更新につながる可能性があります

コメント