一、场景、限制和目录模型
git worktree 允许同一仓库同时检出多个分支,适合并行修复、紧急补丁、长测试和代码审查。它们共享对象数据库,但工作目录、index、HEAD 和未跟踪文件隔离。
工作树目录放仓库外,避免工具递归扫描。一个普通分支不能同时在两个工作树检出。依赖、数据库、端口和 Compose project 仍需主动隔离。
project/ 主工作树:develop
../worktrees/
├── issue-142/ feature/issue-142
├── hotfix-login/ hotfix/login-timeout
└── review-pr-88/ review/pr-88
共享 objects/refs;隔离 index、HEAD、依赖、端口与数据二、创建并核对工作树
创建前记录主工作树状态并获取最新远端引用。进入新目录后再次核对分支和仓库根路径,不凭终端标题判断当前位置。
git status --short
git fetch --prune origin
mkdir -p ../worktrees
git worktree add -b feature/issue-142 ../worktrees/issue-142 origin/develop
git worktree list --porcelain
cd ../worktrees/issue-142
git branch --show-current
git rev-parse --show-toplevel三、隔离依赖、数据库和端口
不同工作树不能共享可写 node_modules、vendor、SQLite 文件或同名 Compose project,否则测试互相污染。下载缓存可以共享,构建产物和数据库必须独立。秘密文件保持忽略并限制权限。
APP_PORT=81142
DB_DATABASE=project_issue_142
COMPOSE_PROJECT_NAME=project_issue_142cp .env.example .env.local
chmod 600 .env.local
npm ci
docker compose --env-file .env.local up -d
docker compose --env-file .env.local ps四、用 Pre-commit 提供快速反馈
本地钩子检查 YAML、JSON、尾随空格、私钥和大文件,再运行聚焦测试。钩子应在数十秒内完成,耗时集成测试放 CI。本地钩子可跳过,因此绝不能替代 CI。
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-yaml
- id: check-json
- id: detect-private-key
- id: check-added-large-files
args: ['--maxkb=1024']
- repo: local
hooks:
- id: project-tests
name: focused project tests
entry: ./scripts/precommit-tests.sh
language: system
pass_filenames: falsepre-commit install
pre-commit run --all-files
git diff --check五、用 Taskfile 统一本地与 CI 命令
Taskfile 只封装可读命令,不隐藏破坏性动作。删除卷和重置数据库要提示并限定当前项目。CI 调用同一个 task check,减少环境规则漂移。
version: '3'
tasks:
bootstrap:
cmds: ['npm ci','docker compose --env-file .env.local up -d']
check:
cmds: ['npm run lint','npm run typecheck','npm test -- --run','git diff --check']
clean:
prompt: This removes only this worktree stack and volumes. Continue?
cmds: ['docker compose --env-file .env.local down -v']task --list
task bootstrap
task check六、小步提交和可审查差异
提交前查看 status、stat 和完整 diff,只 add 目标文件。提交标题说明类型、范围和结果,正文解释原因与验证。一个提交只含一个可回滚意图,格式化和功能修改尽量分开。
git status --short
git diff --stat
git diff
task check
git add src tests
git diff --cached --check
git commit -m 'fix(auth): handle upstream timeout deterministically'
git push -u origin feature/issue-142七、同步基线和解决冲突
是否 rebase 服从团队规则;已被他人依赖的共享分支不要擅自改写历史。文本冲突消失不代表语义正确,解决后必须重跑测试。强制推送使用 force-with-lease 保护远端新提交。
git fetch origin
git status --short
git rebase origin/develop
# 解决后
git add <resolved-files>
git rebase --continue
task check
git push --force-with-lease八、隔离审查外部分支
审查工作树使用独立端口和只读测试数据,不污染正在开发的目录。未经授权不在作者分支直接修改;把复现命令、位置和证据反馈给作者。
git fetch origin pull/88/head:review/pr-88
git worktree add ../worktrees/review-pr-88 review/pr-88
cd ../worktrees/review-pr-88
git diff --stat origin/develop...HEAD
task check九、安全清理与恢复
清理前证明没有未提交内容,确认重要提交已推送且分支已合并。先停止该工作树专属环境,再用 git worktree remove;不要直接删除目录留下陈旧元数据。自动化默认不得使用 --force。
cd /path/to/main/project
git -C ../worktrees/issue-142 status --short
git -C ../worktrees/issue-142 log --oneline --decorate -5
git branch --merged origin/develop | grep 'feature/issue-142' || true
docker compose --env-file ../worktrees/issue-142/.env.local down
git worktree remove ../worktrees/issue-142
git worktree prune --dry-run
git worktree prune
git worktree list十、故障排查和验收
already checked out 表示分支在另一工作树使用;先用 list 找目录。目录已手工删除时先 prune --dry-run。端口和数据库冲突说明环境隔离不完整;构建互相覆盖说明共享了可写依赖或产物。
- 每个工作树分支、端口、数据库和 Compose project 唯一。
- 本地检查与 CI 调用同一命令。
- 清理前 status 为空且重要提交已推送。
- prune 后 worktree list 不含陈旧记录。
总结
worktree 的价值不是多开目录,而是为每条并行任务提供清晰的分支、环境和验证边界。配合 pre-commit、Taskfile、规范提交、独立数据与安全清理,可以并行工作且保持变更可审查、可测试、可回滚。