multi-repo-git-ops

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Multi-Repo Git Operations

多仓库Git操作

This skill handles git operations in multi-repo systems that use git submodules. The parent repo orchestrates multiple service repos, each an independent git repository with its own branches, history, and CI/CD.
Understanding this structure is essential — git operations here always involve deciding which repos are affected and operating in each one correctly.
本技能处理使用git子模块的多仓库系统中的git操作。父仓库协调管理多个服务仓库,每个服务仓库都是独立的git仓库,拥有自己的分支、提交历史和CI/CD。
理解该结构至关重要——此处的git操作始终需要先确定哪些仓库受影响,并在每个仓库中正确执行操作。

Discovery Protocol

发现协议

Before performing any git operations, discover the project structure dynamically. Never assume service names, branch mappings, or directory layout — always read from
.gitmodules
.
执行任何git操作前,先动态探查项目结构。永远不要假设服务名称、分支映射或目录布局——始终从
.gitmodules
文件中读取配置。

Step 1: Identify submodules and their paths

步骤1:识别子模块及其路径

bash
undefined
bash
undefined

List all submodules with their paths

列出所有子模块及其路径

git config -f .gitmodules --get-regexp '.path$'
undefined
git config -f .gitmodules --get-regexp '.path$'
undefined

Step 2: Identify each submodule's tracked branch

步骤2:识别每个子模块的跟踪分支

bash
undefined
bash
undefined

List all submodule branch mappings

列出所有子模块的分支映射

git config -f .gitmodules --get-regexp '.branch$'
git config -f .gitmodules --get-regexp '.branch$'

Get a specific service's default branch

获取特定服务的默认分支

git config -f .gitmodules submodule."{submodule-path}".branch

If a submodule has no branch configured in `.gitmodules`, check the remote:
```bash
cd {submodule-path}
git remote show origin | grep 'HEAD branch'
git config -f .gitmodules submodule."{submodule-path}".branch

如果子模块未在`.gitmodules`中配置分支,则检查远程仓库:
```bash
cd {submodule-path}
git remote show origin | grep 'HEAD branch'

Step 3: Detect project methodology

步骤3:检测项目方法论

  • BMAD: Check if
    _bmad-output/implementation-artifacts/
    directory exists
  • If BMAD is detected, the BMAD Integration section applies
  • BMAD:检查是否存在
    _bmad-output/implementation-artifacts/
    目录
  • 如果检测到BMAD,则适用BMAD集成部分的规则

Step 4: Cache discovered info for the session

步骤4:在会话中缓存探查得到的信息

After discovery, the agent knows:
  • All submodule names and paths
  • Each submodule's default branch
  • Whether BMAD is in use
  • The submodule directory prefix (commonly
    services/
    )
