Git 工作流规范 (Git Workflow Standards)
1. 分支管理
| 分支 | 职责 |
|---|---|
master | 主分支:稳定代码、版本发布与最终合并结果 |
补充约束:
- 不为
fix、docs维护长期专用分支,修复类工作直接在master完成。 - 若某项工作需要隔离,创建短生命周期任务分支,合并后删除。
2. 合并与集成
- Review 前置: 任何改动进入 commit 前必须经过至少一轮 review。
- 未闭环不得提交: review 指出问题但未形成结论的,不得 commit 或发起合并。
3. 提交规范
所有 git commit 操作必须遵循以下约束(与 AGENTS.md 提交规范 一致):
- 必须使用
conventional-committerskill:任何代码、文档、配置或脚本的提交都必须通过conventional-committerskill 执行。禁止直接使用git commit -m "..."裸提交。 - 格式要求:提交消息必须符合 Conventional Commits 规范,格式:
<type>(<scope>): <description>,且description统一使用中文或用户使用的语言。 - 质量前置:提交前必须确认 A 阶段(
Code Auditor (代码审计员))已放行,且pnpm lint、pnpm typecheck和必要的定向测试均已通过。质量门禁未通过时不得提交。 - 原子粒度:一个提交对应一个逻辑变更,关联且仅关联
todo.md中的一个原子条目。 - 分批提交(长任务强制):单次提交规模建议与拆分规则见 规划规范 §1.1 任务粒度约束;按"可独立验证"的顺序分批次提交,每批独立过 Review Gate;锁文件(pnpm-lock.yaml)等随其所属批次提交。
- 推送禁令:
git commit后不得自动执行git push,推送仅限用户明确要求时执行。提交完成后应告知用户"已提交到本地,等待推送确认"。
3.1 提交消息格式
提交消息必须符合 Conventional Commits 规范,格式:<type>(<scope>): <subject>,可选正文。
提交策略(先评估后提交):
- 先评估改动规模,决定单次提交还是分批提交(分批规则见 规划规范 §1.1 任务粒度约束)。
- 再判断类型:默认单类型提交;多类型提交仅用于改动互相关联较大、不宜拆分的情况。
- 最后选择最合适的类型生成提交消息。
单一类型修改:
<type>(<scope>): <subject>
<空行>
- <正文条目>多类型修改(例外,少用):仅当改动互相关联较大、不宜拆分时使用。选择一个最大的类型作为主类型,其他类型的改动放在正文中说明;按以下顺序决定主类型:feat > refactor/perf > fix > 其他。无关改动混入同一提交硬凑多类型属于反模式,应先拆分为独立批次。
特例分类(强制):
- README、API、.md、markdown 等文件及其改动一律视为
docs。 - unit、e2e、test 等测试文件及其改动一律视为
test。 - 无法确定分类时一律视为
chore。
类型表:
| 类型 | 说明 | 示例作用域 |
|---|---|---|
feat | 新功能 | user、payment |
fix | 漏洞修复 | auth、data |
docs | 文档 | README、API |
style | 代码风格 / 格式化 | formatting |
refactor | 代码重构 | utils、helpers |
perf | 性能优化 | query、cache |
test | 测试 | unit、e2e |
build | 构建系统 | webpack、npm |
ci | 持续集成配置 | workflows、dependabot |
chore | 其他修改 | scripts、config |
revert | 代码回滚 | - |
主题行(subject)规则:
type与scope必须为英文。- 采用祈使语气;首字母不大写;末尾不加句点。
- 最长 120 字符(推荐上限,刻意短于 commitlint 的 140 字符硬限制以留缓冲,避免误触发)。
- 主题使用简体中文或用户指定的语言;若无必要,主题中不使用括号备注,需要备注的内容放到正文中。
正文规则:
- 以
-作为列表符号;每行最长 120 字符,内容精简。
3.2 单文件跨 type 改动需提前规划 commit 拆分
- 单文件同时改 2 个不同 type 的逻辑(如
ImportReposDialog.vue同时含fix C48+chore C47)时,不能直接git add整个文件——commit 拆分需分三步:- 先
git restore --staged <file>或git reset,只 edit 保留其中一个逻辑的 diff git add <file>+git commit(commit 1)- 再 edit 加回第二个逻辑 +
git add <file>+git commit(commit 2)
- 先
- 实现阶段提前识别"单文件跨 type"会节省后续 reset/re-edit 成本。
- 替代方案:将不同 type 改动拆分到不同文件(新增组件 / helper),从源头避免单文件跨 type。
3.3 阶段任务分批提交避免单次大 diff 成本失控
- 阶段任务(T-编号 / M-编号)按依赖与职责切分为多个 atomic commit(如 B1 RuntimeAdapter 抽象层仅 2 文件 225 行 + 125 行测试已 lint auto-fix 触发 11 文件改动,独立 style commit 隔离连锁反应)。
- 单次大 diff 成本失控的典型症状:审计耗时指数级上升、Review Gate Reject 概率增加、回滚粒度过粗、lint auto-fix 副作用传染其他文件。
- 按"可独立验证"的顺序分批提交,每批独立过 Review Gate,锁文件(pnpm-lock.yaml)等随其所属批次提交。
- 简单说明做了什么及为什么这么做。
- 使用中文或用户指定的语言。
- 若无必要可不写正文;条目不得太多,内容简单时应当无正文。
3.4 reset 重做 atomic commit(仅在 commit 未推送时适用)
- 当 commit 误把跨子批次改动纳入(如 commit 1 含 commit 2 应有的 i18n key)时,可
git reset --soft HEAD~1回滚到 commit 前状态、重新分两次提交——比git commit --amend更彻底地保持原子粒度。 - 仅在 commit 未推送(ahead of remote)时适用;已推送的 commit 必须靠后续 commit 修复或 revert,不能 reset(会与其他开发者历史冲突)。
- stage 前先
git diff --staged确认本次 commit 内容边界——避免误把跨子批次改动纳入同一 commit。 - 与 §3.2 单文件跨 type 改动需提前规划 commit 拆分 配套——§3.2 处理 staged diff 误纳(
git restore --staged),§3.4 处理已 commit 但未推送的误纳(git reset --soft)。 - 详见 经验归档 §二十四
3.5 lint auto-fix 接受策略(不要回滚,独立 chore commit 接受)
- ESLint
--fix自动修改(如@typescript-eslint/array-type规则偏好T[]写法替换Array<T>、@typescript-eslint/consistent-type-imports加type关键字等)是合规修改——两种写法 TypeScript 等价,规则要求即合规。应该接受 + 独立chorecommit——不要回滚。 - 详见 经验归档 §四十二
- 修正:lint auto-fix 是合规修改,不要回滚。如不希望与 docs 提交混杂,应在 commit 前
git restore --staged <file>排除;如已 uncommitted,作为 standalone chore commit 独立接受。 - 实操:在每次 commit 前过一遍 lint(
pnpm lint/pnpm run lint:md/pnpm typecheck)确认 0 error;如发现 working tree 有未提交 lint auto-fix 改动,按本节策略处理(接受并独立 commit)。
3.6 commit message 信息密度规范
commit message 应聚焦于"当次提交的改动"+"可供事后复查的信息",避免堆砌与 git diff / CI 实测输出重叠的冗余。
正文硬性约束:
- 正文条目 1-5 条;超过必须压缩或拆分到独立 commit
- 内容简单时应当无正文——主题行已能完整说明"做了什么"
- 若有正文,每行最长 120 字符,只说明做了什么及为什么这么做
应包含:
- 改动总览(哪些文件/模块,改了什么)
- 关联 todo 条目(M\d+.\d+ / T\d+ 等)
- 关键决策(多路径选择 + 为什么选这条)
- 问题原因 / 经验教训(事后复查视角,含关联 commit 引用)
- 跨模块影响时说明关联模块与同步关系
不应包含(git diff / CI 实测输出已涵盖,堆砌无增量价值):
- 执行了哪些命令(如
pnpm run check:docs/pnpm lint/pnpm typecheck等) - 执行结果数字(如 "links: 103" / "lint:md 0 error" / "1001/1008 passed")
- 改动行数(如 "+189/-3")
- 没实证的废话(如"确切路径需源码进一步实证"——没实证就别写)
- 与本 commit 实际改动关联度低的教训段(教训应归属在 hotfix 修复 commit 而非 docs 登记 commit)
硬约束自动拦截:scripts/commitlint/ 提供 4 个 commitlint plugins 在 .husky/commit-msg hook 阶段自动拦截上述违规:
- 规则集与正文硬性约束一一对应(不写执行命令 / 不写执行结果数字 / 不写改动行数 / 不写没实证废话与关联度低教训段)
- 拦截失败时返回 exit=1,git commit 直接拒绝
- 规则实现 + 单测详见 scripts/commitlint/ 目录
commit 前轻量级审核:执行方 self-check 4 项必查 + 触发 code-auditor quick depth 条件详见 ai-collaboration.md §1.6 commit 前轻量级审核流程。
4. AI 行为准则
- 禁止擅自推送: commit 后不得自动执行
git push,推送仅限用户明确指令。 - 工作区检查: 每次改动前先
git status确认工作区干净。 - 远程同步: 开始前拉取远程更新(
git fetch+git pull --rebase)。