git worktree 略记
posts/notes/ 下的第二篇。和上一篇共享两个标签(linux、笔记),用来验证标签重复时列表、搜索、上一篇/下一篇都不会串。
它解决什么问题
一个仓库同一时间只能 checkout 一个分支。想一边看 master、一边改特性分支,传统办法是 clone 第二份,代价是两份对象库、两份远端配置、两份忘了同步的缓存。
git worktree 让同一个 .git 下挂多个工作目录,每个目录一个分支。
基本用法
# 在仓库里加一个工作目录,检出已有分支
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,第二个得自己改参数。
go run . -addr :2223 -http :8081
这篇想测什么
- 子目录里的文章能正常出现在列表页,路径带着
notes/ - 两篇共享标签时,
#linux在两篇上都显示,搜索也不会重复计数 - 上一篇/下一篇跨目录也接得上:从这篇往下翻应该翻到
01_ssh_端口转发.md tree posts/能看到两层结构,cd notes之后ls只有这两篇