Use this cached information for all subsequent operations in the session.
探查完成后,Agent将知晓:
  • 所有子模块名称和路径
  • 每个子模块的默认分支
  • 是否使用BMAD
  • 子模块目录前缀(通常为
    services/
会话中所有后续操作都将使用该缓存信息。

Repository Structure

仓库结构

A typical multi-repo project looks like this:
{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)
Key principle: The parent repo tracks commit pointers to each submodule, not the submodule code itself. When you change code in a service, you commit in the service repo, then update the parent's pointer.
典型的多仓库项目结构如下:
{parent-repo}/                       (父仓库——仅用于规划和协调)
├── .gitmodules                      (子模块定义及跟踪分支配置)
├── services/                        (子模块仓库——目录名称可能不同)
│   ├── auth-service/                (分支: develop)
│   ├── booking-service/             (分支: dev)
│   ├── config-repo/                 (分支: main)
│   └── ...
└── [项目方法论目录]       (例如,使用BMAD时的 _bmad-output/)
核心原则:父仓库跟踪每个子模块的提交指针,而非子模块的代码本身。当你修改服务中的代码时,先在服务仓库提交,再更新父仓库的指针。

Branch Conventions

分支规范

Default Branches by Service

各服务的默认分支

Services may track different default branches — always look up the correct one before branching:
bash
undefined
不同服务可能跟踪不同的默认分支——创建分支前务必查询正确的默认分支:
bash
undefined

Get a service's default branch (always use this — never assume)

获取服务的默认分支(始终使用该结果,永远不要假设)

git config -f .gitmodules submodule."{submodule-path}".branch

Different services in the same project often use different default branches (e.g., `develop`, `dev`, `main`). The only reliable source of truth is `.gitmodules`.
git config -f .gitmodules submodule."{submodule-path}".branch

同一项目中的不同服务通常使用不同的默认分支(例如`develop`、`dev`、`main`)。唯一可靠的信息来源是`.gitmodules`文件。

Feature Branch Naming

特性分支命名

For ticket-based work (JIRA/project tracker):
{type}/{TICKET-ID}-{short-description}
Examples:
feat/PROJ-1234-add-search-by-date
,
bugfix/PROJ-5678-fix-null-pointer
For BMAD story work (derived from story file name):
feat/{story-key}
The story key comes from the story file name. A story file named
1-2-user-authentication.md
(representing Epic 1, Story 2) produces branch name
feat/1-2-user-authentication
.
Branch type prefixes:
feat/
,
fix/
,
bugfix/
,
chore/
,
base/
基于工单的工作(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 Integration (If Applicable)

BMAD集成(如适用)

This section applies only if the project uses the BMAD methodology. Detect this by checking for the
_bmad-output/implementation-artifacts/
directory.
BMAD manages work through story files and sprint status tracking. This section explains how git operations map to the BMAD lifecycle.
本部分仅适用于使用BMAD方法论的项目,可通过检查
_bmad-output/implementation-artifacts/
目录是否存在来检测。
BMAD通过故事文件和冲刺状态跟踪来管理工作,本部分说明git操作如何对应BMAD生命周期。

How Stories Reference Services

故事如何关联服务

BMAD story files live at
_bmad-output/implementation-artifacts/{story-key}.md
. Stories reference affected services in several ways — check all of these:
  1. Service tags in story title or body:
    [auth-service]
    ,
    [scheduler-service]
  2. Dev Notes section: Lists "Source tree components to touch" with service paths
  3. Project Structure Notes: References paths like
    services/{service-name}/src/...
  4. Tasks/Subtasks: Individual tasks may reference different services
When a story doesn't explicitly tag services, look at the file paths mentioned in Dev Notes and Tasks to determine which submodule directories are involved.
BMAD故事文件存放在
_bmad-output/implementation-artifacts/{story-key}.md
。故事通过多种方式关联受影响的服务,请检查所有以下项:
  1. 故事标题或正文中的服务标签
    [auth-service]
    [scheduler-service]
  2. 开发笔记部分:列出「需要修改的源码树组件」及服务路径
  3. 项目结构说明:引用类似
    services/{service-name}/src/...
    的路径
  4. 任务/子任务:单个任务可能引用不同的服务
当故事未明确标记服务时,查看开发笔记和任务中提到的文件路径,以确定涉及哪些子模块目录。

BMAD Status and Git Operations Mapping

BMAD状态与Git操作映射

BMAD tracks story status in
_bmad-output/implementation-artifacts/sprint-status.yaml
. Each status transition has corresponding git operations:
Story Status ChangeGit Operations Required
backlog
ready-for-dev
No git ops (story file creation only)
ready-for-dev
in-progress
Create feature branches in affected services
in-progress
(ongoing work)
Commit changes in service repos
in-progress
review
Push all service branches, ensure clean state
review
in-progress
(fixes)
Continue on same branches, commit fixes
review
done
PRs merged, update parent submodule pointers
BMAD在
_bmad-output/implementation-artifacts/sprint-status.yaml
中跟踪故事状态,每个状态转换都有对应的git操作:
故事状态变更所需Git操作
backlog
ready-for-dev
无git操作(仅创建故事文件)
ready-for-dev
in-progress
在受影响的服务中创建特性分支
in-progress
(进行中工作)
在服务仓库中提交变更
in-progress
review
推送所有服务分支,确保状态干净
review
in-progress
(修复问题)
在相同分支上继续工作,提交修复
review
done
PR合并完成,更新父仓库的子模块指针

Starting a BMAD Story (Git Setup)

启动BMAD故事(Git配置)

When beginning work on a BMAD story, perform these git operations:
Step 1: Read the story and identify services
bash
undefined
开始处理BMAD故事时,执行以下git操作:
步骤1:读取故事并识别服务
bash
undefined

Story files follow pattern: {epic_num}-{story_num}-{slug}.md

故事文件遵循格式:{epic_num}-{story_num}-{slug}.md

Example: _bmad-output/implementation-artifacts/1-2-user-authentication.md

示例:_bmad-output/implementation-artifacts/1-2-user-authentication.md


Read the story file. Extract affected services from:
- Service tags like `[auth-service]`
- File paths in Dev Notes (e.g., `services/{service-name}/src/...`)
- Task descriptions referencing specific services

**Step 2: Derive the branch name from the story key**
```bash

读取故事文件,从以下位置提取受影响的服务:
- 服务标签,如`[auth-service]`
- 开发笔记中的文件路径(例如`services/{service-name}/src/...`)
- 引用特定服务的任务描述

**步骤2:从故事键派生分支名**
```bash

Story file: 1-2-user-authentication.md → branch: feat/1-2-user-authentication

故事文件:1-2-user-authentication.md → 分支:feat/1-2-user-authentication

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

**Step 3: Create branches in all affected services**
```bash
STORY_KEY="1-2-user-authentication" # 来自故事文件名(不含.md后缀) BRANCH_NAME="feat/${STORY_KEY}"

**步骤3:在所有受影响的服务中创建分支**
```bash

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

Use the **same branch name** across all affected services for traceability. This makes it easy to find all changes related to a story across the system.

**Step 4: Verify setup**
```bash
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:验证配置**
```bash

Confirm all affected services are on the correct branch

确认所有受影响的服务都在正确的分支上

git submodule foreach --quiet 'BRANCH=$(git branch --show-current); echo "$(basename $(pwd)): $BRANCH"'
undefined
git submodule foreach --quiet 'BRANCH=$(git branch --show-current); echo "$(basename $(pwd)): $BRANCH"'
undefined

During Story Implementation

故事实现过程中

Committing changes — always commit inside the service directory:
bash
cd services/{service-name}
git add {specific-files}
git commit -m "feat({scope}): add validation for booking dates

Story: {story-key}"
Working across multiple services — commit in each separately:
bash
undefined
提交变更——始终在服务目录内提交:
bash
cd services/{service-name}
git add {specific-files}
git commit -m "feat({scope}): add validation for booking dates

Story: {story-key}"
跨多个服务工作——分别在每个服务中提交:
bash
undefined

Service A

服务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"
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

服务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"

All commits must follow the **Commit Message Format** section below — this is critical for release-please to generate correct changelogs and version bumps.
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生成正确的变更日志和版本号至关重要。

Completing a Story (Push & PR)

完成故事(推送与PR)

When story is ready for review:
Step 1: Run quality checks in each affected service
bash
cd services/{service-name}
npm run lint
npm run format
npm run typecheck
npm test
Step 2: Push each service's feature branch
bash
undefined
故事准备好评审时:
步骤1:在每个受影响的服务中运行质量检查
bash
cd services/{service-name}
npm run lint
npm run format
npm run typecheck
npm test
步骤2:推送每个服务的特性分支
bash
undefined

Push services first — always before parent

先推送服务仓库——始终早于父仓库

cd services/{service-name} git push origin feat/{story-key}

**Step 3: Create PR per service**
Each service gets its own PR: `feat/{story-key}` → service's default branch.

PR title format: `feat({story-key}): {story title}`
PR body should reference the story: `Story: {epic_num}.{story_num} - {title}`

**Step 4: After PRs are merged, update parent**
```bash
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合并后更新父仓库**
```bash

For each merged service:

对每个已合并的服务:

cd services/{service-name} git checkout {default-branch} git pull origin {default-branch} cd ../..
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"
undefined
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"
undefined

Commit Message Format (Release-Please Compatible)

提交信息格式(兼容Release-Please)

If the project uses release-please for automated versioning and changelog generation, every commit message must follow the Conventional Commits specification so release-please can correctly determine version bumps and produce meaningful changelogs.
Even without release-please, Conventional Commits is the recommended format for multi-repo systems because it produces clean, parseable git history across many repositories.
如果项目使用release-please实现自动化版本管理和变更日志生成,每条提交信息必须遵循Conventional Commits规范,以便release-please正确判断版本升级幅度并生成有意义的变更日志。
即使不使用release-please,Conventional Commits也是多仓库系统的推荐格式,因为它能在多个仓库中生成清晰、可解析的git历史。

No AI Co-Author Trailers

禁止AI共同作者尾部信息

NEVER add
Co-Authored-By
trailers for AI agents in commit messages.
This means no lines like:
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Commit messages must only contain the conventional commit structure described below. AI attribution in commits pollutes changelogs, adds noise to git history, and provides no value. This rule applies to all commits — feature, fix, chore, or otherwise.
永远不要在提交信息中添加AI Agent的
Co-Authored-By
尾部信息,即不要出现如下内容:
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
提交信息必须仅包含下文描述的约定式提交结构。提交中的AI属性会污染变更日志,为git历史增加无用信息,没有任何价值。该规则适用于所有提交——特性、修复、日常维护等所有类型。

Structure

结构

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

[optional body]

[optional footer(s)]
Header rules:
  • type
    — required (see type table below)
  • scope
    — optional, a noun describing the affected code section in parentheses
  • description
    — required, immediately after
    : 
    • Use imperative, present tense: "add" not "added" or "adds"
    • Do not capitalize the first letter
    • Do not end with a period
    • Keep under ~100 characters
Body — optional, separated from header by a blank line. Free-form, explains the "what" and "why".
Footer(s) — optional, separated from body by a blank line. Used for breaking changes, story references, and other metadata.
<type>(<scope>): <description>

[optional body]

[optional footer(s)]
头部规则:
  • type
    — 必填(参见下方类型表)
  • scope
    — 可选,括号内为描述受影响代码区域的名词
  • description
    — 必填,紧跟在
    : 
    之后
    • 使用祈使句、现在时:用「add」而非「added」或「adds」
    • 首字母不要大写
    • 不要以句号结尾
    • 长度控制在约100字符以内
正文 — 可选,与头部之间空一行。自由格式,说明变更的「内容」和「原因」。
尾部信息 — 可选,与正文之间空一行。用于说明破坏性变更、故事引用及其他元数据。

Commit Types and Version Bumps

提交类型与版本升级

Release-please only creates a release when it detects releasable units — commits with types that map to a version bump. Choosing the right type matters because it directly controls what version gets released and what appears in the changelog.
Release-please仅在检测到可发布单元——即提交类型对应版本升级时才会创建发布。选择正确的类型非常重要,因为它直接控制发布的版本号以及变更日志中显示的内容。

Releasable types (trigger a release)

可发布类型(触发发布)

TypeSemVer BumpWhen to use
feat
Minor (0.x.0)New capability, endpoint, feature, UI component
fix
Patch (0.0.x)Bug fix for existing functionality
deps
Patch (0.0.x)Dependency updates (package.json, lock files)
类型SemVer升级幅度使用场景
feat
次版本 (0.x.0)新增功能、接口、特性、UI组件
fix
修订版本 (0.0.x)修复现有功能的bug
deps
修订版本 (0.0.x)依赖更新(package.json、锁文件)

Non-releasable types (won't trigger a release alone)

不可发布类型(不会单独触发发布)

TypeWhen to use
refactor
Code restructuring without behavior change
perf
Performance improvement (special refactoring)
test
Adding or correcting tests
docs
Documentation changes only
style
Code style (formatting, whitespace, semicolons)
chore
Maintenance tasks (.gitignore, configs, tooling)
build
Build system, dependencies, project version
ci
CI/CD pipeline and workflow changes
If you only commit non-releasable types since the last release, no release PR will be created. Be intentional — don't use
chore:
when the change is actually a
feat:
or
fix:
.
类型使用场景
refactor
代码重构,无行为变更
perf
性能优化(特殊的重构)
test
添加或修正测试
docs
仅文档变更
style
代码风格(格式、空格、分号)
chore
维护任务(.gitignore、配置、工具)
build
构建系统、依赖、项目版本
ci
CI/CD流水线和工作流变更
如果自上次发布以来仅提交了不可发布类型的内容,则不会创建发布PR。请有意识地选择类型——如果变更实际是
feat:
fix:
,不要使用
chore:

Choosing the right type

选择正确的类型

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
新增功能或特性?           → feat
修复bug?                  → fix
依赖更新?                 → deps
性能优化?                 → perf
代码重构,无行为变更?      → refactor
仅文档变更?               → docs
仅测试变更?               → test
CI/CD或构建变更?          → ci / build
其他所有情况(配置、工具)?→ chore

Breaking Changes (Major Bump)

破坏性变更(主版本升级)

Any commit type with a breaking change triggers a major version bump. Two formats:
Option A —
!
in the header:
feat(api)!: redesign authentication flow

BREAKING CHANGE: the /auth/login endpoint now requires OAuth2 tokens
instead of API keys. All existing integrations must migrate.
Option B — footer only:
refactor(database): migrate from MongoDB to PostgreSQL

BREAKING CHANGE: all database connection strings must be updated.
The MongoDB driver is no longer included.
Both
BREAKING CHANGE
(space) and
BREAKING-CHANGE
(hyphen) are recognized in footers.
When marking a breaking change, always include a
BREAKING CHANGE:
footer explaining the migration impact — even when using the
!
format. The footer is what consumers read to understand what they need to change.
任何包含破坏性变更的提交类型都会触发主版本升级,有两种格式:
选项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:
尾部信息说明迁移影响——即使使用了
!
格式。尾部信息是用户了解需要修改哪些内容的依据。

Scopes

范围

Scopes describe which code section is affected — they help organize changelogs and, in monorepo setups, route changes to the correct package.
Good scopes (describe code areas):
feat(auth): add JWT validation
fix(scheduler): correct cron expression parsing
refactor(booking): extract date utility
Bad scopes (these are anti-patterns):
fix(PROJ-1234): ...          ← ticket IDs are not scopes
feat(john): ...               ← people are not scopes
Use the domain or module name as the scope (e.g.,
auth
,
booking
,
scheduler
,
middleware
,
config
,
migration
).
范围描述受影响的代码区域——有助于组织变更日志,在monorepo配置中可将变更路由到正确的包。
好的范围示例(描述代码区域):
feat(auth): add JWT validation
fix(scheduler): correct cron expression parsing
refactor(booking): extract date utility
不好的范围示例(反模式):
fix(PROJ-1234): ...          ← 工单ID不是范围
feat(john): ...               ← 人员不是范围
使用领域或模块名称作为范围(例如
auth
booking
scheduler
middleware
config
migration
)。

Story References

故事引用

If using BMAD, include the story key in the commit body or footer, not in the scope:
feat(auth): add JWT validation endpoint

Implement token validation with RS256 signing.

Story: 1-2-user-authentication
如果使用BMAD,将故事键添加到提交的正文或尾部,不要放在范围中:
feat(auth): add JWT validation endpoint

Implement token validation with RS256 signing.

Story: 1-2-user-authentication

Special Release-Please Footers

特殊Release-Please尾部信息

FooterPurpose
BREAKING CHANGE: <desc>
Triggers major version bump
Release-As: x.x.x
Force a specific version number
Release-As
example
— useful for initial releases or coordinated version jumps:
chore: prepare v3.0.0 release

Release-As: 3.0.0
尾部信息用途
BREAKING CHANGE: <desc>
触发主版本升级
Release-As: x.x.x
强制使用指定的版本号
Release-As
示例
——适用于首次发布或协调版本跳转:
chore: prepare v3.0.0 release

Release-As: 3.0.0

Complete Examples

完整示例

Simple feature (minor bump):
feat(booking): add search by date range endpoint
Bug fix with context (patch bump):
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
Breaking change (major bump):
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
Dependency update (patch bump):
deps: upgrade @nestjs/core to v11.0.0
Test-only change (no release):
test(scheduler): add unit tests for cron expression parser
Chore (no release):
chore: update .gitignore to exclude coverage reports
简单特性(次版本升级):
feat(booking): add search by date range endpoint
带上下文的bug修复(修订版本升级):
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

Parent Repo Commit Messages

父仓库提交信息

When updating submodule pointers in the parent repo, use
chore:
since these don't represent feature changes in the parent itself:
chore: update submodule pointers after story 1-2-user-authentication

Services updated:
- auth-service
- bff-service
在父仓库中更新子模块指针时,使用
chore:
类型,因为这些变更不代表父仓库本身的功能变更:
chore: update submodule pointers after story 1-2-user-authentication

Services updated:
- auth-service
- bff-service

General Operations Reference

通用操作参考

Create Feature Branch (Non-BMAD)

创建特性分支(非BMAD场景)

For ad-hoc work not tied to a BMAD story:
bash
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}
适用于不关联BMAD故事的临时工作:
bash
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}

Sync All Submodules

同步所有子模块

bash
undefined
bash
undefined

Pull parent and update all submodule pointers

拉取父仓库更新并更新所有子模块指针

git pull origin main git submodule update --recursive
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)'
undefined
git submodule foreach 'git pull origin $(git config -f $toplevel/.gitmodules submodule.$name.branch)'
undefined

