Claude Code 学习笔记3-拓展使用:用 git worktree 与 hooks 打通 GitHub 协作流
1. 真实仓库里跑 Claude Code为什么单目录会翻车如果你已经在本地用 Claude Code 改过几个文件大概率会遇到一个很尴尬的场景主分支上正在跑一个功能突然要修一个线上 bug你让 Claude 去改它顺手把当前工作区的文件全动了等你切回来发现未提交的改动和 AI 的改动搅在一起git status一片红根本分不清哪块是谁写的。这不是 Claude 的问题是工作区隔离没做好。Claude Code 在真实仓库里的定位不是一个「帮你补全几行」的插件而是一个能读文件、跑命令、装依赖、执行测试的编码代理。它越能干越需要给它一个干净的沙箱。git worktree就是 Git 原生提供的这个沙箱同一个仓库可以同时检出多个分支到不同目录各自独立互不覆盖。配合hooks你还能在 Claude 每次提交前后自动跑 lint、跑测试把「AI 写完就提交」变成「AI 写完先过检查」。这篇是学习笔记的第三篇聚焦拓展用法。我会给出可复制的 worktree 目录规划、hooks 配置片段以及一次从建 worktree 到推送 GitHub 的完整验证动作。适合已经在用 Claude Code、但还没把它接进团队仓库协作流的人。核心检索词就三个Claude Code、git worktree、GitHub hooks。读完你能把本地 AI 编码接进团队仓库而不互相污染。先说清楚一个前提Claude Code 本身不替代编辑器也不替代 Git。它是在你的终端里工作的代理你给它指令它读代码、改代码、跑命令。所以隔离和检查这两件事必须由 Git 和 hooks 来兜底而不是指望模型自觉。2. 前置准备TaoToken 接入 Claude Code 的 Base URL 与 Key在折腾 worktree 和 hooks 之前得先让 Claude Code 能稳定跑起来。我用的是 TaoToken 的接入方式它提供兼容 Anthropic 的 API 端点Claude Code 直接改环境变量就能用。官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 注意 API 地址不带 UTM 参数配置时别把查询串带进去。Claude Code 读取的是环境变量最省事的做法是在 shell 配置里导出。你需要三样东西Base URL、API Key、Model ID。Base URL 填https://taotoken.net/apiKey 在控制台的 API Keys 页面生成Model ID 按你订阅的模型填。这三件套是后面所有配置的基础缺一个都会报 401。去控制台拿 Key 的入口是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 生成后复制出来只显示一次。如果你还没决定用哪个模型可以先在模型对话页面试一下 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 确认响应正常再写进配置。环境变量这样导出写进~/.zshrc或~/.bashrcexport ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的Key export ANTHROPIC_MODEL你的ModelID改完source ~/.zshrc生效。这里有个坑如果你之前配过别的端点环境变量会覆盖配置文件所以先echo $ANTHROPIC_BASE_URL确认一下当前值。确认无误后在任意仓库目录跑claude能正常对话就说明接入通了。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各客户端的详细参数。如果你打算长期用 Claude Code 做编码和 Agent 任务Coding Plan 会更划算入口是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。前置准备就这些接下来进入正题。3. 可复制配置worktree 目录规划与 hooks 片段这一节是全文的技术核心给你能直接抄的配置。先规划 worktree 目录。我习惯在仓库根目录建一个.trees/文件夹每个实验分支一个子目录命名跟分支语义对齐。这样git status不会把 worktree 目录当成未跟踪文件记得加进.gitignore。# 在仓库根目录执行 mkdir -p .trees echo .trees/ .gitignore # 为 ui 功能建一个隔离工作区 git worktree add .trees/ui_feature -b feature/ui # 为修 bug 建另一个基于 main git worktree add .trees/fix_login -b hotfix/login # 查看当前所有 worktree git worktree list每个.trees/xxx目录都是一个完整的工作区可以各自开一个终端跑claude。这样两个 Claude 实例同时改代码文件不会互相覆盖。实测下来git worktree list会列出主工作区和两个子工作区路径和分支一目了然。用完清理git worktree remove .trees/ui_feature --force注意--force会丢弃未提交改动确认不需要了再删。分支本身还在git branch -a能看到。接下来是 hooks。Claude Code 支持在工具执行前后挂 hook配置写在.claude/settings.json里。下面这段是提交前跑 lint、提交后发通知的片段路径和字段名按官方结构来{ hooks: { PreToolUse: [ { matcher: Bash, hooks: [ { type: command, command: if echo \$CLAUDE_TOOL_INPUT\ | grep -q git commit; then npm run lint; fi } ] } ], PostToolUse: [ { matcher: Bash, hooks: [ { type: command, command: echo \[hook] 命令执行完成: $(date)\ .claude/hook.log } ] } ] } }PreToolUse在工具执行前触发可以用来拦截。上面这段的逻辑是如果 Claude 要跑git commit先跑npm run lintlint 不过就中断提交。PostToolUse在工具执行后触发这里只是记日志你也可以换成发消息、跑测试。matcher 匹配的是工具名Bash表示所有 shell 命令。如果你用的是 Codex 或 Cline 这类客户端配置结构不同但思路一样。Codex 的auth.json里放的是凭据Base URL 和 Model ID 在 config 里Cline 的 MCP 配置是 JSON字段是command和args。不管哪个客户端三件套都是 Base URL、Key、Model ID缺一不可。Claude Code 的 settings.json 里不直接放 KeyKey 走环境变量这点别搞混。hooks 的粒度可以很细。比如你想在 Claude 改完文件后自动格式化可以挂PostToolUse匹配Edit或Write跑prettier --write。想阻止它碰某些目录可以在PreToolUse里判断路径命中就返回非零退出码。这些都能在 settings.json 里用 shell 命令实现不需要写插件。4. 验证请求从 worktree 到 GitHub 的完整动作配置写完得跑一遍完整流程验证。我拿一个真实的小仓库演示主分支有个登录页我要在隔离工作区里让 Claude 加一个「记住我」勾选框跑完 lint 再推 GitHub。第一步建 worktree 并进入git worktree add .trees/remember_me -b feature/remember-me cd .trees/remember_me第二步启动 Claude Code给它明确指令。指令里带上上下文和验收标准比如「在登录表单里加一个记住我勾选框改完跑 npm run lint 和 npm test全过再提交」。Claude 会读相关文件、改代码、跑命令。如果测试挂了它会根据报错自己迭代缺依赖会自动npm install。第三步观察 hooks 是否生效。当 Claude 执行git commit时PreToolUse会先跑 lint。你可以在终端看到 lint 输出如果报错提交会被拦下Claude 会尝试修。修完再提交通过后PostToolUse往.claude/hook.log写一行记录。第四步推送并合并git push origin feature/remember-me然后在 GitHub 上开 PRreview 合并。整个过程主工作区没被碰过你随时可以切回去继续原来的活。验证成功的标志有三个git worktree list显示三个工作区、.claude/hook.log有记录、GitHub 上 PR 正常创建。如果你在验证时想确认模型响应是否正常可以先去模型对话页面发一条测试 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 排除是 Key 或端点的问题。确认接入没问题再回来查 worktree 和 hooks。这一步跑通后你就有了一个可复用的协作流每个任务一个 worktree每个提交过 hooks最后走 GitHub PR。团队里多人用 Claude Code 也不会互相踩。5. 常见报错排查401、local proxy failed 与 OAuth跑这套流程最容易撞的几个错我列一下对照着查。401 Unauthorized九成是 Key 或 Base URL 不对。先echo $ANTHROPIC_API_KEY和echo $ANTHROPIC_BASE_URL确认 Key 没多空格、Base URL 是https://taotoken.net/api不带查询串。如果环境变量对但还报 401检查是不是有别的配置文件覆盖了比如~/.claude/settings.json里写了旧端点。三件套里 Model ID 填错有时也会表现成鉴权失败一并核对。local proxy failed这个通常出现在客户端试图走本地代理但代理没起来。Claude Code 本身不需要本地代理如果你看到这个错先检查是不是装了某个中间层工具在转发。把ANTHROPIC_BASE_URL直接指向https://taotoken.net/api绕开本地转发。另外确认没有残留的HTTP_PROXY/HTTPS_PROXY环境变量干扰。reading choices 报错一般是响应体解析失败常见于端点返回了非预期格式。先确认 Base URL 没写错路径比如多加了/v1或少加了。用 curl 直接打一下端点验证curl -s https://taotoken.net/api/v1/messages \ -H x-api-key: $ANTHROPIC_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d {model:你的ModelID,max_tokens:32,messages:[{role:user,content:ping}]}返回正常 JSON 说明端点没问题问题在客户端配置。OAuth 相关报错Claude Code 某些版本会尝试 OAuth 流程如果你用的是 API Key 接入不需要 OAuth。看到 OAuth 报错检查是不是登录态和 Key 混用了。清掉客户端的登录缓存只用环境变量里的 Key。Codex 的auth.json如果残留旧凭据也会冲突删掉重新生成。worktree 报错already checked out同一个分支不能同时检出到两个 worktree。git worktree list看哪个目录占用了要么换分支名要么先 remove 旧的。hooks 不触发检查.claude/settings.json的 JSON 格式逗号多了少了都会静默失败。用jq . .claude/settings.json验证语法。另外确认 matcher 写的是工具名大小写敏感。排障时如果怀疑是接入层问题去接入文档对照参数 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 或者重新生成一个 Key 试试 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。大部分报错都是配置层面的跟模型能力无关。6. 把 AI 编码接进团队仓库的下一步worktree 加 hooks 这套组合解决的是「隔离」和「检查」两个问题。隔离让多个 Claude 实例不打架检查让 AI 的产出在进主干前先过一道关。这两件事做完Claude Code 才算真正接进团队协作流而不是停留在个人玩具阶段。我自己的习惯是每个任务开工前先git worktree add任务结束提 PR 后git worktree remove。hooks 里至少挂一个 lint 和一个测试提交前必须过。这样即使 Claude 某次改得离谱也进不了主干。长期跑编码和 Agent 任务的话Coding Plan 比按量更省心入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。下一步你可以试试把 hooks 扩展到更多节点比如 Claude 改完 Jupyter Notebook 后自动跑一遍数据校验或者接 Figma MCP 把原型转成页面后自动截图比对。这些都是在同一套隔离加检查的框架里加动作思路不变。先把 worktree 和 hooks 跑顺剩下的就是往里填你自己的检查逻辑。