这个仓库现在包含两部分:
- 一份静态中文教程,也就是本文档后面的内容。
- 一个使用 TypeScript 编写、用 Bun 运行的交互式浏览器教程。
先安装依赖:
bun install启动本地服务:
bun run dev然后打开:
http://localhost:3000
可用脚本:
bun run dev # 启动教程服务
bun run dev:watch # 文件变化时重启服务
bun run build # 构建浏览器端 TypeScript
bun test # 运行模拟器测试交互式版本不会执行真实系统命令。用户输入的 git、cd、echo 等命令会进入 TypeScript 模拟器,由模拟器维护分支、提交、worktree、暂存区和文件状态。
src/
client/ # 浏览器 UI
git-sim/ # Git worktree 状态机和命令解释器
lessons/ # 教程步骤和校验器
server.ts # Bun HTTP 服务和客户端构建入口
public/
index.html
styles.css
test/
simulator.test.ts
git worktree 允许你为同一个 Git 仓库创建多个工作目录。每个工作目录可以检出不同的分支,因此你可以同时处理多个任务,而不必频繁 stash、切分支、恢复现场。
git worktree解决什么问题- 如何创建、查看、删除 worktree
- 如何同时开发功能分支和热修复分支
- 常见错误与处理方式
- 日常使用建议
git worktree 特别适合这些情况:
- 当前分支有未完成改动,但你需要马上切去另一个分支处理问题
- 你想同时打开两个分支做对比
- 你要在一个分支跑测试,同时在另一个分支继续开发
- 你经常需要处理多个 PR、hotfix、release 分支
传统做法通常是:
git stash
git switch other-branch使用 worktree 后,你可以这样:
git worktree add ../project-hotfix -b hotfix/login main然后在 ../project-hotfix 里处理热修复,原来的目录保持不动。
一个普通仓库可以有一个主工作区和多个附加工作区:
project/
.git/
src/
project-feature-login/
src/
project-hotfix/
src/
这些目录共享同一个 Git 仓库数据,但每个目录有自己的:
- 当前分支
- 工作区文件
- 暂存区
- 未提交改动
重要限制:
- 同一个本地分支默认不能同时被两个 worktree 检出。
- 不要手动修改
.git/worktrees/。 - 删除 worktree 时优先使用
git worktree remove。
如果你只是想学习,可以创建一个临时练习仓库:
mkdir git-worktree-demo
cd git-worktree-demo
git init
git switch -c main
echo "# Git Worktree Demo" > README.md
git add README.md
git commit -m "Initial commit"如果 Git 提示没有配置用户名或邮箱,可以先执行:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"在仓库目录中执行:
git worktree list你会看到类似输出:
/path/to/git-worktree-demo abc1234 [main]
这表示当前只有一个主工作区。
假设你要开发登录功能:
git worktree add ../git-worktree-demo-login -b feature/login含义:
../git-worktree-demo-login是新工作目录路径-b feature/login表示创建并检出新分支- 新分支默认从当前提交开始
进入新目录:
cd ../git-worktree-demo-login
git status添加一点改动:
echo "Login feature" > login.txt
git add login.txt
git commit -m "Add login feature note"现在你已经在独立目录中完成了一次功能分支提交。
假设你正在开发 feature/login,但突然需要基于 main 修复文档。
回到主仓库目录:
cd ../git-worktree-demo创建 hotfix worktree:
git worktree add ../git-worktree-demo-hotfix -b hotfix/readme main进入 hotfix 目录:
cd ../git-worktree-demo-hotfix
echo "Hotfix note" >> README.md
git add README.md
git commit -m "Fix README note"此时你有三个工作目录:
git worktree list可能输出:
/path/to/git-worktree-demo abc1234 [main]
/path/to/git-worktree-demo-login def5678 [feature/login]
/path/to/git-worktree-demo-hotfix 987abcd [hotfix/readme]
worktree 本身只是工作目录。真正需要合并的是分支。
例如把 hotfix 合并回 main:
cd ../git-worktree-demo
git switch main
git merge hotfix/readme如果确认不再需要 hotfix 分支:
git branch -d hotfix/readme如果分支还没有被合并,-d 会拒绝删除。确认要强删时才使用:
git branch -D hotfix/readme删除 hotfix 工作目录:
git worktree remove ../git-worktree-demo-hotfix如果那个目录里还有未提交改动,Git 会拒绝删除。你可以先提交、丢弃或手动处理这些改动。
如果你已经手动删除了 worktree 目录,可以清理 Git 记录:
git worktree prune| 命令 | 用途 |
|---|---|
git worktree list |
查看所有 worktree |
git worktree add <path> <branch> |
基于已有分支创建 worktree |
git worktree add <path> -b <new-branch> |
创建新分支并创建 worktree |
git worktree add <path> -b <new-branch> <start-point> |
从指定起点创建新分支和 worktree |
git worktree remove <path> |
删除 worktree |
git worktree prune |
清理已不存在的 worktree 记录 |
git worktree lock <path> |
锁定 worktree,防止被 prune 清理 |
git worktree unlock <path> |
解除锁定 |
你可能会看到:
fatal: '<branch>' is already checked out at '<path>'
原因是同一个本地分支默认不能同时在两个 worktree 中检出。
解决方式:
git worktree add ../another-worktree -b another-branch main也就是为新 worktree 使用不同分支。
你可能会看到:
fatal: '<path>' contains modified or untracked files
先进入对应 worktree 检查:
cd <path>
git status然后选择提交、恢复或删除这些改动。
执行:
git worktree prune这会清理 Git 中残留的 worktree 元数据。
建议把多个 worktree 放在同一层级:
workspace/
app/
app.feature-login/
app.hotfix-readme/
app.release-1.2/
这种命名方式能让你一眼看出每个目录对应的任务。
假设你正在 feature/payment 上开发,并且工作区有未提交改动:
cd app
git status这时线上出现 bug,需要基于 main 修复。
不要切分支,也不需要 stash。直接创建一个新的 worktree:
git worktree add ../app.hotfix-checkout -b hotfix/checkout main
cd ../app.hotfix-checkout修复、提交:
git add .
git commit -m "Fix checkout bug"回到主工作区继续原来的开发:
cd ../app原来的未提交改动还在原地。
git fetch origin
git worktree add ../app.review-123 -b review/pr-123 origin/feature/some-branch这适合本地查看别人的 PR。
git -C ../app.hotfix-checkout status
git -C ../app.hotfix-checkout log --oneline -5git -C <path> 可以让你对指定目录执行 Git 命令。
git worktree list --porcelain这个输出更适合脚本处理。
完成下面练习,基本就能掌握日常使用:
- 创建一个练习仓库,并提交初始
README.md。 - 创建
feature/aworktree,添加a.txt并提交。 - 创建
feature/bworktree,添加b.txt并提交。 - 回到主 worktree,运行
git worktree list。 - 把
feature/a合并到main。 - 删除
feature/a对应的 worktree。 - 尝试再次创建一个指向已检出分支的 worktree,观察错误信息。
- 使用不同分支名重新创建成功。
如果你只是偶尔切一次分支,并且当前工作区很干净,普通的 git switch 就够了。
git worktree 的价值主要在于:
- 多任务并行
- 保留现场
- 减少 stash
- 降低频繁切分支带来的干扰
记住这几个命令就可以开始使用:
git worktree list
git worktree add ../app.some-task -b some/task main
git worktree remove ../app.some-task
git worktree prune最常见的日常模式是:
git worktree add ../project.hotfix -b hotfix/something main这样你可以在不打断当前工作的情况下,马上开始另一个分支的任务。