--- title: git worktree 略记 date: 2026-10-12 tags: git, linux, 笔记 summary: 一个仓库开多个工作目录,顺手把上一篇和这一篇当成"同目录多文章"的测试样本 --- # git worktree 略记 `posts/notes/` 下的第二篇。和上一篇共享两个标签(`linux`、`笔记`),用来验证标签重复时列表、搜索、上一篇/下一篇都不会串。 ## 它解决什么问题 一个仓库同一时间只能 checkout 一个分支。想一边看 master、一边改特性分支,传统办法是 clone 第二份,代价是两份对象库、两份远端配置、两份忘了同步的缓存。 `git worktree` 让同一个 `.git` 下挂多个工作目录,每个目录一个分支。 ## 基本用法 ```console # 在仓库里加一个工作目录,检出已有分支 git worktree add ../ssh-blog-hotfix hotfix/login # 顺手新建分支并检出 git worktree add -b feat/add-404-page ../ssh-blog-404 master # 看有哪些 git worktree list # 用完了 git worktree remove ../ssh-blog-404 ``` ## 和"复制一份"的区别 | | 复制目录 | worktree | |---|---|---| | 对象库 | 各一份 | 共用一份 | | 分支占用 | 两边可以检出同一分支,容易互相踩 | 同一个分支同时只能在一个 worktree 里 | | 体积 | 随仓库增长 | 只有工作文件 | | 删除 | 手动 `rm -rf` | `git worktree remove`,顺带清理元数据 | 第二行是最有价值的一条:分支被"占用"这件事,恰好防止了你在两个目录里同时改同一个分支。 ## 几个坑 - **别忘了它存在**。`git worktree list` 里躺着一堆临时目录,删了目录却没 `remove`,`git worktree prune` 才能清干净。 - **子模块**。每个 worktree 都要单独 `git submodule update --init`,不会共享初始化状态。 - **IDE 缓存**。两个目录会各自建立索引,项目大的时候机器会热。 - **部署脚本**。`deploy.sh` 用 `git ls-files` 出清单,在哪个 worktree 里跑就按哪个分支的文件发,这倒是符合直觉。 ## 本项目里怎么用 给这个博客加功能时,一个舒服的用法是:主目录留在 master 上跑着 `go run .` 看效果,另一个 worktree 检出特性分支随便改、随便删,改完再合回来。 不过要注意端口:两个 worktree 同时 `go run .` 会抢 `:2222` 和 `:8080`,第二个得自己改参数。 ```console go run . -addr :2223 -http :8081 ``` ## 这篇想测什么 - 子目录里的文章能正常出现在列表页,路径带着 `notes/` - 两篇共享标签时,`#linux` 在两篇上都显示,搜索也不会重复计数 - 上一篇/下一篇跨目录也接得上:从这篇往下翻应该翻到 `01_ssh_端口转发.md` - `tree posts/` 能看到两层结构,`cd notes` 之后 `ls` 只有这两篇