跳转到正文

第八章:Git Worktrees 与分支管理

现代功能开发需要隔离。你需要在不破坏当前工作状态的情况下开发新功能,在无需暂存半成品工作的情况下切换上下文,并在没有频繁切换分支的情况下并行推进多个工作流。Git worktrees 解决了所有这些问题。


什么是 Git Worktrees?

Git worktree 允许你同时检出同一仓库的多个分支——每个分支都在磁盘上的独立目录中。

没有 worktrees 时,你的单一仓库只有一个工作目录。切换分支会更改那个目录中的所有文件。每次切换上下文时,你必须暂存更改、提交进行中的工作,否则就面临丢失状态的风险。

使用 worktrees,你可以同时拥有:

  • ~/projects/myapp/main 分支
  • ~/projects/myapp-feature-auth/feature/auth 分支
  • ~/projects/myapp-hotfix-123/hotfix/issue-123 分支

这三个都是同一个仓库。Commits、tags 和历史记录是共享的。但每个目录都有自己的工作树和暂存区,与其他目录完全隔离。

这是 Superpowers 在 v4.2.0 中引入的强制 worktree 隔离策略的基础:每个功能分支都有自己的 worktree,main 分支永远不会被直接修改。


创建新开发分支

开始新工作时,请遵循以下五个步骤。

第一步:选择目录

将 worktree 目录名称与分支名称匹配。将其放置在主工作目录旁边:

# 主仓库位于:
/Users/you/projects/myapp

# 新 worktree 将位于:
/Users/you/projects/myapp--feature-user-auth

双短横线约定(--)在视觉上将项目名称与分支名称分开,便于通过 ls 识别 worktrees。

第二步:创建分支和 Worktree

# 在主仓库目录内执行:
git worktree add ../myapp--feature-user-auth -b feature/user-auth

# 这将创建:
# 1. 一个名为 feature/user-auth 的新分支
# 2. ../myapp--feature-user-auth 处的新目录
# 3. 该目录已检出到新分支

从现有分支创建 worktree:

git worktree add ../myapp--feature-user-auth feature/user-auth

第三步:安全验证

在开始任何工作之前,验证 worktree 是否正确设置:

cd ../myapp--feature-user-auth

# 验证你在正确的分支上
git branch --show-current
# 预期:feature/user-auth

# 验证 worktree 是干净的
git status
# 预期:nothing to commit, working tree clean

# 验证你从正确的位置分叉
git log --oneline -5
# 应该显示最近的 main 分支历史作为基础

不要跳过这一步。在错误的分支上或在脏树上开始工作是造成令人困惑的 bug 的常见原因。

第四步:项目设置

某些项目在新检出后需要额外设置。在你的新 worktree 中:

# 安装依赖(如果 node_modules 未共享)
npm install

# 如需要,复制环境文件
cp ../myapp/.env.local .env.local

# 生成所有需要的文件
npm run generate

查阅项目的 CLAUDE.mdREADME.md 了解规范的设置步骤。

第五步:基线测试

在编写任何功能代码之前,先运行完整的测试套件:

npm test

开始之前所有测试必须通过。如果测试在干净检出时失败,说明存在预先存在的问题,必须在开始功能工作之前解决。此基线确保在工作期间引入的任何测试失败都是由你的更改造成的,而不是从基础分支继承的。


完成开发分支

当你的功能完成且所有测试通过后,你有四个选项来处理这些工作。

四个选项

选项何时使用发生什么
本地合并(Merge Locally)小变更,你有写入权限,无需审查分支合并到 main,worktree 被移除
创建 PR团队项目、需要审查或必须通过 CI在远程打开 PR,worktree 保留到 PR 合并
保持原样(Keep As-Is)进行中的工作,尚未准备好合并,可能稍后返回Worktree 和分支保留,不采取任何操作
丢弃(Discard)失败的实验,不再需要的工作分支和 worktree 被永久删除

选项 A:本地合并

# 确保测试通过
npm test

# 切换到 main 并合并
cd ../myapp
git checkout main
git pull origin main
git merge --no-ff feature/user-auth -m "feat: add user authentication"

# 移除 worktree
git worktree remove ../myapp--feature-user-auth

# 删除分支
git branch -d feature/user-auth

选项 B:创建 Pull Request

# 将分支推送到远程
cd ../myapp--feature-user-auth
git push -u origin feature/user-auth

# 创建 PR(使用 GitHub CLI)
gh pr create --title "feat: add user authentication" --body "..."

# Worktree 保持活跃,直到 PR 被审查并合并

选项 C:保持原样

无需操作。Worktree 和分支继续存在。在评论或 issue 中记录进行中的工作状态,以免被遗忘。

选项 D:丢弃

警告:此操作是永久性的,无法撤销。

丢弃选项需要明确确认。系统会提示你输入 "discard" 一词。这可以防止意外删除工作成果。

# 移除 worktree 目录
git worktree remove --force ../myapp--feature-user-auth

# 删除本地分支
git branch -D feature/user-auth

# 如果已推送到远程,也删除远程分支
git push origin --delete feature/user-auth

只有当你确定这些工作没有任何价值时才丢弃。如有任何疑问,使用"保持原样"并稍后重新评估。


管理多个 Worktrees

查看仓库的所有活跃 worktrees:

git worktree list

输出示例:

/Users/you/projects/myapp              abc1234 [main]
/Users/you/projects/myapp--feature-auth  def5678 [feature/user-auth]
/Users/you/projects/myapp--hotfix-99   ghi9012 [hotfix/issue-99]

清除过期的 worktree 引用(手动删除目录后):

git worktree prune

Main 分支保护

Superpowers 规范对 main 分支执行一条绝对规则:

永远不要直接 commit 到 main。每次变更都必须通过分支和 worktree 进行。

这由 v4.2.0 的强制 worktree 隔离策略执行。即使是小的"快速"修复也应该使用 worktree。始终在隔离中工作的纪律可以防止整类问题:意外 commit 到 main、在单一分支中混合多个变更,以及失去干净回滚的能力。

如果你发现自己即将直接 commit 到 main,停下来。创建一个 worktree。这只需要 30 秒,却能防止需要数小时才能理清的错误。