首页
/ ECC Git 工作流规则解析:Conventional Commits 提交规范、Co-Authored-By 归因控制与 PR 实战流程

ECC Git 工作流规则解析:Conventional Commits 提交规范、Co-Authored-By 归因控制与 PR 实战流程

2026-09-06 19:44:59作者:侯霆垣

本文以 ECC(The agent harness performance optimization system)仓库中的 common-git-workflow.md 规则文件为核心,完整解析其定义的 Conventional Commits 提交格式、8 种提交类型、Claude 提交归因(Co-Authored-By)的默认关闭机制,以及五步 PR 工作流程。读完本文,你可以直接照搬这套规范约束团队或 AI Agent 的 Git 操作,并理解 ECC 安装器是如何在源码层面保证"不覆盖用户显式选择"的。

规则文件的定位与生效机制

该规则位于 ECC 的 Cursor 规则层 .cursor/rules/ 目录,其 YAML frontmatter 为:

---
description: "Git workflow: conventional commits, PR process"
alwaysApply: true
---

两个关键点决定了它的行为:

  • alwaysApply: true:该规则不是按需触发的,而是对 Cursor 会话中所有任务始终生效,因此它适合作为提交信息格式和 PR 流程这类"全局硬约束"。
  • 通用(common)前缀:文件名 common-git-workflow.md 表明它属于 ECC 规则的通用层。按照 rules/README.md 的分层设计,rules/common/ 存放与语言无关的通用原则(该规则的内容源文件即 rules/common/git-workflow.md),而 rules/typescript/rules/golang/ 等语言目录可覆盖其中与语言习惯冲突的默认值,冲突时"特定优先于通用"。.cursor/rules/ 下的 common-git-workflow.mdrules/common/git-workflow.md 内容基本一致,只是尾部引用链接的相对路径不同(前者指向 Cursor 规则体系内的 development workflow 规则,后者指向 development-workflow.md)。

