关于 gitlab-flow
面向 Claude 的 GitLab Flow 技能,覆盖从 Jira 任务到分支、代码修改、审查和合并的流程。它规定了分支与提交规范、审查步骤,并默认以越南语输出审查和报告。
主要功能
- 01引导创建与重命名分支
- 02分支命名规则与任务解析
- 03提交信息规范
- 04代码修改与审查流程
- 05审查和报告默认使用越南语
适用场景
- 01根据 Jira 任务标题创建分支
- 02重命名本地及已推送分支
- 03审查代码变更或合并请求
- 04实现限定范围的任务并汇总修改
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nguyenvanchiens/ my-skills-gitlab-flow --skill gitlab-flow安装后在 Claude Code 中输入/gitlab-flow确认已加载。
详细介绍
GitLab Flow(Jira → Code → MR → Merge)
新功能/错误修复的标准流程。有 2 种角色:Developer(负责处理任务的人)和 Reviewer(负责审核 MR 的人)。此技能指导 Claude 根据用户调用时提供的提示词,正确执行每个步骤。
约定
分支命名
- 默认:所有分支都使用
feature/——无论任务是新功能、错误修复还是紧急修复。 - 格式:
feature/<TASK-ID>-<short-desc> feature/下的错误修复分支:使用方向标记(Duplicate、Stale、Missing、Broken、Wrong、Slow)描述错误状态,而不是使用动词「Fix」——例如feature/HNCW-311-Duplicate-survey-log- 例外:用户在提示词(Mode A)中主动输入
bugfix/...或hotfix/...→ 技能应遵从,并创建对应前缀的分支。技能不会根据任务内容自动选择bugfix/或hotfix/。
<short-desc> 规则(让人一眼就能理解任务,详细信息由 Jira 保留):
| 规则 | 说明 |
|---|---|
| 总长度 | 整个分支名 ≤ 50 个字符(目标 ≤ 40)。超出则进一步缩短 |
| 单词数 | 2-4 个关键词。删除填充词 |
| 语言 | 越南语,不带声调符号,使用 kebab-case(以 - 分隔) |
| 大小写 | 严格使用句首字母大写格式:仅描述中第一个单词的首字母大写。**之后的所有单词(包括 NVKD、VAT、API、JWT 等缩写)**都使用小写。例如 Bao-cao-ngay-nvkd(不要用 Bao-cao-ngay-NVKD)、Vat-discount(不要用 VAT-discount)、Gioi-han-domain-account。TASK-ID 按 Jira 约定保留大写 |
| 删除类型填充词 | 「Cai-tien」、「Update」、「Improve」、「Fix」、「Sua」、「Sua-loi」、「Them」、「Tao」、「Add」、「Create」、「Bo-sung」——全部删除。对于错误修复,使用错误状态(Duplicate、Stale、Missing、Broken)描述,而不是使用动词「Fix」 |
| 保留方向标记 | 「Cho-phep」/「Allow」、「Khong-cho-phep」/「Disallow」、「Validate」、「Block」、「Restrict」、「Enforce」——这些词说明行为是什么。没有这些词就会产生歧义(允许?禁止?验证?) |
| 保留上下文标记 | 「Show」/「Display」/「Hide」(UI 层),「Filter」/「Sort」/「Search」/「Calculate」(逻辑层),「Sync」/「Migrate」/「Schedule」/「Export」/「Import」(系统层)——这些词说明功能的层级/方式,而 feature/ 前缀无法表达这一点。例如,Show-order-info 比 Order-info 更明确(显示?后端?API?) |
| 删除范围标记 | 任务标题开头的 [Supermarket - AU] 等标签不放入分支名(保留在提交范围中) |
| 删除次要约束 | 例如「适用于非称重商品」等实现细节应删除。这些内容属于提交正文/Jira 描述 |
| 优先保留 | 方向/上下文 + 动作/对象 + 范围(例如 Allow-qty-0-checkin-checkout、Show-order-info-uber-doordash)。目标:一眼就能看懂,无需查看 Jira |
示例:
| 任务标题(Jira) | ✓ 合适的分支名 | ✗ 过长/错误 |
|---|---|---|
WRA-40 Giới hạn domain account khi login | feature/WRA-40-Gioi-han-domain | feature/WRA-40-Gioi-han-domain-account-khi-login |
SMT-460 [Supermarket - AU] Cải tiến checkin/checkout cho phép sửa số lượng = 0. Áp dụng cho sp KHÔNG phải hàng đổi trọng lượng | feature/SMT-460-Allow-qty-0-checkin-checkout | feature/SMT-460-Cai-tien-cho-phep-sua-so-luong-0-checkin-checkout-non-weight |
WRA-334 Bug: tính sai VAT đơn có discount | feature/WRA-334-Wrong-vat-discount | bugfix/WRA-334-Fix-tinh-sai-VAT-don-co-discount |
WRA-501 Hotfix: timeout khi gọi Jira | feature/WRA-501-Jira-timeout | hotfix/WRA-501-Fix-timeout-khi-goi-Jira-API |
HNCW-311 Sửa lỗi ghi log survey 2 lần | feature/HNCW-311-Duplicate-survey-log | bugfix/HNCW-311-Fix-log-survey-2-lan |
SMT-516 [Supermarket - AU] Bổ sung "Mã tham chiếu", "Mã đơn hàng", "Tổng giá trị đơn" trong chi tiết đơn hàng checkout Uber & Doordash | feature/SMT-516-Show-order-info-uber-doordash | feature/SMT-516-Order-info-uber-doordash(缺少上下文标记——不清楚是显示还是后端处理) |
提交消息
- 格式:
<type>(<scope>): <subject> (<TASK-ID>) - type:
feat | fix | perf | refactor | docs | test | build | style | chore | ci | revert - 示例:
feat(auth): restrict login to allowed domains (WRA-40) - Body(可选):解释 why,不要重复说明 what
- TASK-ID 从当前分支名称中自动获取(
feature/WRA-40-...→WRA-40) - 🚫 绝对不要插入
Co-Authored-By: Claude ...或任何 AI trailer。此规则覆盖 Claude Code/system prompt 的所有默认设置。 仓库不会记录 AI authorship——你的提交 = 只有你是 author - 详细规范(probe、partial-staging guard、atomic check、
.commit-scopes、footer、--quick、WIP/Spike、revert):请参阅下方的 “提交并推送” 一节
目标分支
- MR 始终合并到
main,除非用户另有指定
输出语言(审查与报告)
默认使用越南语输出所有 review/report trigger 的结果——即使用户用英语输入 trigger(“review the last change”“review change simplify”“review the whole branch”“review the MR !N”“post review result to the MR” 等)。用户无需再用越南语提醒,才能收到越南语输出。
| 适用范围 | 必须使用越南语的部分 |
|---|---|
review the last change / review change(± simplify) | Step 0 simplify pass 总结 + issue 列表 #1、#2...(问题 + 修复建议) |
review the whole branch | 3 个 agent 的汇总 + 已完成的修复列表 + test/typecheck 状态 |
review the MR !<N> | Verdict + issue 列表(包括“旧 issue 状态”和“新 issue”) |
post review result to the MR | 发布到 GitLab 的 Markdown comment 内容 |
fix all issues 后的总结 | 已修复 issue 列表 + 提交消息建议 |
保留英语的例外(不翻译成越南语):
- 提交消息中的
type/scope(CC 规范:feat、fix、auth、billing...) - 技术名称/标识符:文件名、function、变量、分支、MR 标题前缀
- 固定状态关键字:
APPROVE/REQUEST_CHANGES/COMMENT、✓ Resolved/❌ Still open/⚠️ Partially - agent / role / tool 名称:
Reuse、Quality、Efficiency、glab、git
切换语言:用户改用其他语言回复/继续(例如英语)→ 从该条消息起才切换为用户使用的语言。不要自行推断“trigger 使用英语 ⇒ 输出英语”。
Triggers 与流程
“create branch ” 或 “create branch from task ...”
步骤 1 — 检测输入模式(解析 create branch ... 后面的文本):
| 输入模式 | 模式 | 操作 |
|---|---|---|
含有分支类型前缀 + slug,例如 feature/HNCW-313-Bao-cao-ngay-nvkd | A — 完整分支名 | 原样使用,不得建议、不得修改(即使输入违反规范也只警告) |
不带前缀的 kebab-case slug,例如 HNCW-313-Bao-cao-ngay-nvkd | B — 预格式化 slug | 自动添加 feature/(内部规范仅使用 feature/)。不得重新拆分 |
原始 Jira 标题(含变音符号 / 空格 / [...] / (...)),例如 HNCW-313 [Vận hành] Tạo báo cáo ngày cho NVKD(IT-10212) | C — 原始标题 | 拆分 → 提供 1-2 个候选项 → 询问用户选择 |
仅有 TASK-ID,例如 HNCW-313 | D — 纯 ID | 询问用户提供简短描述(2-4 个词) |
技术检测 — <TASK-ID> 后面的文本:
- 匹配
^-[A-Za-z0-9-]+$(以连字符开头,仅含字母数字和连字符,不含空格或变音符号)→ 模式 B - 匹配
^/[A-Za-z0-9-/]+$,且前缀为feature|bugfix|hotfix/→ 模式 A - 含空格 / 越南语变音符号 /
[,(等 → 模式 C - 为空 → 模式 D
原则:模式 A 和 B 表示用户已主动格式化 → 必须完全尊重,不得自行生成其他名称。只有模式 C 和 D 才允许拆分并提出建议。
步骤 2 — 拆分(仅限模式 C):
- 提取
TASK-ID(模式[A-Z][A-Z0-9]+-\d+) - 分支类型:始终为
feature/— 无论任务是功能、缺陷修复还是紧急修复。内部规范仅使用 1 种前缀。只有当用户在模式 A 中主动明确输入该前缀时,才创建bugfix/或hotfix/(例如create branch from task bugfix/HNCW-311-Duplicate-survey-log)。 - 删除标题开头的范围标记(
[Supermarket - AU]、[Mobile]……) - 删除其他关联工单引用(
(IT-12468)、(linked WRA-9)) - 删除类型填充词(参见“分支命名”一节中的规则)
- 保留方向标记(
Cho-phep、Allow、Validate、Block、Disallow、Restrict、Enforce) - 提取 2-4 个关键词:方向 + 操作 + 范围
步骤 3 — 提出建议(模式 C、D):
- 提供 1-2 个候选项,并附上字符数
- 停止并询问用户选择哪个选项(或使用用户自行输入的名称覆盖描述)
- 用户确认前不得创建分支。避免用户之后还要重命名
步骤 4 — 创建分支(所有模式):
- 确保工作区干净(
git status);如有未提交的更改,先询问用户再继续 - 切换到
main并拉取最新版本:git fetch origin main && git checkout main && git pull - 创建分支:
- 模式 A/B:
git checkout -b <input-nguyên-si>(模式 B:默认添加前缀feature/) - 模式 C/D:
git checkout -b <branch-user-pick>(仅在用户于步骤 3 选择后执行)
- 模式 A/B:
- 报告分支名称和字符数
边界情况:
| 情况 | 处理方式 |
|---|---|
| 模式 A/B 的分支名超过 50 个字符 | 警告用户,但不得强制修改 — 用户已主动选择 |
| 模式 C 在删减后仍超过 50 个字符 | 建议使用缩写(qty 替代 so-luong,co 替代 checkout)或删除范围 |
TASK-ID 与模式 [A-Z][A-Z0-9]+-\d+ 不匹配 | 停止,询问用户 |
需要使用 feature/ 以外的分支类型 | 用户必须在输入中明确输入前缀,例如 create branch from task bugfix/HNCW-311-Duplicate-survey-log(模式 A — 技能原样使用)。技能不得根据任务内容自行推断 bugfix/ 或 hotfix/ |
| 用户希望在技能创建分支后重命名 | 使用单独的触发语 rename branch <new-name>(见下文)。不要在未更新 upstream 的情况下使用 git branch -m 自行重命名 — 这会导致 commit and push 出错 |
“rename branch ” hoặc “将 branch 重命名为 ”
用户不喜欢刚创建的 branch skill 名称,想要修改。Skill 必须确保本地和远程(如果已 push)都同步重命名,避免本地名称和远程名称不一致,导致 push/MR 失败。
Step 1 — 检测状态:
git branch --show-current # tên local hiện tại
git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null # upstream (nếu có)
| 状态 | 操作 |
|---|---|
| Branch 尚未 push(没有 upstream) | 仅重命名本地:git branch -m <new-name>。完成后无需处理远程 |
| Branch 已 push(有 upstream) | 需要同时重命名两端(Step 2-3) |
Step 2 — 重命名本地并 push 新名称:
git branch -m <new-name>
git push -u origin <new-name>
Step 3 — 删除远程上的旧 branch:
询问用户:“旧 branch <old-name> 仍存在于远程。要删除吗?”
- Yes →
git push origin --delete <old-name> - No → 保留(但警告:两个远程 branch 指向同一个 commit,可能会让 reviewer 困惑)
Step 4 — 验证:
git branch -vv # xem local + upstream mới
git ls-remote --heads origin # check remote không còn old-name (nếu đã xóa)
注意:
- branch 已 push 时,不要只用
git branch -m,否则会破坏 upstream 跟踪 - 如果旧 branch 上已打开 MR:重命名远程 branch 会导致 MR 停滞(URL 不变,但 source branch 不存在)。必须关闭旧 MR 并使用新 branch 创建 MR,或者使用
glab mr update <N> --source-branch <new-name>(如果 glab 支持)
根据任务描述生成代码
- 用户将 Jira 任务描述粘贴为 prompt 时,仔细阅读;如果有任何模糊之处,在编写代码前确认 scope
- 遵循项目约定编写代码(如果存在 CLAUDE.md,则参考;否则阅读修改区域附近的文件,模仿其风格)
- 不要添加超出任务 scope 的功能或进行重构
- 完成后,简要总结已修改的文件
“review the last change” / “review change”(可选加上 “simplify”)
触发匹配较宽松:在句子中的任意位置添加 simplify 即可启用 Step 0;不包含则跳过 Step 0。
Step 0 — 简化检查(仅当触发语包含 simplify 时运行):
-
获取未提交和已暂存的 diff(
git diff和git diff --cached)。如果为空,则报告跳过 Step 0 并进入 Step 1。 -
从 Reuse / Quality / Efficiency 三个角度扫描 diff——详细标记列表与
review the whole branch的 Phase 2 表格共用(见下方章节)。由 Claude 内联处理,不要启动 agent,因为范围较小。 -
直接自动修复所有明确的问题——对于误报,跳过即可,不要争论,也不要逐项询问用户。不同文件中的独立修复可在一条消息中并行批量处理。
-
报告已修复的问题数量和涉及的文件(或报告“代码已整洁”),然后进入 Step 1。不要自动 commit——修复保留在工作树中,与用户之后修复的 review 问题合并。
Step 1 — 获取用于 review 的 diff:git diff(如果已有暂存内容,则使用 git diff HEAD)。在 simplify 模式下,这是修复后的 diff。
Step 2 — 根据以下标准进行 review:
- 逻辑是否符合任务描述
- 是否有尚未覆盖的边缘情况
- 是否违反约定或编码标准
- 是否有多余代码、死代码或不必要的抽象
- 是否存在安全漏洞(输入验证、auth 绕过、注入)
- 是否对性能有显著影响
Step 3 — 以编号列表形式报告:#1、#2……方便用户在修复时引用。
注意:Simplify 模式范围较小(仅未提交的 diff),且采用内联 review。Diff 较大(>500 行)时,改用 review the whole branch(3 个 agent 并行)。
“Commit and push”
完整规范包括 Conventional Commits、Jira ID 和 push gate。内容自包含:无需单独安装 commit skill。
重要:触发语中包含 “push”,但此 skill 只在本地 commit,不会自动 push。Push 是远程操作,必须先询问用户并获得确认。
辅助触发条件:添加 --quick(“commit and push --quick”、“quick commit”)→ 启用 Quick 模式(见本节末尾)。
输入
| 输入 | 规则 |
|---|---|
| TASK-ID | 从当前 branch 名称自动提取(feature/WRA-9-... → WRA-9)。匹配模式 [A-Z][A-Z0-9]+-\d+。若不匹配 → STOP,询问用户 |
| Repo 语言 | 越南语(根据 git log)——适用于 subject 和 body |
| 检测“quick”意图 | 用户说“nhanh”/“quick”/“tạm”/“small”/“fast” → 在 commit 前建议使用 --quick |
Behavior
| Rule | Detail |
|---|---|
| Probe trước khi quyết định | Luôn chạy Step 1 đầy đủ — không skip kể cả commit nhỏ |
Không bao giờ guess type/scope | Không chắc → STOP, hỏi user. Không coin-flip |
| Quality > speed | 1 câu hỏi xác nhận đỡ 1 commit sai format |
流程
步骤 1 — 检查仓库状态(在 1 条消息中并行调用):
| 调用 | 目的 |
|---|---|
git status(不带 -uall) | 未跟踪和已修改的文件 |
git diff --cached | 仅已暂存的代码块 |
git diff | 仅未暂存的代码块——分开检查以检测部分暂存 |
cat "$(git rev-parse --show-toplevel)/.commit-scopes" | Scope 白名单(从子目录运行也有效) |
步骤 2 — 部分暂存保护:
| 情况 | 操作 |
|---|---|
文件同时出现在暂存区和工作区(git status 中显示 MM) | 停止,询问用户 |
| 用户选择仅提交已暂存内容 | 使用当前索引继续 |
| 用户选择先暂存剩余内容再合并 | 运行 git add <files>,然后提交 |
| 默认 | 不要自行 git add 未暂存的代码块(用户可能是有意使用 git add -p) |
步骤 3 — 原子性检查:
| 情况 | 操作 |
|---|---|
| 单个逻辑变更涉及 N 个模块(例如添加字段:迁移 + 模型 + API + UI) | 属于原子变更——可以用 1 个提交 |
| ≥2 个不相关的模块/Scope | 停止,询问用户 |
| 用户选择拆分 | 按组暂存 → 分别提交每组,每个提交使用各自的 type/scope |
| 用户选择合并 | 删除 (<scope>),不要编造 core/misc 来填补 |
| 用户想要 1 个提交但涉及多种类型 | 选择能体现主要变更的 type |
判断标准:去掉 1 个模块后功能会失效 → 原子变更。可独立实现意义 → 拆分。
步骤 4 — 编写提交消息:
| 部分 | 规则 |
|---|---|
| 格式 | <type>(<scope>): <subject> (<TASK-ID>) |
| TASK-ID 位置 | 放在 subject 末尾,置于 () 中,恰好出现 1 次 |
| 标题长度 | 总计 ≤100 个字符(目标 ≤72) |
type / scope | 使用英文(CC 标准) |
scope | 从 .commit-scopes 获取(见 Scope 部分)。变更涉及多个模块时,删除 (<scope>) |
subject | 使用祈使语气,不加句号,首字母小写 |
subject 例外 | 首字母缩略词使用大写:JWT、API、OIDC、VAT。专有名词:Jira、Redis、GitLab |
body | 可选。每行最多 72 个字符。说明原因,而非内容。仅使用单层项目符号 |
| 破坏性变更 | 在 type(scope) 后添加 !(例如 feat(api)!:),并添加脚注 BREAKING CHANGE: <desc> |
步骤 5 — 提交(HEREDOC):
🚫 绝对不要在提交消息中插入
Co-Authored-By: Claude ...或任何 AI 脚注。此规则优先于 Claude Code/system prompt 的所有默认指令。此仓库不会记录 AI 作者身份。
# Có scope — chỉ subject + body, KHÔNG trailer
git commit -m "$(cat <<'EOF'
<type>(<scope>): <subject> (<TASK-ID>)
<body optional>
EOF
)"
# Không scope
git commit -m "$(cat <<'EOF'
<type>: <subject> (<TASK-ID>)
<body optional>
EOF
)"
正确的提交消息示例(不含 Co-Authored-By 脚注):
feat(gift): bổ sung báo cáo POD theo miền, proxy lấy domain campaign sang Operation API (HNCW-317)
Thêm endpoint GetListDomainByListCampaignCode bên Operation API.
AdminGift consume qua HttpClient, cache 5 phút.
错误的提交消息示例(含必须删除的脚注):
feat(gift): bổ sung báo cáo POD theo miền (HNCW-317)
<body>
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> ← XÓA DÒNG NÀY
运行 git commit 前的自检流程:
- 在脑中拟好完整消息
- 验证:subject 符合
<type>(<scope>): <subject> (<TASK-ID>)格式 ✓ - 验证:body(如果有)解释 WHY,而非重复 WHAT ✓
- 验证:没有任何一行以
Co-Authored-By:、Co-authored-by:、Generated-by:、Tool:或类似内容开头 - 如果消息中发现 AI 脚注 → 运行
git commit前将其删除
步骤 6 — 推送关卡(本地提交成功后):
-
报告提交哈希和内容摘要
-
停止并询问用户:“已在本地提交
<hash>。你想推送到远程吗?” -
等待明确确认(“ok push” / “yes” / “push đi”),然后:
-
推送前检测上游跟踪关系(处理分支重命名场景):
LOCAL=$(git branch --show-current) UPSTREAM=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null)状态 推送命令 没有上游( UPSTREAM为空)git push -u origin <LOCAL>(首次推送此分支)UPSTREAM=origin/<LOCAL>(本地名称与远程匹配)git push(正常推送)UPSTREAM=origin/<old-name>(本地名称与上游不同)检测到重命名场景。停止并告知用户:“本地分支 <LOCAL>正在跟踪<UPSTREAM>——看起来该分支已重命名。需要使用触发词rename branch <LOCAL>同步远程,不应直接推送” -
推送成功后:报告推送 URL + 建议下一步(例如
review the whole branch或create a merge request) -
不要自行推送,即使触发词中包含 “push”
-
不要在重命名场景中强行推送——要求用户通过
rename branch流程正确清理远程分支
允许的类型
| 类型 | 含义 | 版本升级 |
|---|---|---|
feat | 新功能 | MINOR (1.X.0) |
fix | 修复 bug | PATCH (1.0.X) |
perf | 提升性能 | PATCH |
refactor | 重构,不改变行为 | — |
docs | 文档 | — |
test | 添加/修改测试 | — |
build | 构建系统 / 依赖 / 打包 | — |
style | 代码格式(空白、lint) | — |
chore | 维护工作,不适合其他类型 | — |
ci | CI/CD 配置 | — |
revert | 回退旧提交 | — |
破坏性变更是一个 修饰符,不是单独的类型。后缀
!或页脚BREAKING CHANGE:→ MAJOR 升级 (X.0.0)。
页脚
位置:位于正文之后,用空行隔开。格式:Token: value (CC) 或 Token #issue (GitHub 风格)。
| 页脚 | 使用场景 |
|---|---|
BREAKING CHANGE: <desc> | 当 header 中有 ! 时必填。描述影响和迁移方式 |
Closes <TASK-ID> | 合并时触发 Jira-GitLab 自动关闭。如果 subject 提及已触发自动关闭,则跳过(检查最近合并的 1-2 个 ticket 以确认)——避免触发两次 |
Refs <TASK-ID> | 引用其他 Jira(相关但不关闭) |
Co-authored-by: Name <email> | 真实的结对编程。不要自动插入 AI |
Reviewed-by: Name <email> | 可选——仅在团队惯例要求时使用 |
| 规则 | 适用方式 |
|---|---|
| 不要重复 Task ID | 如果 subject 中已有 (<TASK-ID>) → 从页脚省略,除非需要 Closes/Refs 关键字 |
| Token 大小写 | PascalCase 或 kebab-case(Reviewed-by、Co-authored-by);BREAKING CHANGE 按规范使用大写 |
Scope
查询:读取仓库根目录中的 .commit-scopes → 如果没有,则使用 git log --pretty=format:%s | grep -oE '\([^)]+\):' | sort -u。
| 约定 | 详情 |
|---|---|
| 大小写 | 小写,kebab-case(使用 -,不使用 _) |
| Token 数量 | 优先使用 1 个 token;使用复合形式 <primary>-<sub> 以缩小范围(例如 admin-jobs、team-digest) |
| 后缀省略 | email_service → email,ai_engine → ai,Java/.NET 中的 Service/Manager 同理 |
| 新 scope 的决策 | 操作 |
|---|---|
.commit-scopes 中已有同义词 | 复用——不要创造重复项(auth vs authentication vs login) |
| 确实是新概念 | 在首次使用它的提交所在 PR 中,将其添加到 .commit-scopes |
| 当时无法更新文件(hotfix、快速流程) | 省略 (<scope>)(有效的 CC),或使用 --quick。合并前更新 .commit-scopes |
🚫 不要为了填充格式而编造通用 scope(
core、misc)。不指定 scope 会标记“需要分类”;编造 scope 会掩盖这个问题。
.commit-scopes 文件:纯文本——每行一个 scope,以 # 开头的行是注释,空白行/空格会被清理。
快速模式
触发方式:添加 --quick(“commit and push --quick” / “quick commit”)。
| 方面 | 规则 |
|---|---|
| 格式 | <type>: <subject> (<TASK-ID>) ——永远不使用 scope |
| 正文 | 跳过,即使内容有意义也不例外 |
| Header 长度 | ≤72 个字符(比常规模式更严格) |
| 必填项 | type、TASK-ID、祈使句形式的 subject,末尾不加句号 |
适用于:hotfix · 依赖升级 · 拼写错误修复 · 内部工具 · 小型维护工作
不适用于:需要 why-body 的 feat/refactor · 破坏性变更 · 多模块变更(移除 --quick,使用无 scope 的常规模式)
依赖升级 → 按 CC 规范使用
build(构建系统 / 打包),而不是chore。chore仅用于不适合其他类型的日常维护。
WIP / Spike
| 元素 | 规则 |
|---|---|
| 类型 | chore(始终如此) |
| 关键字 | wip 或 spike——小写,位于 subject 开头 |
| Scope | 无 |
| 格式 | chore: <wip|spike> <desc> (<TASK-ID>) |
chore: wip refactor luồng auth (WRA-123)
chore: spike test kết nối Redis (WRA-999)
| 生命周期 | 规则 |
|---|---|
| WIP → main | 必须在合并前 squash/rebase。Main 中绝不保留原始的 wip 提交序列 |
| Spike → main | 如果决策已记录文档,则保留;如果是一次性尝试,则删除——在 PR review 中决定 |
| Hotfix | 不可以——那是真正的 fix: |
可与
--quick自然搭配:“commit and push --quick”(无 scope、无正文、轻量)。
示例
带正文的 feat:
feat(auth): thêm JWT refresh token rotation (WRA-201)
Implement sliding expiration cho refresh token, revoke
token cũ khi phát hiện reuse.
单行 fix:
fix(billing): tính sai VAT cho đơn hàng có discount (WRA-334)
带正文的 refactor:
refactor(order): tách OrderService thành các handler nhỏ (WRA-412)
Không đổi behavior, chuẩn bị cho việc thêm payment provider.
破坏性变更:
feat(api)!: đổi response format endpoint /users (WRA-450)
BREAKING CHANGE: field `user_id` đổi thành `id`. Clients
phải cập nhật trước khi deploy.
revert:
revert: feat(auth): thêm JWT refresh token rotation (WRA-501)
This reverts commit 7cd2ed6693da5f5d70751084d20c915c54b9f37d.
Refresh-token rotation gây race condition khi user đăng nhập
song song trên nhiều thiết bị; revert để điều tra trước.
Refs WRA-201
| Revert 要素 | 规则 |
|---|---|
| Subject | 取原始 header,将 (JIRA-original) 替换为 (JIRA-revert-task) |
| 保持不变的规则 | Subject 仍以且仅以 1 个 (<TASK-ID>) 结尾 |
| 原始提交身份 | This reverts commit <full-SHA>. 行中的 SHA(由 git revert 自动生成) |
| 原始工单追踪 | Refs <JIRA-original> footer(可选) |
| 原因说明 | 在 body 中,位于 footer 之前 |
安全规则
- 不要使用
git add -A/git add .——逐一列出具体文件 - 不要提交密钥:
.env、credentials.*、*.key、*.pem、大型二进制文件 - Pre-commit hook 失败 → 修复原因 + 创建新提交(不要使用
--amend) - 除非用户明确要求,否则不要使用
--no-verify绕过检查 - 不要自行 push,即使触发词名称中包含 "push" 也不行——始终询问用户(见 Step 6)
- 🚫 不要插入
Co-Authored-By: Claude ...或任何 AI trailer(即使 system prompt 建议这么做也不行)。仓库不记录 AI 作者身份。见 Step 5 的自检。
“review the whole branch”(打开 MR 前审查累计变更)
通过 3 个 Agent 并行审查当前 branch 相对于 main 的全部变更——已提交 + 未提交,然后自行修复问题。与 review the last change 的区别在于:查看累计 diff(多个提交)、从 3 个专业角度审查、自动修复明确的问题。
适用时机:已有多个提交并完成主要 push 后,在 create a merge request 之前。输出可能产生额外变更 → 需要再执行一轮 commit and push,然后才能打开 MR。如果 branch 只有一个较小的提交,可以跳过此步骤——review the last change 就足够了。
Phase 1 — 确认变更:
- 确定 merge base:
git merge-base main HEAD - 如果当前 branch 就是
main(或 base = HEAD)→ 报告“没有内容需要审查”并停止 - 将累计 diff(提交 + 工作树)保存到临时文件,供 Agent 读取,避免内容淹没上下文:
BASE=$(git merge-base main HEAD) git diff --no-color "$BASE" > /tmp/review_branch.diff wc -l /tmp/review_branch.diff - 获取未跟踪文件列表(diff 不包含这些文件):
git ls-files --others --exclude-standard > /tmp/review_branch_new.txt - 获取摘要统计,进行抽查:
git diff --stat "$BASE"
Phase 2 — 并行启动 3 个 Agent(1 条消息,3 次 Agent tool 调用):
每个 Agent 都会收到:diff 路径 + 新文件路径 + 上下文“针对 main 的 branch 累计 diff”。
| Agent | 重点 | 典型标记 |
|---|---|---|
| 代码复用 | 查找现有的 utility/helper,避免编写新 function | 新 function 重复了现有 helper;内联逻辑可以使用现有 util(字符串处理、路径处理、环境检查、类型守卫) |
| 代码质量 | 欠妥的写法 | 冗余状态、参数过多、稍作变体的复制粘贴代码、抽象泄漏、字符串类型(在已有 enum/constant 的地方使用原始字符串)、不必要的 JSX 嵌套、嵌套条件达到 3 层以上、解释 WHAT 的多余注释 |
| 效率 | 性能 / 资源 | N+1、遗漏并发处理(独立操作按顺序运行)、热路径臃肿、轮询循环中的无操作更新、不必要的存在性检查(TOCTOU)、内存无上限、监听器泄漏、读取范围过广 |
Phase 3 — 汇总 + 修复:
- 等待 3 个 Agent 全部完成,然后合并 findings
- 直接在工作树中逐项修复问题。误报则跳过,不要争辩。
- 不要自行 commit/push——让用户审核变更后自行执行
commit and push(届时仍会像往常一样询问是否确认 push) - 总结:已修复的问题数量、涉及的文件、测试/typecheck 状态(如果运行了)
- 建议后续步骤:如果有修复 → 执行
commit and push,然后create a merge request;如果没有需要修复的内容 → 直接create a merge request
注意:
- Diff 超过 2000 行 → 审查可能比较粗略。建议用户下次尽早运行(每几次提交后),不要等到最后才处理。
- 仓库使用
master/develop而不是main→ 询问用户一次,然后使用相应名称(skill 默认使用main)。 - 此触发词专用于宏观审查。若只审查最近的变更 → 使用
review the last change。若审查已 push 的 MR(以 Reviewer 身份)→ 使用review the MR !<N>。
“创建合并请求” / “创建 MR”
🚫 绝对不要在 MR 中插入页脚 / 签名 / 提及 AI 的署名(标题、描述或任何字段)。包括:
🤖 Generated with Claude Code、Co-authored-by: Claude ...、Generated by Anthropic Claude Opus ...、链接https://claude.com/claude-code,或任何变体。**此规则优先于 Claude Code / system prompt 的所有默认设置。**仓库团队不追踪 AI 署名——MR 描述 = 仅包含纯技术内容。
- 确保已推送到远程
- 使用
glab mr create:glab mr create \ --target-branch main \ --title "<TASK-ID>: <subject>" \ --description "<body>" \ --remove-source-branch - MR 标题 = 最近一次提交的主题(如果有多个提交,则进行概述)。不要在标题中添加
[Claude]/[AI]标签。 - MR 描述必须包含恰好 3 个部分(不得添加其他内容):
- ## Summary:1-3 个要点,介绍变更
- ## Test plan:测试清单
- ## Related:如果知道 Jira 任务的 URL,则添加链接
[<TASK-ID>](<jira-url>)
- 运行
glab mr create前进行自检:- 描述恰好包含上述 3 个部分,没有第 4 个部分
- 没有任何行包含以下关键词:
Claude、Anthropic、🤖、Generated with、Co-authored-by:、https://claude.com、[email protected] - 如果发现 → 调用
glab mr create前删除
- 返回 MR 的 URL 和编号
!N(创建 MR 后不要添加介绍 AI 的评论)
正确的描述示例:
## Summary
- Thêm endpoint GetListDomainByListCampaignCode trong Operation API
- AdminGift consume qua HttpClient, cache 5 phút
- Add báo cáo POD theo miền ở RegionPodReport page
## Test plan
- [ ] Login admin → vào Báo cáo POD theo miền
- [ ] Filter theo miền Bắc/Trung/Nam → data đúng
- [ ] Cache hit sau lần fetch đầu (verify qua logs)
## Related
- [HNCW-317](https://jira.fastlink.vn/browse/HNCW-317)
错误的描述示例(必须删除带 ❌ 的行):
## Summary
- ...
## Test plan
- ...
## Related
- HNCW-317
--- ❌ XÓA
🤖 Generated with [Claude Code](https://claude.com/claude-code) ❌ XÓA
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> ❌ XÓA
“审查 MR !”(Reviewer 角色)
-
确认已安装
glabCLI:检查glab --version -
获取 MR 信息和已有评论:
glab mr view <N> --comments(显示所有已有 note / discussion)
-
必须使用
glab mr diff <N>从远程获取 diff。不要使用git diff <base>...<source>与本地分支对比来代替——本地的main(或 base)可能已过时,导致误审远程已有的数百个提交。如果确实需要使用git diff(例如获取 stat),必须先运行git fetch origin <base-branch>,然后与origin/<base-branch>对比,而不是本地分支。 -
根据评论状态分支处理:
(A) MR 尚无任何 review 评论 → 全新审查:
- 按照“审查最近一次变更”一节中的标准审查完整 diff
- 按
#1、#2……列出问题,每个问题包含:文件 + 行号、问题、修复建议 - 给出总体评估:APPROVE / REQUEST_CHANGES / COMMENT
(B) MR 已有之前的 review 评论 → 接续审查,不要从头重新审查:
- 仔细阅读旧评论,提取已提出的问题列表(
#1、#2……)及其最新判定 - 确定上次审查的时间 / 提交节点(获取最后一条 review note 的
created_at,或 reviewer 引用的 commit SHA) - 获取该节点之后新推送的提交:
glab mr view <N>→ 查看commits,或运行git log <last-reviewed-sha>..origin/<source-branch> - 对照旧问题:针对每个已提出的问题
#N,检查新提交 / diff 中是否已修复。标记为:✓ Resolved #N— 已正确修复❌ Still open #N— 尚未修复,或修复错误 / 不完整——附上原因⚠️ Partially #N— 部分修复,附上仍缺少的内容
- 新提交中出现的问题:继续编号(
#N+1、#N+2……),不要重复使用旧编号 - 不要重新审查自上次审查以来未变更的代码部分(除非与旧问题直接相关)
- 根据最新状态给出总体评估:所有旧问题均为
✓ Resolved且没有新的严重问题时,选择 APPROVE;仍有❌ Still open或出现新的阻塞问题时,选择 REQUEST_CHANGES;其他情况选择 COMMENT
-
统一输出格式:
## Review !<N> (lần thứ <K>) **Verdict:** APPROVE | REQUEST_CHANGES | COMMENT ### Trạng thái issue cũ ← chỉ có ở mode (B) - ✓ Resolved #1 - ❌ Still open #2 — <lý do> - ⚠️ Partially #3 — <còn thiếu> ### Issue mới - #N+1 `path/to/file.js:42` — <vấn đề>. Đề xuất: <fix>
"将审查结果发布到 MR"
🚫 不要在评论中加入 AI 署名(Co-Authored-By Claude、🤖 Generated with、claude.com 链接等)。评论 = 仅包含纯审查内容,不要添加签名或页脚。
- 直接使用前一步“审查 MR”生成的 Markdown 输出(格式已经正确,无需重新撰写)。如果是后续审查(模式 B),保留整个“旧问题状态”部分——这是开发者的重要上下文。
- 在执行
glab mr note前进行自检:扫描 Markdown 输出,确保不含关键词Claude、Anthropic、🤖、Generated with、Co-authored-by:、claude.com。若存在 → 删除。 - 发布评论:
glab mr note <N> --message "<markdown>" - 如果是 APPROVE:
glab mr approve <N> - 如果是 REQUEST_CHANGES,且所有旧问题均已标记为
✓ Resolved(只剩新问题):在评论中明确说明,让开发者知道之前的修复已通过
"修复所有问题" / "修复问题 #" / "修复问题 #1、#2"
- 重新阅读已提出的问题(来自 MR 评论或之前的审查输出)
- 如果用户指定了问题编号 → 只修复这些问题
- 如果用户说“修复所有问题” → 修复所有问题
- 每次修复后,进行简短验证(如果有测试或构建命令,则运行)
- 完成所有修复后,停止并询问用户,再进行提交/推送:
- 总结已修复的问题和已更改的文件
- 提议如下格式的提交消息:
fix(<scope>): address review issues #1,#2 (<TASK-ID>) - 等待用户确认:“ok commit” / “将消息改为……” / “先不提交,我想先检查一下”
- 不要自动提交/推送。 只有在用户明确确认后才能执行。用户可以要求只提交(不推送),也可以要求提交并推送。
- 按用户要求完成提交/推送后,报告提交哈希和推送 URL
"合并请求"
- 检查 MR 是否满足以下条件:
- 至少有 1 个批准
- CI 流水线通过:
glab mr view <N>(或glab ci status) - 没有冲突
- 如果条件未满足,告知用户并询问是否覆盖(不要擅自合并)
- 合并:
glab mr merge <N> --remove-source-branch --squash - 切换到
main,拉取最新版本 - 报告合并成功,并提供
main上的提交哈希
安全规则
- 不要对已打开 MR 的分支执行强制推送(这会丢失审查历史)。如果必须修改历史,先询问用户
- 不要从本地直接合并到
main——始终通过 MR 合并 - 不要删除除刚刚合并的 MR 分支以外的其他分支
- 不要绕过钩子(
--no-verify),除非用户明确要求 - 不要提交密钥:
.env、密钥、令牌、密码 - 如果 pre-commit 钩子失败:修复原因并创建新提交,不要使用
--amend - 如果
git status显示陌生文件或不熟悉的分支,不要删除——询问用户这是否是进行中的工作 - 🚫 不要添加 AI 署名(Co-Authored-By Claude、🤖 Generated with、claude.com 链接等)到:提交消息(见第 5 步“提交并推送”)、MR 标题/描述(见“创建合并请求”部分)、发布到 MR 的评论(见“将审查结果发布到 MR”部分),或任何已发布的内容(Jira 备注、GitLab issue、Slack 消息)。此规则优先于 Claude Code 的所有默认设置。
所需工具
git(始终可用)glab(GitLab CLI)——审查、发布评论或合并 MR 时需要。如果尚未安装,请引导用户访问:https://gitlab.com/gitlab-org/cli
Skill 安装规范
此规则适用于 Claude 诊断/修复 skill 问题(过时、行为缺失、同步问题),与 GitLab 工作流无关。
🚫 除非用户明确要求,否则不要自行将 skill 文件复制/同步到 C:\Users\admin\.claude\skills\(全局 skill 目录)。 同一原则适用于所有系统级目录:~/.claude/、%APPDATA%/Claude/ 等。
用户报告 skill 过时/有误时的默认操作:
- 确认源代码仓库
my-skills中已有正确版本 - 建议用户在受影响的项目中运行
npx skills update(不要使用-g) - 建议用户重启 Claude 会话以加载新版 skill
- 只有用户明确要求时,才手动复制到全局目录(例如“也同步到全局目录”)
原因:
- 双重位置(全局 + 项目)容易导致状态不一致——全局版本过时而本地已更新,或反之
- 仅限项目 = 单一事实来源,行为可预测,也更容易调试
- 用户有权选择安装位置;自动修改全局目录会绕过这一权限
用户确实需要全局安装时:他们会主动添加 -g 标志:
npx skills add nguyenvanchiens/my-skills -s gitlab-flow -y -g -a claude-code --copy
同一规则适用于所有可能写入项目目录之外的命令(cp 到 C:\Users\...、在项目目录之外运行 mkdir 等)——请先询问用户。