[TOC] #### 1. 工作树介绍 --- Git 的工作树这个功能其实很早就有了,但最近因为 AI 内容爆发才火起来,阅读本文需要已经掌握 Git 基础。 `git worktree` 是 Git 提供的一个强大功能,允许你在同一个 Git 仓库中同时检出多个分支,而无需克隆多个仓库副本 每个工作树都有独立的工作目录、暂存区和 HEAD,但共享同一个 `.git` 仓库对象数据库,从而节省磁盘空间并提升效率 核心概念: + 主工作树:正常 `clone` 或 `init` 的原始目录 + 链接工作树:通过 `git worktree add` 创建的额外工作目录,指向同一仓库的不同分支 #### 2. 创建工作树 --- 为已有分支创建工作树:在指定路径创建一个新目录,并检出已有分支 ```plaintext git worktree add <path> <branch> ``` 使用示例 ```bash # 从远程仓库检出 dev 分支到本地,然后建立工作树 git worktree add ../dev dev # 特别注意,如果已经检出分支,需要先删除本地分支,再使用该分支构建工作树 git branch -d dev ``` 创建新的分支并同时建立工作树(使用新分支构建工作树) ```plaintext git worktree add -b <new-branch> <path> <base-branch> ``` 使用示例:创建新的分支 `feature-b`,并在`../feature-b` 目录建立工作树 ```bash git worktree add -b feature-b ../feature-b ``` #### 3. 查看工作树 --- 查看当前仓库中所有工作树(可用于验证工作树是否创建成功) ```bash git worktree list ``` 使用示例(会列出当前仓库所有工作树及其路径、分支和提交信息) ```plaintext $ git worktree list /Users/liang/code/demo/git_demo/shop ad31fb7 [master] /Users/liang/code/demo/git_demo/dev b4946c3 [dev] ``` #### 4. 删除工作树 --- 安全删除:确保目标目录没有未提交的更改后执行,会自动删除对应的物理目录 ```plaintext git worktree remove <path> ``` 使用示例 ```bash # 创建新分支,并且创建工作树 git worktree add -b feature-d ../feature-d # 此时并没有在 ../feature-d 目录做任何修改 # 安全删除 git worktree remove ../feature-d ``` 强制删除:即使有未提交的更改也会强制删除(使用 `-f,--force` 参数表示强制删除) ```plaintext git worktree remove <path> -f ``` 使用示例 ```bash # 创建新分支,并且创建工作树 git worktree add -b feature-e ../feature-e # 修改工作树目录内容后,再使用安全删除会报错 git worktree remove ../feature-e # fatal: '../feature-e' contains modified or untracked files, use --force to delete it # 强制删除(使用 -f 参数) git worktree remove ../feature-e -f ``` 特别注意:删除工作树只会删除工作树目录,建立工作树时使用的分支不会被删除 ```bash # 删除工作树后,查看本地分支,可验证这一说法 git branch # 删除本地分支 git branch -d <branch> ``` #### 5. 裸仓库工作树 --- 这种用法非常高级且使用,这是 Git 中一种被称为 **“基于裸仓库(Bare Repository)的 Worktree 工作流”** 的最佳实践 拉取仓库的常规方式:使用 `clone` 拉取代码仓库,下载下来的内容分为两部分(`.git` 目录、默认工作树) 当克隆裸仓库时,Git 不会生成默认工作树,只会下载 `.git` 目录,这样就得到了一个纯仓库,没有任何工作树干扰 ```bash # 创建并进入项目目录 mkdir project && cd project # 使用 --bare 参数表示拉取裸仓库,并设置目录名为 .git git clone git@github.com:u1s1it/test1.git --bare .git ``` 此时项目目录文件结构如下所示(只有一个 `.git` 目录,没有工作树): ```plaintext project └── .git ├── config ├── description ├── HEAD ├── hooks │ ├── ... │ └── update.sample .... ``` 建立工作树 ```bash # 从现有分支建立工作树 git worktree add ./master git worktree add ./develop # 从新的分支建立工作树 git worktree add -b hotfix ./hotfix ``` ```plaintext project ├── .git ├── develop ├── hotfix └── master ``` #### 6. 典型使用场景 --- 使用场景: + 紧急 Bug 修复:正在 `main` 分支开发新功能时,突然需要修复生产环境的紧急 Bug。无需暂存当前代码,直接创建一个 `hotfix` 工作树进行修复,完成后切回原目录继续开发 + 并行功能开发:同时开发多个不相关的功能,每个功能拥有独立的工作目录,可以同时运行不同的开发服务器,互不干扰 + 代码审查:在不影响当前工作的情况下,为同事的 PR 分支创建一个独立的工作树来查看代码和运行测试 + 文档站点维护:主分支写代码,`docs` 分支生成文档,使用 `worktree` 可以同时维护代码和文档 注意事项: + 分支唯一性:不能在同一个分支上创建多个工作树(Git 会报错) + 工作树保护:不能删除当前正在使用的工作树 + 配置共享:所有工作树共享 `.git/config` 配置。如果某个工作树修改配置,会写入共享配置,建议谨慎操作