作为程序员,基本上每天都在用Git,但这两天发现一个扎心的现实,Git有一个2015年发布的功能至今已经有 10年多 了,随着AI编程的爆火才重新崭露头角,可以说真的是由AI编程带火的Git功能,我也是这两天使用Claude Code Worktree才开始了解和真正使用🤣的,不过我发现Claude Code Worktree目前使用上还有一些限制需要Git原生Worktree配合,今天重新认识一下Git Worktree。
优势
- 真正的并行开发
- 消除环境切换成本
限制
- 单一分支锁定,同一个分支不能同时被多个 Worktree 签出
- 额外磁盘空间占用
- 增加管理成本
Git Worktree简介
Git Worktree 是一项发布于 2015 年的高效功能,它允许开发者在同一个仓库中同时开启多个独立的物理目录(工作区),从而彻底告终了在不同分支间切换时频繁 stash 或提交未完成代码的烦恼。
特别是在Claude Code等 AI 工具的驱动下,它让 AI 代理能够在隔离的“分身环境”中自主运行长时任务或修复 Bug,而开发者则可以在主目录中同步进行其他核心工作,实现了真正的多线程并行开发模式。
为什么之前没有关注过?
在过去的软件开发模式里,我们的工作方式都是 单一项目、单一分支 和 单一任务,工作模式也是串行的:代码编写 → 提交 → 合并,整个过程完全不会涉及Git Worktree场景。随着AI编程时代的到来涌现出大量并行任务的需求场景,我们可以同时让AI写代码、重构、测试,Git Worktree的重要性也随之提现。
为什么不会冲突?
当我们在尝试从一个分支签出多个Worktree时会报错
$ git worktree add -b feat/login .workt/feat-login
$ git worktree add -b feat/login .workt/feat-login2
报错的原因是因为Git Worktree限制:一个分支只能被一个worktree checkout,每个分支只有一个Worktree自然不会出现冲突问题
Git Worktree的工作流程
Git Worktree目录结构
在Git Worktree中可以简单的将项目文件目录分为2大类:.git 和 其他文件
当我们创建Git Worktree时,会在 .git下的 worktrees 目录添加新Worktree的“链接工作区”记录
Worktree会拷贝工作区目录并且只会拷贝签出 .git 和 未被.gitignore忽略的文件
- .git:不是工作区 .git 的拷贝而是 .git 的索引,因为有该索引文件所以在Worktree中才可以正常执行git命令,也正是因为没有拷贝 .git所以Worktree的创建过程很快
- 未被.gitignore忽略的文件:工作区中未被 .gitignore 记录的工作区文件
有一点需要注意的是,这里的 **.git**并不是工作区的 .git,只是工作区的 **.git的索引,**打开 **.worktrees/feat-login**中的 .git 可以看到文件中只有一行命令
gitdir: /Users/username/../jimeng-free-api-all/.git/worktrees/feat-login
基本使用
Worktree命令
在命令行终端输入以下命令查看Git Worktree命令行帮助文档
$ git worktree --help
Git Worktree命令列表:
- add:创建新的Worktree,示例:git worktree add[-b ] []
- list:查看Worktree列表,示例:git worktree list [-v | --porcelain [-z]]
- lock:锁定保护Worktree,防止工作树的管理文件被自动清理(prune),示例:git worktree lock [--reason]
- unlock:解锁Worktree,解除锁定状态,允许该工作树被清理、移动或删除,示例:git worktree unlock
- move:移动Worktree,将工作树移动到新的磁盘路径,示例:git worktree move
- prune:清理失效的Worktree,清理残留的、已经不存在于磁盘上的工作树管理信息,示例:git worktree prune [-n] [-v] [--expire]
- remove:删除Worktree,示例:git worktree remove [-f]
- repair:修复Worktree,当手动移动了主工作树或链接工作树(没用move命令)导致路径脱节时,用于重新建立它们之间的引用关系,示例:git worktree repair [...]
创建Worktree
以 github.com/zhizinan199… 项目为例,首先将项目克隆到本地
$ git clone https://github.com/zhizinan1997/jimeng-free-api-all.git
项目结构如下,默认需包含 .git 目录(有.git目录才能调用git命令)
Git Worktree标准命令格式如下:
$ git worktree add -b <本地新分支名> <路径> <本地|远程分支名>
使用下面命令创建worktree,该命令默认会基于当前分支创建 feat/login 分支并创建一个名为 feat-login 的worktree存放到 .worktrees/feat-login
# 默认使用当前分支
$ git worktree add -b feat/login .worktrees/feat-login
# 指定分支,HEAD指针指向当前分支
$ git worktree add -b feat/login .worktrees/feat-login HEAD
# 指定本地其他分支
$ git worktree add -b feat/login .worktrees/feat-login develop
命令参数释义:
- add:创建新的Worktree
- -b feat/login:创建一个新的Git分支,分支名为 feat/login
- .worktrees/feat-login:新创建的Worktree的存放路径
- HEAD:基于当前分支创建,可以省略,省略时默认基于当前 HEAD 创建
当然也是可以指定为远程分支的,直接填写分支为远程分支名称即可
$ git worktree add -b feat/login .worktrees/feat-login origin/main
Git Worktree的创建过程是非常快的,命令行终端提示如下表示Worktree创建成功
查看Worktree
Git Worktree提供了查看Worktree的命令,在命令行终端使用 git worktree list 查看所有Worktree信息
也可以使用VS Code等集成Git的编辑器可视化查看
使用Worktree
使用Git Worktree时直接进入Worktree目录启动CLI终端即可
cd .worktrees/feat-login
此时Worktree上发生变更就是feat-login分支上的变更
变更内容commit后,就可以使用 merge 将变更合并到主分支
$ git merge feat/login
删除Worktree
Git Worktree提供了删除Worktree的功能,命令格式如下:
$ git worktree remove <Worktree路径>
以 feat-login 为例,删除Worktree的完整指令如下:
# 删除指定
$ git worktree remove .worktrees/feat-login
如果Worktree目录被手动删掉了或者发现Worktree 状态不对,我们可以使用下面命令清理无效引用
# 默认清理
$ git worktree prune
# 强制清理
$ git worktree prune -f
友情提示
见原文:重新认识10年未被重视的Git原生功能:Git Worktree
本文同步自微信公众号 "程序员小溪" ,这里只是同步,想看及时消息请移步我的公众号,不定时更新我的学习经验。友情提示友情提示