重新认识10年未被重视的Git原生功能:Git Worktree

0 阅读4分钟

作为程序员,基本上每天都在用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

Image

报错的原因是因为Git Worktree限制:一个分支只能被一个worktree checkout,每个分支只有一个Worktree自然不会出现冲突问题

Git Worktree的工作流程

Image

Git Worktree目录结构

在Git Worktree中可以简单的将项目文件目录分为2大类:.git 和 其他文件

Image

当我们创建Git Worktree时,会在 .git下的 worktrees 目录添加新Worktree的“链接工作区”记录

Image

Worktree会拷贝工作区目录并且只会拷贝签出 .git 和 未被.gitignore忽略的文件

  • .git:不是工作区 .git 的拷贝而是 .git 的索引,因为有该索引文件所以在Worktree中才可以正常执行git命令,也正是因为没有拷贝 .git所以Worktree的创建过程很快
  • 未被.gitignore忽略的文件:工作区中未被 .gitignore 记录的工作区文件

Image

有一点需要注意的是,这里的 **.git**并不是工作区的 .git,只是工作区的 **.git的索引,**打开 **.worktrees/feat-login**中的 .git 可以看到文件中只有一行命令

gitdir: /Users/username/../jimeng-free-api-all/.git/worktrees/feat-login

基本使用

Worktree命令

在命令行终端输入以下命令查看Git Worktree命令行帮助文档

$ git worktree --help

Image

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命令)

Image

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创建成功

Image

查看Worktree

Git Worktree提供了查看Worktree的命令,在命令行终端使用 git worktree list 查看所有Worktree信息

Image

也可以使用VS Code等集成Git的编辑器可视化查看

Image

使用Worktree

使用Git Worktree时直接进入Worktree目录启动CLI终端即可

cd .worktrees/feat-login

Image

此时Worktree上发生变更就是feat-login分支上的变更

Image

变更内容commit后,就可以使用 merge 将变更合并到主分支

$ git merge feat/login

Image

删除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

本文同步自微信公众号 "程序员小溪" ,这里只是同步,想看及时消息请移步我的公众号,不定时更新我的学习经验。友情提示友情提示