Git 的设计部分是为了实现实验。一旦您知道您的工作被安全地跟踪,并且存在安全状态供您在出现严重错误时回退,您就不会害怕尝试新想法。然而,创新的一部分代价是您可能会在这个过程中搞得一团糟。文件被重命名、移动、删除、更改和切割成碎片。引入了新文件。您不打算跟踪的临时文件占据了您的工作目录。
简而言之,您的工作区变成了一个纸牌屋,在“它几乎可以工作了!”和“哦不,我做了什么?”之间岌岌可危地平衡着。那么,当您需要让您的存储库在下午恢复到已知状态,以便您可以完成一些真正的工作时,会发生什么呢?经典的命令 git branch 和 git stash 立即浮现在脑海中,但两者都不是为了处理未跟踪的文件而设计的,而更改的文件路径和其他重大变化可能会使您很难仅仅将您的工作隐藏起来以供以后使用。答案是 Git worktree。
什么是 Git worktree
Git worktree 是 Git 存储库的链接副本,允许您同时检出多个分支。worktree 与您的主工作副本具有不同的路径,但它可以处于不同的状态并在不同的分支上。Git 中新 worktree 的优势在于,您可以进行与当前任务无关的更改,提交更改,然后在稍后合并它,而不会干扰您当前的工作环境。
来自 git-worktree
手册页的规范示例是,当您的项目经理告诉您需要紧急修复时,您正在为一个项目开发一个令人兴奋的新功能。问题是您的工作存储库(您的“worktree”)处于混乱状态,因为您正在开发一个主要的新功能。您不想将修复“偷偷地”添加到当前的 sprint 中,并且您不希望隐藏更改以创建用于修复的新分支。相反,您决定创建一个新的 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 worktree,其 HEAD
停留在名为 trunk
的分支上。您现在可以将此 worktree 视为您的主工作区。您可以更改目录进入其中,进行紧急修复,提交它,并最终删除 worktree
$ cd ~/code/hotfix
$ sed -i 's/teh/the/' hello.txt
$ git commit --all --message 'urgent hot fix'
完成紧急工作后,您可以返回到之前的任务。您可以控制何时将您的 hotfix 集成到主项目中。例如,您可以直接从其 worktree 将更改推送到项目的远程仓库
$ git push origin HEAD
$ cd ~/code/myproject
或者您可以将 worktree 存档为 TAR 或 ZIP 文件
$ cd ~/code/myproject
$ git archive --format tar --output hotfix.tar master
或者您可以从单独的 worktree 本地获取更改
$ git worktree list
/home/seth/code/myproject 15fca84 [dev]
/home/seth/code/hotfix 09e585d [master]
从那里,您可以使用最适合您和您的团队的任何策略合并您的更改。
列出活动的 worktree
您可以使用 git worktree list
命令获取 worktree 列表,并查看每个 worktree 检出了哪个分支
$ git worktree list
/home/seth/code/myproject 15fca84 [dev]
/home/seth/code/hotfix 09e585d [master]
您可以从任何一个 worktree 中使用此命令。Worktree 始终是链接的(除非您手动移动它们,从而破坏 Git 定位 worktree 的能力,并因此切断链接)。
移动 worktree
Git 在您项目的 .git
目录中跟踪 worktree 的位置和状态
$ cat ~/code/myproject/.git/worktrees/hotfix/gitdir
/home/seth/code/hotfix/.git
如果您需要重新定位 worktree,则必须使用 git worktree move
来执行此操作;否则,当 Git 尝试更新 worktree 的状态时,它将失败
$ mkdir ~/Temp
$ git worktree move hotfix ~/Temp
$ git worktree list
/home/seth/code/myproject 15fca84 [dev]
/home/seth/Temp/hotfix 09e585d [master]
删除 worktree
完成工作后,您可以使用 remove
子命令将其删除
$ git worktree remove hotfix
$ git worktree list
/home/seth/code/myproject 15fca84 [dev]
为确保您的 .git
目录是干净的,请在删除 worktree 后使用 prune
子命令
$ git worktree prune
何时使用 worktree
与许多选项一样,无论是标签页还是书签还是自动备份,都取决于您来跟踪您生成的数据,否则可能会变得不堪重负。不要过于频繁地使用 worktree,以至于最终得到 20 个存储库副本,每个副本都处于略微不同的状态。我发现最好的方法是创建一个 worktree,完成需要它的任务,提交工作,然后删除树。保持简单和专注。
重要的是,worktree 为您管理 Git 存储库的方式提供了更高的灵活性。在您需要它们时使用它们,并且永远不要再为了检查另一个分支上的内容而争先恐后地保存您的工作状态。
评论已关闭。