Git Worktree 使用
新入职了一家公司,发现不同项目用的使用一个 git 仓库管理。不久之后我看到这篇文章。
Git 的设计部分是为了支持实验。一旦你确定你的工作被安全地跟踪,并且存在安全的状态,以便在出现严重错误时可以恢复,你就不会害怕尝试新的想法。然而,创新的代价之一就是你可能会在过程中弄得一团糟。文件会被重命名、移动、删除、更改,甚至被分割成多个文件。新的文件会被引入。你不想跟踪的临时文件会在你的工作目录中驻留。
简而言之,你的工作区变成了一座纸牌屋,在“快要正常工作了!”和“哦不,我做了什么?”之间艰难地平衡着。那么,当你需要让仓库在某个下午恢复到已知状态以便完成一些实际工作时,该怎么办呢?经典命令 git branch 和git stash 会立即浮现在你的脑海中,但它们的设计初衷并非以某种方式处理未跟踪文件、更改的文件路径以及其他重大变更,而存储工作以供日后使用会让人感到困惑。答案是 Git worktree。
什么是 Git 工作树
Git 工作树是 Git 仓库的链接副本,允许您一次检出多个分支。工作树与主工作副本有独立的路径,但可以处于不同的状态并位于不同的分支。Git 中新工作树的优势在于,您可以进行与当前任务无关的更改,提交更改,然后在稍后合并,所有这些都不会干扰您当前的工作环境。
一个典型的例子,直接来自git-worktree
手册页:你正在为一个项目开发一个令人兴奋的新功能,这时项目经理告诉你,需要紧急修复一个问题。问题在于,由于你正在开发一个重要的新功能,你的工作仓库(你的“工作树”)一片混乱。你不想把修复工作“偷偷”拖进当前的冲刺阶段,也不想为了修复这个功能而存储更改,创建一个新的分支。于是,你决定创建一个新的工作树,以便在那里进行修复:
$ git branch | tee
* dev
trunk
$ git worktree add -b hotfix ~/code/hotfix trunk
Preparing ../hotfix (identifier hotfix)
HEAD is now at 62a2daf commit
在你的目录中code
,现在有一个名为 的新目录hotfix
,它是一个链接到你主项目仓库的 Git 工作树,它HEAD
位于名为 的分支trunk
。现在你可以将此工作树视为你的主工作区。你可以将目录切换到该目录,进行紧急修复,提交修复,并最终删除该工作树:
$ cd ~/code/hotfix
$ sed -i 's/teh/the/' hello.txt
$ git commit --all --message 'urgent hot fix'
完成紧急工作后,您可以返回上一个任务。您可以控制何时将修补程序集成到主项目中。例如,您可以将更改直接从其工作树推送到项目的远程仓库:
$ git push origin HEAD
$ cd ~/code/myproject
或者您可以将工作树存档为 TAR 或 ZIP 文件:
$ cd ~/code/myproject
$ git archive --format tar --output hotfix.tar master
或者您可以从单独的工作树本地获取更改:
$ git worktree list
/home/seth/code/myproject 15fca84 [dev]
/home/seth/code/hotfix 09e585d [master]
从那里,您可以使用最适合您和您的团队的策略合并您的更改。
列出活动工作树
您可以使用以下命令获取工作树列表并查看每个工作树已检出的分支git worktree list
:
$ git worktree list
/home/seth/code/myproject 15fca84 [dev]
/home/seth/code/hotfix 09e585d [master]
您可以在任一工作树中使用它。工作树始终保持链接(除非您手动移动它们,否则 Git 将无法定位工作树,从而切断链接)。
移动工作树
Git 跟踪项目.git
目录中工作树的位置和状态:
$ cat ~/code/myproject/.git/worktrees/hotfix/gitdir
/home/seth/code/hotfix/.git
如果需要重新定位工作树,则必须使用git worktree move
;否则,当 Git 尝试更新工作树的状态时,将会失败:
$ mkdir ~/Temp
$ git worktree move hotfix ~/Temp
$ git worktree list
/home/seth/code/myproject 15fca84 [dev]
/home/seth/Temp/hotfix 09e585d [master]
删除工作树
完成工作后,可以使用remove
子命令将其删除:
$ git worktree remove hotfix
$ git worktree list
/home/seth/code/myproject 15fca84 [dev]
为了确保.git
目录干净,请prune
在删除工作树后使用子命令:
$ git worktree prune
何时使用工作树
与许多选项一样,无论是标签页、书签还是自动备份,您都需要自行跟踪生成的数据,否则可能会不堪重负。不要过于频繁地使用工作树,以免最终导致您的代码库副本多达 20 个,每个副本的状态都略有不同。我发现最好的方法是创建一个工作树,执行需要它的任务,提交工作,然后删除该工作树。保持简洁和专注。
重要的是,工作树为 Git 仓库的管理提供了更高的灵活性。在需要的时候使用它们,再也不用为了检查其他分支上的内容而费力地保存工作状态了。