Check Status Across All Repos

检查所有仓库的状态

bash
undefined
bash
undefined

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'
undefined
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'
undefined

Switch Service Back to Default Branch

将服务切回默认分支

bash
DEFAULT_BRANCH=$(git config -f .gitmodules submodule."{submodule-path}".branch)
cd {submodule-path}
git checkout $DEFAULT_BRANCH
git pull origin $DEFAULT_BRANCH
bash
DEFAULT_BRANCH=$(git config -f .gitmodules submodule."{submodule-path}".branch)
cd {submodule-path}
git checkout $DEFAULT_BRANCH
git pull origin $DEFAULT_BRANCH

CI/CD Awareness

CI/CD注意事项

Understanding what happens when you push is critical in multi-repo systems. Typical branch-to-deployment mappings:
BranchTypical Push Effect
develop
/
dev
May auto-deploy to dev environment — confirm with user first
main
Stable reference — deployment workflows available
test
,
stage
,
release
Manual deployment via
workflow_dispatch
feat/*
,
base/*
CI runs (lint, test, build) but no deployment
Actual deployment behavior depends on the project's CI/CD configuration. Check if the project has a shared CI/CD workflow repository among its submodules, and confirm with the user which branches trigger deployments.
在多仓库系统中,了解推送后会发生什么至关重要。典型的分支-部署映射关系:
分支典型推送效果
develop
/
dev
可能自动部署到开发环境——先与用户确认
main
稳定参考分支——有部署工作流可用
test
stage
release
通过
workflow_dispatch
手动部署
feat/*
base/*
运行CI(检查、测试、构建)但不部署
实际部署行为取决于项目的CI/CD配置。检查项目的子模块中是否有共享的CI/CD工作流仓库,并与用户确认哪些分支会触发部署。

Safety Rules

安全规则

These rules prevent common mistakes in multi-repo systems:
  1. Always push service repos before parent — pushing parent first creates broken submodule pointers that break other developers' checkouts
  2. Never force-push to shared default branches (
    develop
    ,
    dev
    ,
    main
    ) — these are shared branches
  3. Confirm with user before pushing to deployment-triggering branches
  4. Check service's default branch before creating feature branches — they differ across services, and branching from the wrong base causes merge conflicts
  5. Never use
    git add .
    or
    git add -A
    in service repos — always add specific files to avoid committing secrets or build artifacts
  6. Never commit
    .env
    , credentials, secrets, or
    node_modules
    in any repo
  7. Same branch name across services for multi-service stories — enables traceability
  8. Update sprint-status.yaml when git operations change story state (branch created →
    in-progress
    , pushed for review →
    review
    ) — only if using BMAD
  9. Never add
    Co-Authored-By
    trailers for AI agents
    in commit messages — no Claude, Copilot, or any AI attribution. These pollute changelogs and git history. Commit messages must contain only the conventional commit structure (type, scope, description, body, footers for breaking changes/story refs)
  10. All commit messages must be Conventional Commits format — release-please depends on this for automated versioning and changelog generation. A malformed commit message can cause missed releases or incorrect version bumps
这些规则可避免多仓库系统中的常见错误:
  1. 始终先推送服务仓库,再推送父仓库——先推送父仓库会创建损坏的子模块指针,影响其他开发者的 checkout
  2. 永远不要强制推送到共享的默认分支(
    develop
    dev
    main
    )——这些是共享分支
  3. 推送到会触发部署的分支前与用户确认
  4. 创建特性分支前检查服务的默认分支——不同服务的默认分支不同,从错误的基础分支创建会导致合并冲突
  5. 在服务仓库中永远不要使用
    git add .
    git add -A
    ——始终添加指定文件,避免提交密钥或构建产物
  6. 任何仓库中永远不要提交
    .env
    、凭证、密钥或
    node_modules
  7. 多服务故事在所有服务中使用相同的分支名——便于追溯
  8. 当git操作变更故事状态时更新sprint-status.yaml(分支创建→
    in-progress
    ,推送评审→
    review
    )——仅使用BMAD时适用
  9. 提交信息中永远不要添加AI Agent的
    Co-Authored-By
    尾部信息
    ——不要添加Claude、Copilot或任何AI属性,这些会污染变更日志和git历史。提交信息必须仅包含约定式提交结构(类型、范围、描述、正文、破坏性变更/故事引用的尾部信息)
  10. 所有提交信息必须遵循Conventional Commits格式——release-please依赖该格式实现自动化版本管理和变更日志生成。格式错误的提交信息会导致发布遗漏或版本升级错误