安装方式上,ECC 官方文档给出的通用做法是保留目录结构整体拷贝(切勿用 cp -r rules/common/* 打平,同名文件会互相覆盖):

# 用户级 Claude 安装(ECC 命名空间)
mkdir -p ~/.claude/rules/ecc
cp -r rules/common ~/.claude/rules/ecc/

# 项目级安装
mkdir -p .claude/rules/ecc
cp -r rules/common .claude/rules/ecc/

也可以直接使用安装脚本 ./install.sh typescript(自动处理 common 层与语言层)。

Commit Message 格式:类型、结构与校验边界

规则给出的提交信息格式为:

<type>: <description>

<optional body>

允许的 8 种类型为:feat, fix, refactor, docs, test, chore, perf, ci

这 8 种类型覆盖了日常开发的绝大多数场景:feat 表示新功能,fix 表示缺陷修复,refactor 表示不改变外部行为的结构调整,docs/test/chore/perf/ci 分别对应文档、测试、杂务、性能优化与 CI 变更。可选的 body 用于补充"为什么改"而不仅是"改了什么"。

与仓库实际 commitlint 配置的对照

该规则并非孤立存在——仓库自身用 commitlint.config.js 对提交信息做了机器校验,值得对照阅读:

module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [2, 'always', [
      'feat', 'fix', 'docs', 'style', 'refactor',
      'perf', 'test', 'chore', 'ci', 'build', 'revert'
    ]],
    'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
    'header-max-length': [2, 'always', 100]
  }
};

可以读出三个与规则文件互补的约束细节:

  1. 类型白名单更宽:commitlint 的 type-enum 在规则的 8 种之外还允许 stylebuildrevert 三种(severity 为 2 即 error 级别,违反则 CI 失败)。
  2. subject 大小写约束subject-case 规则禁止 sentence-case、start-case、pascal-case、upper-case 四种写法,即 subject 应以小写命令式开头(如 fix login redirect loop 而非 Fix login redirect loop)。
  3. header 长度上限 100 字符:首行(type + subject)不得超过 100 字符,超长内容应放入 body。

如果你希望在自己的项目里复用这套校验,ECC 的 git-workflow skill 还给出了配套的提交模板方案:在仓库根目录创建 .gitmessage 文件并执行 git config commit.template .gitmessage,把类型列表和书写要求固化成编辑器里的提示注释。该 skill 同时给出了正反例对比:

# BAD: 含糊、无上下文
git commit -m "fixed stuff"

# GOOD: 清晰、具体、解释原因
git commit -m "fix(api): retry requests on 503 Service Unavailable

The external API occasionally returns 503 errors during peak hours.
Added exponential backoff retry logic with max 3 attempts.

Closes #123"

Co-Authored-By 归因控制:默认关闭且绝不覆盖用户选择

规则中有一段专门说明 AI 提交归因的约定:

ECC-managed installs set "includeCoAuthoredBy": false in ~/.claude/settings.json, so commits carry no Co-Authored-By trailer by default. To keep Claude attribution, set "includeCoAuthoredBy": true or configure attribution; ECC never overwrites an explicit choice.

含义是:在 ECC 托管的安装流程中,ECC 会向 ~/.claude/settings.json 写入 "includeCoAuthoredBy": false,使 Claude Code 产生的提交默认不附带 Co-Authored-By 尾注。若你希望保留 Claude 归因,可显式设置 "includeCoAuthoredBy": true 或改用 attribution 配置;ECC 承诺永远不会覆盖用户的显式选择。

这段约定的实现逻辑在 scripts/lib/claude-commit-attribution.js 中,源码注释把设计决策讲得非常清楚:

  1. 两个配置键的关系attribution: { commit, pr } 是当前生效的配置且优先级更高;includeCoAuthoredBy 自 Claude Code 2.1.x 起已弃用但仍被兼容,并且是旧版本唯一能识别的键。
  2. 为什么写的是弃用键:ECC 选择写入 includeCoAuthoredBy 而非 attribution,因为未知键会导致 settings 校验失败——如果对旧版 Claude Code 写入 attribution,会直接弄坏用户的设置文件。
  3. 显式意图判定hasExplicitCommitAttributionPreference() 检查两个键——只要 includeCoAuthoredBy 是布尔值,或 attribution 对象中定义了 commit/pr 任一字段,即视为用户的刻意选择。
  4. 只填空、不覆盖withCommitAttributionDisabled() 只在用户没有显式偏好时追加 [COAUTHOR_SETTING_KEY]: false,否则原样返回:
function withCommitAttributionDisabled(settings) {
  if (hasExplicitCommitAttributionPreference(settings)) {
    return settings;
  }
  return {
    ...settings,
    [COAUTHOR_SETTING_KEY]: false,
  };
}

这一"默认关闭 + 尊重显式选择"的策略,本质是避免工具链替用户做不可逆的决定:归因信息一旦写进 git 历史就无法干净移除。相关行为在 tests/lib/claude-commit-attribution.test.js 中有测试覆盖。

Pull Request 工作流程:五步清单及其命令化实现

规则对创建 PR 给出五步操作清单:

  1. 分析完整提交历史(not just latest commit)——PR 描述应基于整个分支相对 base 的全部变更,而不是最后一次 commit;
  2. git diff [base-branch]...HEAD 查看所有变更——注意这里是三点语法 base...HEAD,表示从两分支的共同祖先到 HEAD 的差异,正是 PR 语义下"本分支引入了什么"的准确表达;
  3. 起草全面的 PR 摘要
  4. 附上带 TODO 的测试计划——明确测试了什么、还欠哪些验证;
  5. 新分支首次推送使用 -u 标志——git push -u origin <branch> 建立上游跟踪,后续 git push 无需再带远端名。

这五步在 ECC 的 commands/pr.md(即 /pr 命令)中被展开为一条六阶段流水线,是规则在 Agent 场景下的完整落地:

  • Phase 1 VALIDATE:用 git branch --show-currentgit status --shortgit log origin/<base>..HEAD --oneline 做前置检查(不在 base 分支、工作区不干净、无领先提交、已存在 PR,任一命中即中止并给出明确提示);
  • Phase 2 DISCOVER:按 .github/PULL_REQUEST_TEMPLATE/.github/PULL_REQUEST_TEMPLATE.md.github/pull_request_template.mddocs/pull_request_template.md 的顺序探测 PR 模板;用 git log origin/<base>..HEAD --format="%h %s" --reverse 分析提交序列决定 PR 标题(多类型时取主导类型,标题沿用 conventional commit 前缀);用 git diff origin/<base>..HEAD --stat--name-only 将变更文件归类为 source/tests/docs/config/migrations;
  • Phase 3 PUSH:执行 git push -u origin HEAD;若远端分叉则 git fetch origin && git rebase origin/<base> 后重推,rebase 冲突则停止并告知用户;
  • Phase 4 CREATE:有模板则填充模板(不删除任何小节,不适用处写 "N/A");无模板则使用内置格式(Summary / Changes / Files Changed / Testing / Related Issues 五节);最终经 gh pr create --title ... --base ... --body ... 创建;
  • Phase 5 VERIFYgh pr view --json number,url,title,state,...gh pr checks 回读校验;
  • Phase 6 OUTPUT:按固定格式回报 PR 编号、URL、分支方向、增删行数、CI 状态与后续操作。

几个值得注意的工程细节:

  • 强推只允许 --force-with-lease/pr 命令的 Edge Cases 明确写了"rebase 后需要 force push 时使用 git push --force-with-lease,never --force",避免覆盖他人的新提交;
  • 大 PR 预警:变更超过 20 个文件时命令会主动建议拆分,与 git-workflow skill 中"PR 理想规模小于 500 行、聚焦单一功能"的反模式清单一致;
  • 环境依赖/pr 依赖 GitHub CLI,未安装或未 gh auth login 时会停止并给出提示。

与 Development Workflow 规则的前置衔接

规则文件尾部的引用块指向"git 操作之前的完整开发流程":

For the full development process (planning, TDD, code review) before git operations, see the development workflow rule.

对应的 common-development-workflow.md 将 git 提交定义为开发管线的最后一步,完整管线为:

  1. Plan First:先用 planner agent 产出实现计划,识别依赖与风险,拆分为阶段;
  2. TDD Approach:tdd-guide agent 主导,先写失败测试(RED)→ 实现至通过(GREEN)→ 重构(IMPROVE),并验证 80%+ 覆盖率;
  3. Code Review:写完代码立即用 code-reviewer agent 审查,必须处理 CRITICAL/HIGH 问题,尽量修复 MEDIUM;
  4. Commit & Push:写详细的提交信息、遵循 conventional commits 格式,"详见 git workflow 规则"——即本文所讲的这条规则。

也就是说,common-git-workflow 管的是"提交和 PR 应该长什么样",common-development-workflow 管的是"提交之前应该发生什么",两条 alwaysApply: true 的规则共同约束 Agent 的完整交付行为。

实战速查表

事项 规则要求 / 命令
提交格式 <type>: <description> + 可选 body
允许类型 feat, fix, refactor, docs, test, chore, perf, ci(commitlint 另放行 style/build/revert)
subject 写法 小写命令式,禁止 sentence/start/pascal/upper-case,首行 ≤ 100 字符
AI 归因 默认无 Co-Authored-By;需要则设 "includeCoAuthoredBy": trueattribution
查看 PR 全量变更 git diff [base-branch]...HEAD
首次推送新分支 git push -u origin <branch>
分叉后同步 git fetch origin && git rebase origin/<base>,冲突则停下人工处理
需要强推时 只用 git push --force-with-lease
提交历史参考 git log origin/<base>..HEAD --format="%h %s" --reverse

适用前提说明:归因相关的 ~/.claude/settings.json 约定仅作用于 ECC 托管安装的 Claude Code 用户(且 includeCoAuthoredBy 在 Claude Code 2.1.x 之后属于弃用但兼容的键);commitlint 校验配置(commitlint.config.js)约束的是 ECC 仓库自身的提交,而规则文件中 8 种类型是面向用户项目的建议集合。如果你要把这套规则移植到其他项目,建议同时引入 commitlint 配置,把"建议"升级为 CI 中的硬校验。

登录后查看全文
热门项目推荐
相关项目推荐