Skip to content

rg216/Git-Worktree-Tutorial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Git Worktree 教程

这个仓库现在包含两部分:

  • 一份静态中文教程,也就是本文档后面的内容。
  • 一个使用 TypeScript 编写、用 Bun 运行的交互式浏览器教程。

运行交互式教程

先安装依赖:

bun install

启动本地服务:

bun run dev

然后打开:

http://localhost:3000

可用脚本:

bun run dev        # 启动教程服务
bun run dev:watch  # 文件变化时重启服务
bun run build      # 构建浏览器端 TypeScript
bun test           # 运行模拟器测试

交互式版本不会执行真实系统命令。用户输入的 gitcdecho 等命令会进入 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"

查看当前 worktree

在仓库目录中执行:

git worktree list

你会看到类似输出:

/path/to/git-worktree-demo  abc1234 [main]

这表示当前只有一个主工作区。

创建一个功能分支 worktree

假设你要开发登录功能:

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"

现在你已经在独立目录中完成了一次功能分支提交。

同时创建一个 hotfix worktree

假设你正在开发 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 中的分支

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

删除 worktree

删除 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

然后选择提交、恢复或删除这些改动。

不小心手动删除了 worktree 目录

执行:

git worktree prune

这会清理 Git 中残留的 worktree 元数据。

推荐目录命名方式

建议把多个 worktree 放在同一层级:

workspace/
  app/
  app.feature-login/
  app.hotfix-readme/
  app.release-1.2/

这种命名方式能让你一眼看出每个目录对应的任务。

实用工作流:不用 stash 处理紧急修复

假设你正在 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

原来的未提交改动还在原地。

进阶技巧

从远程分支创建 worktree

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 -5

git -C <path> 可以让你对指定目录执行 Git 命令。

查看每个 worktree 的分支

git worktree list --porcelain

这个输出更适合脚本处理。

练习任务

完成下面练习,基本就能掌握日常使用:

  1. 创建一个练习仓库,并提交初始 README.md
  2. 创建 feature/a worktree,添加 a.txt 并提交。
  3. 创建 feature/b worktree,添加 b.txt 并提交。
  4. 回到主 worktree,运行 git worktree list
  5. feature/a 合并到 main
  6. 删除 feature/a 对应的 worktree。
  7. 尝试再次创建一个指向已检出分支的 worktree,观察错误信息。
  8. 使用不同分支名重新创建成功。

什么时候不需要 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

这样你可以在不打断当前工作的情况下,马上开始另一个分支的任务。

About

An interactive tutorial for git worktree created with codex.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors