EverOS 分支模型与/new-branch工作流:基于 main 保护策略的 Git 协作规范
【免费下载链接】EverOSOne portable memory layer for every AI agent: local-first, Markdown-native, user-owned, and self-evolving across apps, tools, and workflows.项目地址: https://gitcode.com/gh_mirrors/ev/EverOS
本篇文章深入解析 EverOS 仓库中.claude/skills/new-branch/SKILL.md所定义的 GitHub 分支创建规范:从分支类型模型、操作步骤到命名约定,并延伸讲解仓库中配套的提交信息、PR 校验与 CI 门禁,帮助贡献者与维护者建立一套可复制、可校验的分支协作流程。读完本文,你将掌握 EverOS 的分支命名体系、从main切出特性分支的标准命令序列,以及仓库如何用 gitlint、pre-commit 与脚本门禁保证这条规范不被绕过。
一、为什么需要一套统一的分支模型
EverOS 是一个以main为默认分支、且默认受保护(default and protected branch)的仓库。在 CONTRIBUTING.md 的「For maintainers (core team)」一节中,项目明确规定:不要直接向main推送(Do not push directly tomain),不要对共享分支强制推送,所有变更必须通过 PR 合入,且需在必需检查通过之后。
.claude/skills/new-branch/SKILL.md正是把这一协作约束固化为 Claude Code 斜杠命令/new-branch的完整定义。它的价值在于:当开发者(尤其是 AI 辅助开发环境)需要新建分支时,不用再去回忆「这个改动该用feat/还是fix/前缀」,而是由技能文件给出确定性的分支模型、步骤与命名规范,从源头保证仓库历史清晰、可审计、可回溯。
二、分支模型:六类分支与各自的职责边界
/new-branch技能将仓库分支收敛为如下模型:
main = default and protected branch feat/* = feature work fix/* = bug fixes docs/* = documentation-only changes ci/* = CI, build, and developer-experience changes chore/* = repository maintenance refactor/* = behavior-preserving code structure changes这一模型与 CONTRIBUTING.md 中维护者分支策略表完全一致,两者互为印证:
| 分支 | 职责 |
|---|---|
main | 默认且受保护的分支 |
feat/<scope>-<desc> | 功能开发 |
fix/<scope>-<desc> | 缺陷修复 |
docs/<scope>-<desc> | 仅文档变更 |
ci/<scope>-<desc> | CI、构建与开发者体验相关变更 |
其中refactor/*的语义值得注意:它专指保持行为不变的代码结构重构(behavior-preserving code structure changes)。如果某次重构改变了外部行为,那它本质上应当归类为feat/或fix/,而不是refactor/。这个区分确保评审者在看到分支名时就能预判改动的风险等级。
三、标准操作步骤:从同步 main 到提交 PR
/new-branch的核心流程只有四步,但每一步都有明确约束:
第 1 步:确认变更类型
先询问(或根据上下文推断)本次变更属于哪一类:feat、fix、docs、ci、chore或refactor。类型判断是后续一切命名与 PR 归类的前提,.claude/skills/pr/SKILL.md 中 PR 模板的Area一栏也要求勾选 architecture / benchmark / use case / docs / DX / CI-build-release 等区域,与分支类型形成对应关系。
第 2 步:先更新 main
任何新分支都必须从最新的main切出,避免基于过期主干开发:
git checkout main git pull --ff-only使用--ff-only是关键细节:它强制快进合并,一旦本地main与远端产生分叉就会直接失败,从而杜绝「本地 main 落后却继续在其上开分支」的隐患。
第 3 步:以 kebab-case 短横线命名创建分支
git checkout -b <type>/<short-slug>例如git checkout -b feat/add-agentic-rerank。slug 应尽量短小精炼(short-slug),仅描述本次改动的核心目的。
第 4 步:保持单一职责并提交 PR
分支必须「一个分支只做一件事」(Keep the branch scoped to one purpose),最终通过 Pull Request 合回main。这与 .claude/skills/commit/SKILL.md 中「一次提交只包含一个逻辑变更、保持历史可 bisect」的要求一脉相承。
四、命名规范:类型前缀 + kebab-case
技能文件给出了明确的命名规则:
- 示例:
feat/add-agentic-rerank、fix/empty-profile-crash、docs/quickstart-config、ci/check-github-docs - 规则:全部小写、用连字符(hyphen)分隔、不允许空格、尽量简洁
注意前缀类型与提交信息的 type 字段遵循同一套词表。在 scripts/check_commit_messages.py 中,ALLOWED_TYPES被定义为 11 种:feat, fix, refactor, test, docs, style, perf, chore, build, ci, revert,分支命名所用的类型是该集合的子集,保持「分支名 → 提交信息 → PR 标题」三者风格统一。
五、绝不对 main 直接提交:多层防护机制
/new-branch的最终约束是Never commit directly tomain— always use a branch and pull request。这句话在仓库中并不是一句口号,而是被多层工具链强制执行的:
1. gitlint:commit-msg 阶段的提交信息门禁
仓库根目录的 .gitlint 配置启用了contrib-title-conventional-commits,并显式声明忽略 merge / revert / fixup / squash 提交:
[general] contrib=contrib-title-conventional-commits ignore-merge-commits=true ignore-revert-commits=true ignore-fixup-commits=true ignore-squash-commits=true [contrib-title-conventional-commits] types=feat,fix,refactor,test,docs,style,perf,chore,build,ci,revert [title-max-length] line-length=72也就是说,提交标题必须以合法 type 开头、总长不超过 72 字符,否则commit-msg钩子直接拒绝。
2. pre-commit 钩子矩阵
.pre-commit-config.yaml 中:
- 通过
make install(内部执行uv run pre-commit install与uv run pre-commit install --hook-type commit-msg)同时安装 pre-commit 与 commit-msg 两个阶段的钩子; - gitlint 只在
commit-msg阶段运行(stages: [commit-msg]); - 其余钩子(ruff、trailing-whitespace、check-yaml、check-merge-conflict、detect-private-key 等)在提交前阶段拦截格式与安全隐患。
3. 脚本门禁与 Makefile 入口
Makefile 提供了两个直接对应本主题的目标:
make check-commits # python3 scripts/check_commit_messages.py $(RANGE) make check-pr-title # python3 scripts/check_pr_title.py- scripts/check_commit_messages.py 会扫描指定 git 范围内(默认根据
GITHUB_EVENT_NAME、GITHUB_SHA等环境变量推导)的所有提交,校验主题长度(MAX_TITLE_LENGTH = 72)与正则^('|'.join(ALLOWED_TYPES))(\([A-Za-z0-9._/-]+\))?(!)?: .+,即<type>[(scope)][!]: <description>格式; - scripts/check_pr_title.py 复用同一策略模块,校验 PR 标题,并支持从
PR_TITLE环境变量读取标题(便于 CI 集成)。其配套单测 tests/unit/test_scripts/test_check_pr_title.py 覆盖了「合法标题放行」「[codex] ...这类非规范前缀被拦截」「超过 72 字符被拦截」三类典型场景。
这三层防线(本地钩子、脚本门禁、CI 工作流)共同保证:即便开发者绕过/new-branch手动操作,不合规的分支/提交/PR 标题也无法通过合入门槛。
六、与 /commit、/pr 的协作闭环
/new-branch不是孤立存在的。在 CONTRIBUTING.md 的「Slash commands (Claude Code)」一节中,EverOS 提供了三个成体系的斜杠命令:
/new-branch— 按正确命名规范创建分支/commit— 生成符合 Conventional Commits 的提交信息/pr— 以正确目标分支打开 GitHub PR
.claude/skills/pr/SKILL.md 展示了完整闭环:先确认 base 分支是main、head 分支是feat/*之类的 scoped 分支,本地跑make ci确保全部检查通过后再git push -u origin HEAD,最后gh pr create --base main --fill-first并补全 PR 模板。
也就是说,一个标准的 EverOS 贡献周期是:/new-branch切分支 → 开发 →/commit规范提交 →make ci全量校验 →/pr合入 main。本文所讲的分支模型是这个周期里的第一环,也是后续所有门禁生效的前提。
七、实战小结:一份可直接执行的分支操作清单
综合以上内容,给出 EverOS 中一次合规变更的完整命令序列:
# 1. 同步 main git checkout main git pull --ff-only # 2. 按变更类型创建 kebab-case 分支 git checkout -b fix/empty-profile-crash # 3. 开发并规范提交(gitlint 在 commit-msg 阶段校验) git add <changed-files> git commit -m "fix(search): guard empty profile" # 4. 全量校验 make ci # 5. 推送并打开指向 main 的 PR git push -u origin HEAD gh pr create --base main --fill-first需要特别提醒的两点约束:其一,分支名与提交信息必须为纯小写 + 连字符的 kebab-case,杜绝空格与大写;其二,永远不要绕过 PR 直接向main推送——这条规则同时被 CONTRIBUTING.md、.gitlint 与脚本门禁三重背书,是 EverOS 协作模型不可动摇的底线。
【免费下载链接】EverOSOne portable memory layer for every AI agent: local-first, Markdown-native, user-owned, and self-evolving across apps, tools, and workflows.项目地址: https://gitcode.com/gh_mirrors/ev/EverOS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考