tldraw 仓库实战:用 clean-copy 技能把混乱分支重写成叙事级提交历史
【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. World's best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw
导读
本指南以 tldraw 仓库内置的 Agent 技能文档 skills/clean-copy/SKILL.md 为核心,完整讲解如何在 tldraw 这类大型 monorepo 中,将当前分支的杂散开发过程重写为一条全新的、具有叙事质量的干净提交历史分支。读完本文,你将掌握完整的九步重写工作流、--no-verify与钩子机制的权衡、以及与 tldraw 仓库pr、write-pr、commit-changes等周边技能协同的 PR 提交流程。
为什么需要 clean copy
在 tldraw 仓库(一个使用 Yarn workspaces 组织的无限画布 SDK monorepo,核心包包括packages/editor、packages/tldraw、packages/store、packages/tlschema、packages/state等)中,长时间开发的分支往往积累了大量中间提交:调试用的临时改动、来回反复的取舍、甚至带钩子失败记录的提交。这些提交对审阅者(reviewer)来说难以理解。
clean-copy 技能的定位(见其 frontmatter 的description)非常明确:当用户要求制作干净的分支副本、通过重放工作清理提交历史、或把分支重建为可审阅的提交时使用。其核心思路不是git rebase式改写,而是:
Reimplement the current branch on a new branch with a clean, narrative-quality commit history suitable for reviewer comprehension.
即在新分支上重新实现当前分支的最终状态,每一步提交都像教程中的一个开发阶段,让审阅者可以按逻辑顺序读懂实现过程。
技能与 tldraw 仓库的关联
该技能是 tldraw 仓库中面向用户的技能集之一。根据仓库根目录的 AGENTS.md 说明,面向用户的工作流技能包括skills/pr/、skills/issue/、skills/take/、skills/commit-changes/和skills/clean-copy/。这些技能遵循统一规范:以skill-name/SKILL.md形式组织,YAML frontmatter 至少包含name与description,body 为 Markdown 指令。clean-copy 技能在流程末尾显式调用pr技能开 PR,并引用write-pr技能作为 PR 内容标准,因此理解 clean-copy 需要同时理解这一技能链。
完整九步工作流
步骤 1:收集上下文
重写前必须先完整掌握源分支的状态,技能要求执行四个 Git 命令:
git branch --show-current # 确认源分支名 git status --short # 检查工作区状态 git log main..HEAD --oneline # 列出自 main 以来的提交 git diff main...HEAD --stat # 统计与 main 的差异概况注意最后一个命令使用的是三点差异main...HEAD,即以main与HEAD的合并基为基准比较,反映的是本分支真正引入的改动,而不是main上同期合并的其他改动。
步骤 2:验证源分支
在动手之前必须确认两个前提:
- 无未提交的更改或合并冲突:工作区必须干净,否则重写过程无法保证可复现;
- 源分支已与
main同步:确保最终目标状态包含main的最新内容,避免开 PR 时出现不必要的冲突。
这与 AGENTS.md 中「Respect existing worktree changes. Do not revert user changes unless explicitly asked」的规则一致——技能先验证再操作,不会擅自处理脏工作区。
步骤 3:选择新分支名
分支命名规则:
- 用户指定了名称时优先使用用户提供的名称;
- 否则使用默认约定:
<source-branch>-clean。
例如源分支为feature/arrows-binding,默认新分支名即为feature/arrows-binding-clean。
步骤 4:分析差异
在重建之前,必须完整研究源分支相对main的所有改动,理解最终想要达成的状态。技能强调 "Understand the final intended state before recreating it"——重写不是盲目重放提交,而是先明确终点,再规划如何分步走到终点。此时可以使用git diff main...HEAD细读每一处改动,并结合仓库源码理解其意图。
步骤 5:从 main 创建干净分支
git switch -c <new-branch> main新分支直接从main创建,而不是从源分支复制历史,这是实现「干净历史」的前提——旧分支上所有杂乱提交都不会进入新分支。
步骤 6:规划提交叙事线(commit storyline)
这是整个技能的核心思想:把实现拆分为自包含的逻辑步骤,每一步都读起来像教程中的一个开发阶段。规划时考虑:
- 每个提交应该是一个完整、可独立理解的概念(一个 idea 一次提交);
- 提交顺序应该体现从零到一的发展脉络,而不是按时间线堆叠;
- 每一步的大小以「审阅者不需要查看多个提交才能理解一个功能」为准。
步骤 7:逐步重实现并提交
按规划的叙事线,逐步重建最终改动,每完成一个连贯的想法就提交一次。这里有一个关键技术细节:
git commit --no-verify中间提交使用--no-verify,让钩子(hooks)不会因为临时不完整的中间状态而阻塞提交。这背后对应 tldraw 仓库的实际钩子配置——根目录 package.json 中配置了lint-staged(配合 husky 的 pre-commit 钩子):
"lint-staged": { "*.{js,jsx,ts,tsx,cjs,mjs}": [ "oxfmt --no-error-on-unmatched-pattern", "oxlint --no-error-on-unmatched-pattern" ], "*.{css,md,mdx,html,yml,yaml}": [ "oxfmt --no-error-on-unmatched-pattern" ] }即每次提交都会对暂存文件运行oxfmt(格式化)与oxlint(lint)。如果中间状态格式不完整或存在临时代码,钩子会失败并阻止提交,因此技能要求中间步骤跳过钩子,最后一步再跑完整检查。
提交信息本身要求清晰的 subject 与 description,遵循仓库统一的 Conventional Commits 规范(详见下文「与 commit-changes 的规范对齐」)。
步骤 8:验证正确性
重写完成后必须确认两点:
- 最终干净分支的状态与原源分支完全一致——可以通过对比两个分支的差异确认:
git diff <source-branch> <new-branch> --stat技能原话是 "Confirm the final clean branch state exactly matches the original source branch",这是硬性要求:重写只允许改变提交历史,不允许改变最终代码状态。
- 最后一步提交不使用
--no-verify,让常规检查(oxfmt、oxlint)完整运行,确保干净分支的最终状态通过仓库所有提交门禁。
步骤 9:使用 pr 技能打开 PR
最后调用 skills/pr/SKILL.md 打开 Pull Request,并在 PR 描述中包含指向原分支的链接,方便审阅者对比。
规则:四条不可逾越的红线
技能最后给出四条纪律性规则:
- 绝不把自己或 AI 工具添加为作者、贡献者或共同作者(co-author)——包括提交和 PR 内容中;
- 绝不在提交或 PR 内容中包含 AI 归属说明;
- 最终干净分支必须与源分支完全一致(状态层面);
- 除非用户明确要求,不要强制推送(force push)。
这些规则与 tldraw 仓库的全局约定高度一致。AGENTS.md 在「Git and PR notes」一节明确写道:"Never add yourself or an AI tool as a co-author",而 skills/write-pr/SKILL.md 的Important部分也强调 "Never include AI attribution unless the PR directly relates to AI tooling"。也就是说,clean-copy 产出的提交历史必须是看起来完全由人类作者自然书写的。
与相关技能链的协同
clean-copy 不是孤立的,它处于 tldraw 仓库完整的 Agent 工作流技能链中:
- skills/pr/SKILL.md:clean-copy 第 9 步显式调用它开 PR。pr 技能负责完整的 PR 生命周期:检查重叠工作(
gh pr list)、准备分支并推送、开 PR 前的自查 pass、用gh pr create/gh pr view/gh pr edit管理 PR,以及链接相关 issue(Closes #123/Relates to #123)。 - skills/write-pr/SKILL.md:PR 内容标准参考。它要求 PR 标题使用语义化格式(Conventional Commits)
<type>(<scope>): <description>,类型包括feat、fix、docs、refactor、perf、test、chore;正文遵循「为审阅者而写」的倒金字塔结构——目标与动机在最前,其次是大体方案、API 设计与决策、最后才是示例片段。 - skills/commit-changes/SKILL.md:普通提交场景的规范,与 clean-copy 的提交信息风格一致。它规定提交信息格式:
type(scope): brief description Optional longer explanation if the changes are complex.允许的类型为feat、fix、refactor、test、docs、chore、perf、style、build、ci;首行不超过 72 字符,使用祈使语气(add feature而非added feature)。有意思的是,commit-changes 明确禁止使用--no-verify,而 clean-copy 在中间提交时允许它——两者的区别恰恰体现了「中间状态 vs 最终状态」的不同场景。
- skills/shepherd-pr/SKILL.md:PR 开完之后维护提交历史的闭环。它补充了一个环境前提——"this repository requires that you be using node 24",需先用
nvm use 24切换 Node 版本。根目录 package.json 的engines字段声明node >= 22.12.0、yarn@4.17.1,仓库规则要求用yarn而非npm运行命令。
实战要点与最佳实践总结
把技能映射到 tldraw 仓库的真实开发场景,以下要点值得牢记:
1. 何时用 clean-copy 而不是 rebase?技能描述中的触发场景是:用户要求「clean copy branch」「clean up commit history by replaying work」「rebuild a branch as reviewable commits」。它适合历史已经乱到 rebase 无法挽救、或者希望提交线呈现教程式结构的情况。
2. 中间提交的钩子权衡:tldraw 的 pre-commit 钩子会运行oxfmt与oxlint(根目录 package.json 的lint-staged配置)。中间提交用--no-verify绕过,最终提交必须跑全量检查。这一步在大型重构中能省下大量「为了过 lint 而临时补格式」的时间。
3. 状态一致性是硬指标:重写历史唯一允许改变的是「提交的切分方式」,绝不允许改变「最终代码状态」。验证时对比新旧分支的 tree 差异应为空。
4. 技能链接力:clean-copy → pr → write-pr → shepherd-pr 构成了从「重写分支」到「PR 合入后维护」的完整链路。开 PR 时按 write-pr 标准写标题正文、在描述中附原分支链接;合入前按 shepherd-pr 处理审阅线程与 CI 失败。
5. 仓库环境前提:命令基于 Git 与 GitHub CLI(gh),Node 需满足仓库engines要求(>=22.12.0),shepherd-pr 进一步要求 node 24;所有仓库级命令从根目录用yarn执行。
结语
clean-copy 技能为 tldraw 仓库提供了一套把「过程混乱」转化为「叙事清晰」的分支重写方法论:九步工作流保证了从收集上下文、验证、规划、重实现到验证、开 PR 的完整闭环;四条规则保证了产出历史的可信度与规范性;与pr、write-pr、commit-changes等技能的协同则让它融入仓库现有的 Agent 工作流体系。无论你是 tldraw 的贡献者还是参考其技能设计模式维护自己的仓库,这套「以最终状态为目标、以叙事线组织提交」的思路都值得直接借鉴。
【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. World's best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考