git%3Aworktrees by neolabhq/context-engineering-kit
npx skills add https://github.com/neolabhq/context-engineering-kit --skill git:worktreesGit 工作树允许在独立的目录中同时检出多个分支,所有这些目录共享同一个仓库。创建一个工作树,而不是暂存更改或单独克隆。
核心原则: 每个活动分支对应一个工作树。通过切换目录来切换上下文,而不是切换分支。
| 概念 | 描述 |
|---|---|
| 主工作树 | 来自 git clone 或 git init 的原始工作目录 |
| 链接工作树 | 使用 git worktree add 创建的额外目录 |
共享的 .git | 所有工作树共享同一个 Git 对象数据库(无重复) |
| 分支锁定 | 每个分支一次只能在一个工作树中检出 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 工作树元数据 | 位于 .git/worktrees/ 中用于跟踪链接工作树的管理文件 |
| 任务 | 命令 |
|---|---|
| 创建工作树(现有分支) | git worktree add <路径> <分支> |
| 创建工作树(新分支) | git worktree add -b <分支> <路径> |
| 创建工作树(从引用创建新分支) | git worktree add -b <分支> <路径> <起始点> |
| 创建分离头指针工作树 | git worktree add --detach <路径> <提交> |
| 列出所有工作树 | git worktree list |
| 移除工作树 | git worktree remove <路径> |
| 强制移除工作树 | git worktree remove --force <路径> |
| 移动工作树 | git worktree move <旧路径> <新路径> |
| 锁定工作树 | git worktree lock <路径> |
| 解锁工作树 | git worktree unlock <路径> |
| 清理陈旧工作树 | git worktree prune |
| 修复工作树链接 | git worktree repair |
| 比较工作树间的文件 | diff ../worktree-a/file ../worktree-b/file |
| 从另一个分支获取单个文件 | git checkout <分支> -- <路径> |
| 获取部分文件更改 | git checkout -p <分支> -- <路径> |
| 拣选提交 | git cherry-pick <提交> |
| 拣选但不提交 | git cherry-pick --no-commit <提交> |
| 合并但不自动提交 | git merge --no-commit <分支> |
# 使用现有分支创建工作树
git worktree add ../feature-x feature-x
# 从当前 HEAD 创建新分支的工作树
git worktree add -b new-feature ../new-feature
# 从特定提交创建新分支的工作树
git worktree add -b hotfix-123 ../hotfix origin/main
# 创建跟踪远程分支的工作树
git worktree add --track -b feature ../feature origin/feature
# 创建分离头指针工作树(用于实验)
git worktree add --detach ../experiment HEAD~5
# 简单列表
git worktree list
# 详细输出,包含额外信息
git worktree list -v
# 机器可读格式(用于脚本)
git worktree list --porcelain
示例输出:
/home/user/project abc1234 [main]
/home/user/project-feature def5678 [feature-x]
/home/user/project-hotfix ghi9012 [hotfix-123]
# 移除工作树(工作目录必须干净)
git worktree remove ../feature-x
# 强制移除(丢弃未提交的更改)
git worktree remove --force ../feature-x
# 将工作树重新定位到新路径
git worktree move ../old-path ../new-path
# 锁定工作树(如果在可移动存储上,可防止被清理)
git worktree lock ../feature-x
git worktree lock --reason "On USB drive" ../feature-x
# 解锁工作树
git worktree unlock ../feature-x
# 移除陈旧的工作树元数据(在手动删除目录后)
git worktree prune
# 试运行以查看将被清理的内容
git worktree prune --dry-run
# 详细输出
git worktree prune -v
# 在手动移动目录后修复工作树链接
git worktree repair
# 修复特定工作树
git worktree repair ../feature-x
在功能开发过程中修复错误:
# 从 main 分支创建热修复工作树
git worktree add -b hotfix-456 ../project-hotfix origin/main
# 切换到热修复目录,修复,提交,推送
cd ../project-hotfix
git add . && git commit -m "fix: resolve critical bug #456"
git push origin hotfix-456
# 返回功能开发
cd ../project
# 完成后清理
git worktree remove ../project-hotfix
在不影响当前工作的情况下审查 PR:
# 获取 PR 分支并创建工作树
git fetch origin pull/123/head:pr-123
git worktree add ../project-review pr-123
# 审查:运行测试,检查代码
cd ../project-review
# 返回工作,然后清理
cd ../project
git worktree remove ../project-review
git branch -d pr-123
并排比较不同分支的代码:
# 为不同版本创建工作树
git worktree add ../project-v1 v1.0.0
git worktree add ../project-v2 v2.0.0
# 差异比较,或同时运行两者
diff ../project-v1/src/module.js ../project-v2/src/module.js
# 清理
git worktree remove ../project-v1
git worktree remove ../project-v2
在继续开发的同时,在隔离环境中运行测试/构建:
# 为类似 CI 的测试创建工作树
git worktree add ../project-test main
# 在后台启动长时间运行的测试
cd ../project-test && npm test &
# 在主工作树中继续开发
cd ../project
维护一个干净的 main 分支检出以供参考:
# 为 main 分支创建永久工作树
git worktree add ../project-main main
# 锁定以防止意外移除
git worktree lock --reason "Reference checkout" ../project-main
合并来自多个功能分支的特定更改:
# 为每个要审查的功能创建工作树
git worktree add ../project-feature-1 feature-1
git worktree add ../project-feature-2 feature-2
# 在每个工作树中审查更改
diff ../project/src/module.js ../project-feature-1/src/module.js
diff ../project/src/module.js ../project-feature-2/src/module.js
# 从主工作树中,有选择地获取更改
cd ../project
git checkout feature-1 -- src/moduleA.js src/utils.js
git checkout feature-2 -- src/moduleB.js
git commit -m "feat: combine selected changes from feature branches"
# 或者拣选特定提交
git cherry-pick abc1234 # 来自 feature-1
git cherry-pick def5678 # 来自 feature-2
# 清理
git worktree remove ../project-feature-1
git worktree remove ../project-feature-2
由于所有工作树共享同一个 Git 仓库,你可以在它们之间比较文件、拣选提交并有选择地合并更改。
由于工作树只是目录,你可以直接比较文件:
# 比较工作树间的特定文件
diff ../project-main/src/app.js ../project-feature/src/app.js
# 使用 git diff 比较分支(在任何工作树中都有效)
git diff main..feature-branch -- src/app.js
# 使用你偏好的工具进行可视化差异比较
code --diff ../project-main/src/app.js ../project-feature/src/app.js
# 比较整个目录
diff -r ../project-v1/src ../project-v2/src
你可以使用 git checkout 有选择地从另一个分支获取单个文件:
# 在当前分支中,从另一个分支获取特定文件
git checkout feature-branch -- path/to/file.js
# 或者从特定提交获取
git checkout abc1234 -- path/to/file.js
# 获取多个特定文件
git checkout feature-branch -- src/module.js src/utils.js
对于部分文件更改(仅特定代码块/行):
# 交互式补丁模式 - 选择要获取的更改
git checkout -p feature-branch -- path/to/file.js
这会提示你单独接受/拒绝每个更改块,选项包括:
y - 应用此块n - 跳过此块s - 分割成更小的块e - 手动编辑此块拣选在提交级别工作。由于所有工作树共享同一个仓库,你可以拣选任何提交:
# 查找提交哈希(从任何工作树或 git log)
git log feature-branch --oneline
# 将特定提交拣选到当前分支
git cherry-pick abc1234
# 拣选多个提交
git cherry-pick abc1234 def5678
# 拣选一系列提交
git cherry-pick abc1234^..def5678
# 拣选但不提交(仅暂存更改)
git cherry-pick --no-commit abc1234
你可以合并或拣选来自多个分支的更改:
# 顺序合并多个分支
git merge feature-1
git merge feature-2
# 或者使用章鱼合并一次性合并多个分支
git merge feature-1 feature-2 feature-3
# 从多个分支拣选提交
git cherry-pick abc1234 # 来自 feature-1
git cherry-pick def5678 # 来自 feature-2
# 从不同分支获取特定文件
git checkout feature-1 -- src/moduleA.js
git checkout feature-2 -- src/moduleB.js
git commit -m "Merge selected files from feature branches"
# 从文件中选择特定代码块
git checkout -p feature-1 -- src/shared.js
# 应用更改但不提交
git cherry-pick --no-commit abc1234
# 取消暂存你不想要的内容
git reset HEAD -- unwanted-file.js
git checkout -- unwanted-file.js
# 仅提交你保留的内容
git commit -m "Selected changes from feature-1"
# 开始合并但不自动提交
git merge --no-commit feature-1
# 审查并修改暂存的更改
git status
git reset HEAD -- file-to-exclude.js
git checkout -- file-to-exclude.js
# 提交你的选择
git commit -m "Merge selected changes from feature-1"
# 从另一个分支恢复特定文件
git restore --source=feature-branch -- path/to/file.js
# 交互式恢复,带补丁选择
git restore -p --source=feature-branch -- path/to/file.js
以可预测的方式组织工作树:
~/projects/
myproject/ # 主工作树 (main/master 分支)
myproject-feature-x/ # 功能分支工作树
myproject-hotfix/ # 热修复工作树
myproject-review/ # 临时 PR 审查工作树
命名约定: <项目>-<用途> 或 <项目>-<分支>
| 实践 | 理由 |
|---|---|
| 使用同级目录 | 将工作树保持在主项目同一层级,便于导航 |
| 按用途命名 | project-review 比 project-pr-123 更清晰 |
| 及时清理 | 完成后移除工作树,避免混淆 |
| 锁定远程工作树 | 如果工作树位于网络/USB 存储上,防止被清理 |
使用 --detach 进行实验 | 避免创建临时分支 |
| 移除前提交 | 在 git worktree remove 前始终提交或暂存 |
原因: 尝试检出已在另一个工作树中处于活动状态的分支。
解决方案:
# 查找该分支在何处被检出
git worktree list
# 要么在该工作树中工作,要么先移除它
git worktree remove ../other-worktree
原因: 未使用 git worktree remove 就删除了工作树目录。
解决方案:
# 清理陈旧的元数据
git worktree prune
原因: 未使用 git worktree move 就移动了工作树目录。
解决方案:
# 修复工作树链接
git worktree repair
# 或者指定新路径
git worktree repair /new/path/to/worktree
原因: 工作树位于不再连接的可移动存储上。
解决方案:
# 如果是临时的,锁定它以防止被清理
git worktree lock ../usb-worktree
# 如果是永久的,清理它
git worktree prune
| 错误 | 修复方法 |
|---|---|
使用 rm -rf 删除工作树 | 始终使用 git worktree remove,如果需要再运行 git worktree prune |
| 忘记分支被锁定到工作树 | 在检出错误前运行 git worktree list |
| 未清理临时工作树 | 任务完成后立即移除工作树 |
| 在嵌套位置创建工作树 | 使用同级目录 (../project-feature),而非子目录 |
| 手动移动工作树目录 | 使用 git worktree move 或在之后运行 git worktree repair |
隔离并行代理任务:
# 为隔离任务创建工作树
git worktree add -b task-123 ../project-task-123
cd ../project-task-123
# 进行更改,运行测试,返回
cd ../project
安全地进行分离头指针实验:
# 创建分离头指针工作树(无需清理的分支)
git worktree add --detach ../project-experiment
cd ../project-experiment
# 实验,然后丢弃或提交到新分支
git worktree remove --force ../project-experiment
使用工作树前:
创建工作树时:
--detach移除工作树时:
git worktree remove,而非 rm -rfgit worktree prune每周安装数
218
仓库
GitHub 星标数
699
首次出现
2026年2月19日
安装于
opencode212
codex211
github-copilot211
gemini-cli209
kimi-cli208
amp207
Git worktrees enable checking out multiple branches simultaneously in separate directories, all sharing the same repository. Create a worktree instead of stashing changes or cloning separately.
Core principle: One worktree per active branch. Switch contexts by changing directories, not branches.
| Concept | Description |
|---|---|
| Main worktree | Original working directory from git clone or git init |
| Linked worktree | Additional directories created with git worktree add |
Shared.git | All worktrees share same Git object database (no duplication) |
| Branch lock | Each branch can only be checked out in ONE worktree at a time |
| Worktree metadata | Administrative files in .git/worktrees/ tracking linked worktrees |
| Task | Command |
|---|---|
| Create worktree (existing branch) | git worktree add <path> <branch> |
| Create worktree (new branch) | git worktree add -b <branch> <path> |
| Create worktree (new branch from ref) | git worktree add -b <branch> <path> <start> |
| Create detached worktree | git worktree add --detach <path> <commit> |
| List all worktrees | git worktree list |
| Remove worktree | git worktree remove <path> |
# Create worktree with existing branch
git worktree add ../feature-x feature-x
# Create worktree with new branch from current HEAD
git worktree add -b new-feature ../new-feature
# Create worktree with new branch from specific commit
git worktree add -b hotfix-123 ../hotfix origin/main
# Create worktree tracking remote branch
git worktree add --track -b feature ../feature origin/feature
# Create worktree with detached HEAD (for experiments)
git worktree add --detach ../experiment HEAD~5
# Simple list
git worktree list
# Verbose output with additional details
git worktree list -v
# Machine-readable format (for scripting)
git worktree list --porcelain
Example output:
/home/user/project abc1234 [main]
/home/user/project-feature def5678 [feature-x]
/home/user/project-hotfix ghi9012 [hotfix-123]
# Remove worktree (working directory must be clean)
git worktree remove ../feature-x
# Force remove (discards uncommitted changes)
git worktree remove --force ../feature-x
# Relocate worktree to new path
git worktree move ../old-path ../new-path
# Lock worktree (prevents pruning if on removable storage)
git worktree lock ../feature-x
git worktree lock --reason "On USB drive" ../feature-x
# Unlock worktree
git worktree unlock ../feature-x
# Remove stale worktree metadata (after manual directory deletion)
git worktree prune
# Dry-run to see what would be pruned
git worktree prune --dry-run
# Verbose output
git worktree prune -v
# Repair worktree links after moving directories manually
git worktree repair
# Repair specific worktree
git worktree repair ../feature-x
To fix a bug while feature work is in progress:
# Create worktree for hotfix from main
git worktree add -b hotfix-456 ../project-hotfix origin/main
# Switch to hotfix directory, fix, commit, push
cd ../project-hotfix
git add . && git commit -m "fix: resolve critical bug #456"
git push origin hotfix-456
# Return to feature work
cd ../project
# Clean up when done
git worktree remove ../project-hotfix
To review a PR without affecting current work:
# Fetch PR branch and create worktree
git fetch origin pull/123/head:pr-123
git worktree add ../project-review pr-123
# Review: run tests, inspect code
cd ../project-review
# Return to work, then clean up
cd ../project
git worktree remove ../project-review
git branch -d pr-123
To compare code across branches side-by-side:
# Create worktrees for different versions
git worktree add ../project-v1 v1.0.0
git worktree add ../project-v2 v2.0.0
# Diff, compare, or run both simultaneously
diff ../project-v1/src/module.js ../project-v2/src/module.js
# Clean up
git worktree remove ../project-v1
git worktree remove ../project-v2
To run tests/builds in isolation while continuing development:
# Create worktree for CI-like testing
git worktree add ../project-test main
# Start long-running tests in background
cd ../project-test && npm test &
# Continue development in main worktree
cd ../project
To maintain a clean main checkout for reference:
# Create permanent worktree for main branch
git worktree add ../project-main main
# Lock to prevent accidental removal
git worktree lock --reason "Reference checkout" ../project-main
To combine specific changes from multiple feature branches:
# Create worktrees for each feature to review
git worktree add ../project-feature-1 feature-1
git worktree add ../project-feature-2 feature-2
# Review changes in each worktree
diff ../project/src/module.js ../project-feature-1/src/module.js
diff ../project/src/module.js ../project-feature-2/src/module.js
# From main worktree, selectively take changes
cd ../project
git checkout feature-1 -- src/moduleA.js src/utils.js
git checkout feature-2 -- src/moduleB.js
git commit -m "feat: combine selected changes from feature branches"
# Or cherry-pick specific commits
git cherry-pick abc1234 # from feature-1
git cherry-pick def5678 # from feature-2
# Clean up
git worktree remove ../project-feature-1
git worktree remove ../project-feature-2
Since all worktrees share the same Git repository, you can compare files, cherry-pick commits, and selectively merge changes between them.
Since worktrees are just directories, you can compare files directly:
# Compare specific file between worktrees
diff ../project-main/src/app.js ../project-feature/src/app.js
# Use git diff to compare branches (works from any worktree)
git diff main..feature-branch -- src/app.js
# Visual diff with your preferred tool
code --diff ../project-main/src/app.js ../project-feature/src/app.js
# Compare entire directories
diff -r ../project-v1/src ../project-v2/src
You can selectively bring a single file from another branch using git checkout:
# In your current branch, get a specific file from another branch
git checkout feature-branch -- path/to/file.js
# Or get it from a specific commit
git checkout abc1234 -- path/to/file.js
# Get multiple specific files
git checkout feature-branch -- src/module.js src/utils.js
For partial file changes (specific hunks/lines only):
# Interactive patch mode - select which changes to take
git checkout -p feature-branch -- path/to/file.js
This prompts you to accept/reject each change hunk individually with options:
y - apply this hunkn - skip this hunks - split into smaller hunkse - manually edit the hunkCherry-picking works at the commit level. Since all worktrees share the same repository, you can cherry-pick any commit:
# Find the commit hash (from any worktree or git log)
git log feature-branch --oneline
# Cherry-pick specific commit into your current branch
git cherry-pick abc1234
# Cherry-pick multiple commits
git cherry-pick abc1234 def5678
# Cherry-pick a range of commits
git cherry-pick abc1234^..def5678
# Cherry-pick without committing (stage changes only)
git cherry-pick --no-commit abc1234
You can merge or cherry-pick from multiple branches:
# Merge multiple branches sequentially
git merge feature-1
git merge feature-2
# Or use octopus merge for multiple branches at once
git merge feature-1 feature-2 feature-3
# Cherry-pick commits from multiple branches
git cherry-pick abc1234 # from feature-1
git cherry-pick def5678 # from feature-2
# Get specific files from different branches
git checkout feature-1 -- src/moduleA.js
git checkout feature-2 -- src/moduleB.js
git commit -m "Merge selected files from feature branches"
# Select specific hunks from a file
git checkout -p feature-1 -- src/shared.js
# Apply changes without committing
git cherry-pick --no-commit abc1234
# Unstage what you don't want
git reset HEAD -- unwanted-file.js
git checkout -- unwanted-file.js
# Commit only what you kept
git commit -m "Selected changes from feature-1"
# Start merge but don't auto-commit
git merge --no-commit feature-1
# Review and modify staged changes
git status
git reset HEAD -- file-to-exclude.js
git checkout -- file-to-exclude.js
# Commit your selection
git commit -m "Merge selected changes from feature-1"
# Restore specific file from another branch
git restore --source=feature-branch -- path/to/file.js
# Interactive restore with patch selection
git restore -p --source=feature-branch -- path/to/file.js
Organize worktrees predictably:
~/projects/
myproject/ # Main worktree (main/master branch)
myproject-feature-x/ # Feature branch worktree
myproject-hotfix/ # Hotfix worktree
myproject-review/ # Temporary PR review worktree
Naming convention: <project>-<purpose> or <project>-<branch>
| Practice | Rationale |
|---|---|
| Use sibling directories | Keep worktrees at same level as main project for easy navigation |
| Name by purpose | project-review is clearer than project-pr-123 |
| Clean up promptly | Remove worktrees when done to avoid confusion |
| Lock remote worktrees | Prevent pruning if worktree is on network/USB storage |
Use--detach for experiments | Avoid creating throwaway branches |
| Commit before removing | Always commit or stash before git worktree remove |
Cause: Attempting to checkout a branch that's active in another worktree.
Solution:
# Find where the branch is checked out
git worktree list
# Either work in that worktree or remove it first
git worktree remove ../other-worktree
Cause: Deleted worktree directory without using git worktree remove.
Solution:
# Clean up stale metadata
git worktree prune
Cause: Moved worktree directory without using git worktree move.
Solution:
# Repair the worktree links
git worktree repair
# Or specify the new path
git worktree repair /new/path/to/worktree
Cause: Worktree was on removable storage that's no longer connected.
Solution:
# If temporary, lock it to prevent pruning
git worktree lock ../usb-worktree
# If permanent, prune it
git worktree prune
| Mistake | Fix |
|---|---|
Using rm -rf to delete worktree | Always use git worktree remove, then git worktree prune if needed |
| Forgetting branch is locked to worktree | Run git worktree list before checkout errors |
| Not cleaning up temporary worktrees | Remove worktrees immediately after task completion |
| Creating worktrees in nested locations | Use sibling directories (../project-feature) not subdirs |
| Moving worktree directory manually | Use git worktree move or run after |
To isolate parallel agent tasks:
# Create worktree for isolated task
git worktree add -b task-123 ../project-task-123
cd ../project-task-123
# Make changes, run tests, return
cd ../project
To experiment safely with detached HEAD:
# Create detached worktree (no branch to clean up)
git worktree add --detach ../project-experiment
cd ../project-experiment
# Experiment, then discard or commit to new branch
git worktree remove --force ../project-experiment
Before using worktrees:
When creating worktrees:
--detach for experimentsWhen removing worktrees:
git worktree remove, not rm -rfgit worktree prune if directory was deleted manuallyWeekly Installs
218
Repository
GitHub Stars
699
First Seen
Feb 19, 2026
Installed on
opencode212
codex211
github-copilot211
gemini-cli209
kimi-cli208
amp207
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
109,600 周安装
| Force remove worktree | git worktree remove --force <path> |
| Move worktree | git worktree move <old> <new> |
| Lock worktree | git worktree lock <path> |
| Unlock worktree | git worktree unlock <path> |
| Prune stale worktrees | git worktree prune |
| Repair worktree links | git worktree repair |
| Compare files between worktrees | diff ../worktree-a/file ../worktree-b/file |
| Get one file from another branch | git checkout <branch> -- <path> |
| Get partial file changes | git checkout -p <branch> -- <path> |
| Cherry-pick a commit | git cherry-pick <commit> |
| Cherry-pick without committing | git cherry-pick --no-commit <commit> |
| Merge without auto-commit | git merge --no-commit <branch> |
git worktree repair