不用再反复 stash:用 Git Worktree 同时开发多个分支
很多开发者都遇到过这样的场景你正在一个功能分支上写代码修改了十几个文件程序暂时还跑不起来也不适合提交。就在这时同事突然告诉你线上出现了一个紧急问题需要马上从main分支拉出一个 Hotfix。按照传统做法你可能会先执行gitstashgitswitch maingitpullgitswitch-chotfix/xxx修复完成以后再回到原来的分支gitswitch feature/xxxgitstash pop如果只是偶尔操作一次这种方式倒也能用。但当你同时维护多个 PR、审查别人代码、修复线上问题或者需要在不同版本之间反复测试时频繁执行stash和switch很容易让工作现场变得混乱。Git 其实提供了一个非常适合这种场景的功能Git Worktree。内容结构概览本文将介绍Git Worktree 是什么它与git switch、git stash和重新clone有什么区别如何创建、查看和删除 Worktree如何在开发新功能的同时处理紧急 Bug多个 PR、代码审查和版本测试中的使用方法常见问题与容易踩到的坑。一、Git Worktree 是什么Git Worktree 可以让一个 Git 仓库同时拥有多个工作目录每个目录分别检出不同的分支。普通情况下一个仓库只有一个代码目录my-project/这个目录某一时刻只能显示一个分支。你从main切到feature/login后目录中的代码也会随之变化。使用 Worktree 后可以变成这样code/ ├── my-project/ # main ├── my-project-feature-login/ # feature/login └── my-project-hotfix/ # hotfix/payment-timeout三个目录属于同一个 Git 仓库但分别检出了三个不同分支。你可以在第一个目录运行稳定版代码在第二个目录继续开发新功能同时在第三个目录修复线上问题。它们彼此独立不需要来回切换分支也不需要把未完成的代码临时藏进stash。Git 官方把最初通过git clone或git init创建的工作目录称为main worktree后来通过git worktree add创建的目录称为linked worktree。一个普通仓库可以拥有一个主工作区以及零个或多个附加工作区。(Git)二、Worktree 到底共享什么Worktree 并不是重新复制出一份完整的 Git 仓库。多个 Worktree 会共享Git 提交历史对象数据库分支和标签引用远程仓库信息大部分 Git 配置。但每个 Worktree 都拥有自己的工作目录当前检出的分支HEAD暂存区也就是 index未提交修改未跟踪文件。可以把它理解为所有工作区共用一个仓库档案室但每个工作区都有自己的桌面。共享的 Git 仓库 commits / objects / refs │ ┌──────────────┼──────────────┐ │ │ │ Worktree 1 Worktree 2 Worktree 3 main feature hotfix 独立文件 独立文件 独立文件 独立 HEAD 独立 HEAD 独立 HEAD 独立 index 独立 index 独立 indexGit 官方文档也说明不同 Worktree 的HEAD等状态彼此独立而普通分支引用通常由各个 Worktree 共享。(Git)三、为什么不直接重新 clone 一份当然可以重新 clonegitclone gitgithub.com:example/project.git project-maingitclone gitgithub.com:example/project.git project-featuregitclone gitgithub.com:example/project.git project-hotfix但这样会得到三套独立仓库project-main/.git/ project-feature/.git/ project-hotfix/.git/对于大型仓库这意味着Git 对象可能被重复存储每个仓库都要单独执行fetchRemote、Hook 和部分配置可能不一致本地仓库数量越来越多很难管理创建新环境的速度比 Worktree 慢。Worktree 复用的是同一套 Git 仓库数据因此创建速度通常很快也更加节省空间。不过要注意Worktree 只共享 Git 数据并不会共享所有构建产物。例如下面这些目录通常仍然是各自独立的node_modules/ target/ dist/ vendor/ .venv/因此两个大型 Rust Worktree 仍可能分别生成自己的target目录占用较多磁盘空间。四、查看当前已有的 Worktree进入任意一个工作区执行gitworktree list可能得到/Users/mac/code/my-project a1b2c3d [main] /Users/mac/code/my-project-login d4e5f6g [feature/login] /Users/mac/code/my-project-hotfix h7i8j9k [hotfix/payment-timeout]每一行分别表示工作目录路径 当前提交 当前分支查看更详细的信息gitworktree list--verbose需要在 Shell 脚本中处理输出时可以使用gitworktree list--porcelain五、为已有分支创建 Worktree假设仓库中已经存在feature/login当前主仓库位于~/code/my-project可以执行cd~/code/my-projectgitworktreeadd\../my-project-feature-login\feature/loginGit 会创建新目录~/code/my-project-feature-login并在里面检出feature/login。现在可以直接进入新目录cd../my-project-feature-logingitstatus输出会显示On branch feature/login此时主目录仍然保持原来的分支和所有未提交修改完全不会受到影响。六、创建新分支时同时创建 Worktree这是最常用的方式。假设要从最新的origin/main创建一个 Hotfixgitfetch origingitworktreeadd\-bhotfix/payment-timeout\../my-project-payment-timeout\origin/main这条命令同时完成三件事基于origin/main创建hotfix/payment-timeout创建目录../my-project-payment-timeout在新目录中检出该分支。它的通用格式是gitworktreeadd-b新分支名新目录起始提交起始提交可以是main origin/main release/v2 v2.1.0 某个 commit hash例如gitworktreeadd\-bfix/readme-typo\../my-project-fix-readme\origin/main我通常建议明确写出origin/main而不是省略起点。这样可以避免本地main很久没有更新导致新分支建立在旧提交上。七、实战开发未完成时紧急修复 Bug假设你正在ethereumjs-monorepo中开发一个功能当前分支有不少未提交修改gitstatus输出类似On branch feature/trie-refactor Changes not staged for commit: modified: packages/trie/src/trie.ts modified: packages/trie/test/trie.spec.ts现在你需要基于上游最新代码修复一个 README typo。不需要stash直接执行cd~/code/ethereumjs-monorepogitfetch upstreamgitworktreeadd\-bfix-util-readme-typo\../ethereumjs-fix-util-readme-typo\upstream/master如果项目默认分支是main则改成gitworktreeadd\-bfix-util-readme-typo\../ethereumjs-fix-util-readme-typo\upstream/main进入新的工作区cd../ethereumjs-fix-util-readme-typo完成修改gitaddpackages/util/README.mdgitcommit-mdocs(util): fix README typogitpush-uorigin fix-util-readme-typo此时目录结构可能是~/code/ ├── ethereumjs-monorepo/ │ └── feature/trie-refactor保留未提交修改 │ └── ethereumjs-fix-util-readme-typo/ └── fix-util-readme-typo准备提交 PR两个工作区互不干扰。修复完成后你可以在浏览器里提交 PR也可以使用 GitHub CLIghprcreate然后回到原来的目录继续开发cd../ethereumjs-monorepo不需要执行gitstashgitswitchgitstash pop也不需要重新启动或恢复原来分支的工作状态。八、PR 合并后如何清理先确认工作区中没有需要保留的修改cd../ethereumjs-fix-util-readme-typogitstatus然后回到主仓库或者任意其他 Worktreecd../ethereumjs-monorepo删除附加工作区gitworktree remove../ethereumjs-fix-util-readme-typo注意git worktree remove会删除对应的工作目录但不会自动删除分支。如果本地分支已经合并可以继续执行gitbranch-dfix-util-readme-typo清理远程已经删除的跟踪引用gitfetch--pruneorigin完整清理流程如下gitworktree remove../ethereumjs-fix-util-readme-typogitbranch-dfix-util-readme-typogitfetch--pruneoriginGit 官方建议使用git worktree remove删除附加 Worktree而不是直接删除目录。(Git)九、为什么不能直接执行 rm -rf下面这种操作并不推荐rm-rf../my-project-hotfix因为目录虽然被删除了但主仓库内部可能仍然保留该 Worktree 的管理信息。这时执行gitworktree list可能仍会看到已经不存在的工作区。可以使用gitworktree prune清理失效记录。正式删除时最好始终使用gitworktree remove工作区路径如果目录已经被手动删除再执行gitworktree prune查看哪些记录将被清理但暂时不执行gitworktree prune --dry-run--verbose十、工作区中有未提交代码时怎么办假设某个 Worktree 中仍然存在修改gitstatus显示Changes not staged for commit此时执行gitworktree remove../my-project-hotfixGit 通常会拒绝删除因为这会导致未提交内容丢失。正确做法是先决定如何处理这些代码方案一提交代码gitadd.gitcommit-mwip: preserve current work方案二暂存修改gitstash push-u方案三确认不再需要强制删除gitworktree remove--force../my-project-hotfix--force可能造成代码永久丢失使用前应确认该目录中没有任何需要保留的文件。十一、一个分支不能同时在两个 Worktree 中检出假设main已经在主工作区中使用gitworktree list输出/Users/mac/code/my-project a1b2c3d [main]此时再执行gitworktreeadd../my-project-main-copy mainGit 通常会拒绝并提示fatal: main is already checked out这是为了防止两个工作目录同时修改同一个分支指针。假设你只是想基于main做实验应该创建一个新分支gitworktreeadd\-bexperiment/new-parser\../my-project-new-parser\main或者创建一个 detached HEAD 工作区gitworktreeadd\--detach\../my-project-main-test\main默认情况下Git 会阻止同一个分支同时出现在多个 Worktree 中。(Git)十二、用 Worktree 审查别人的 PRWorktree 不仅适合开发也非常适合代码审查。假设要审查 GitHub PR#1234可以先拉取 PR 分支gitfetch origin pull/1234/head:review/pr-1234然后创建 Worktreegitworktreeadd\../my-project-review-1234\review/pr-1234进入该目录cd../my-project-review-1234在不影响当前开发环境的情况下运行gotest./...或者cargotest审查结束后cd../my-projectgitworktree remove../my-project-review-1234gitbranch-Dreview/pr-1234这样每个 PR 都可以拥有独立的测试环境不需要频繁切换当前仓库的分支。十三、同时维护多个 PR对于经常给开源项目提交贡献的人Worktree 非常实用。假设正在处理三个 PRfix/readme-typo fix/parser-comment test/new-analyzer可以分别创建gitfetch upstreamgitworktreeadd\-bfix/readme-typo\../project-fix-readme\upstream/maingitworktreeadd\-bfix/parser-comment\../project-fix-parser-comment\upstream/maingitworktreeadd\-btest/new-analyzer\../project-new-analyzer\upstream/main目录结构变成code/ ├── project/ ├── project-fix-readme/ ├── project-fix-parser-comment/ └── project-new-analyzer/每个目录可以分别打开一个终端或 IDE 窗口。等待第一个 PR 的 CI 时可以直接进入第二个目录继续工作cd../project-fix-parser-comment这种方式比不断switch分支更加自然也不容易把不同 PR 的文件混在一起。不过同时提交多个 PR 时仍应注意项目维护者的体验。相关的小修改最好合并处理不要为了增加提交数量而拆成大量价值很低的 PR。十四、测试旧版本或历史提交Worktree 也很适合临时查看某个版本。例如需要测试v1.5.0gitworktreeadd\--detach\../my-project-v1.5.0\v1.5.0进入该目录cd../my-project-v1.5.0完成编译或测试后删除cd../my-projectgitworktree remove../my-project-v1.5.0因为使用了--detach这个工作区没有绑定普通分支适合复现旧版本 Bug比较两个版本的性能编译某个 Tag检查历史提交执行临时实验。十五、移动 Worktree不要优先使用普通的mv命令移动工作区。推荐执行gitworktree move\../my-project-hotfix\../worktrees/my-project-hotfix如果已经使用 Finder 或mv手动移动了目录导致 Git 的路径记录失效可以尝试gitworktree repair也可以指定路径gitworktree repair../worktrees/my-project-hotfix当前 Git Worktree 命令提供了move和repair分别用于移动工作区和修复工作区关联。(Git)十六、外置硬盘上的 Worktree有时 Worktree 放在移动硬盘、网络磁盘或者临时挂载目录中。磁盘没有挂载时Git 可能认为该工作区已经失效并在后续清理中删除管理记录。可以锁定该 Worktreegitworktree lock\--reasonStored on external SSD\/Volumes/SSD/my-project-release解除锁定gitworktree unlock\/Volumes/SSD/my-project-release日常放在本机固定目录中的 Worktree 通常不需要执行lock。这个功能主要用于路径可能暂时不可访问的工作区。Git 官方命令集中也包含lock和unlock。(Git)十七、推荐的目录组织方式不建议把 Worktree 建在主仓库内部my-project/ └── worktrees/ └── feature-login/这样可能导致IDE 重复索引大量文件搜索结果出现多个版本文件监听器监控额外目录构建工具误扫描另一个工作区主仓库出现复杂的未跟踪目录。更推荐使用并列目录~/code/ ├── ethereumjs-monorepo/ ├── ethereumjs-fix-readme/ └── ethereumjs-trie-refactor/或者统一放在专门目录~/code/ ├── ethereumjs-monorepo/ └── worktrees/ └── ethereumjs/ ├── fix-readme/ ├── trie-refactor/ └── review-pr-1234/对应命令gitworktreeadd\-bfix/readme\~/code/worktrees/ethereumjs/fix-readme\upstream/main目录名称不必与分支名完全相同但保持一致会更容易管理。十八、Worktree、stash 和重新 clone 怎么选三种方式分别适合不同场景。场景推荐方式临时离开当前分支几分钟git stash两个任务需要并行开发Worktree同时运行新旧两个版本Worktree审查多个 PRWorktree复现某个历史版本问题Worktree需要完全不同的 Remote 和 Git 配置重新 clone要破坏性修改.git数据重新 clone多个 AI Agent 同时处理不同任务Worktree简单来说stash是临时把桌面收起来Worktree 是再准备一张桌子重新 clone 则是再租一个办公室。十九、常用命令速查查看全部 Worktreegitworktree list为已有分支创建 Worktreegitworktreeadd目录已有分支创建新分支并创建 Worktreegitworktreeadd-b新分支目录起点创建 detached HEAD 工作区gitworktreeadd--detach目录提交或标签删除 Worktreegitworktree remove目录强制删除gitworktree remove--force目录移动 Worktreegitworktree move旧路径新路径清理失效记录gitworktree prune修复关联gitworktree repair锁定外置工作区gitworktree lock目录解除锁定gitworktree unlock目录二十、总结Git Worktree 解决的问题并不复杂它允许同一个 Git 仓库同时在多个目录中检出不同分支。过去我们常常需要在一个目录中不断执行gitstashgitswitchgitstash pop使用 Worktree 后很多时候只需要切换目录cd../project-featurecd../project-hotfix每个任务都有自己的目录、分支、暂存区和未提交修改。正在运行的开发服务器、IDE 窗口以及测试环境也可以继续保持不需要因为切换分支而反复重启。它尤其适合同时维护多个 PR开发新功能时紧急修复 Bug审查其他人的代码对比多个版本同时运行多个测试环境让多个自动化工具或 AI Agent 并行工作。掌握 Worktree 后Git 分支不再只是需要不断切换的状态而可以变成多个真正并行存在的工作空间。对于经常参与大型开源项目、同时维护多个分支的开发者来说这可能是 Git 中最值得养成使用习惯的功能之一。参考资料Git 官方git-worktree文档对 Worktree 的创建、查看、删除、移动、清理、锁定和修复等行为给出了完整定义。(Git)

相关新闻

函数指针、指针函数与结构体的基础知识与应用

函数指针、指针函数与结构体的基础知识与应用

一、指针函数 1.概念 本质是指针&#xff0c;返回值是指针 2.定义格式 数据类型 *函数名(参数列表) { 函数体&#xff1b; return 地址&#xff1b; } 3.应用实例 #include<stdio.h> #include<stdlib.h> #include<string.h> char *fun() {// char p[…

2026/7/24 12:19:58 阅读更多 →
嵌入式AI部署---基于RK3588运行yolov5(2)

嵌入式AI部署---基于RK3588运行yolov5(2)

前言&#xff1a;在上篇博客中撰写了关于yolov5在RK3588上运行的流程&#xff0c; 在学习的过程中发现后处理很难&#xff0c;我一直不理解输出结果是如何存储的&#xff0c;它比较抽象&#xff0c;对于我来讲很难理解&#xff0c;经过一段时间的学习&#xff0c;有了一个比较好…

2026/7/24 12:20:13 阅读更多 →
Netflix-4K-DDplus字幕优化技巧:如何调整字幕样式和关闭imsc字幕

Netflix-4K-DDplus字幕优化技巧:如何调整字幕样式和关闭imsc字幕

Netflix-4K-DDplus字幕优化技巧&#xff1a;如何调整字幕样式和关闭imsc字幕 【免费下载链接】netflix-4K-DDplus MicrosoftEdge(Chromium core) extension to play Netflix in 4K&#xff08;Restricted&#xff09;and DDplus audio 项目地址: https://gitcode.com/gh_mirr…

2026/7/23 17:32:39 阅读更多 →

最新新闻

LLM-Explorer:用语言模型优化强化学习策略探索

LLM-Explorer:用语言模型优化强化学习策略探索

1. 项目概述&#xff1a;LLM-Explorer如何革新强化学习的策略探索 在强化学习领域&#xff0c;策略探索&#xff08;Policy Exploration&#xff09;一直是决定算法性能的关键瓶颈。传统方法如ε-greedy或高斯噪声注入&#xff0c;本质上都是基于预设的随机过程&#xff0c;这种…

2026/7/24 12:20:15 阅读更多 →
【毕业设计】 基于 Django 的教材出入库运维管理系统轻量化校园教材数字化管理网站设计(源码文档+远程调试,全bao定制等)

【毕业设计】 基于 Django 的教材出入库运维管理系统轻量化校园教材数字化管理网站设计(源码文档+远程调试,全bao定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

2026/7/24 12:20:15 阅读更多 →
AI Agent开发实战:从概念到工业落地的关键技术

AI Agent开发实战:从概念到工业落地的关键技术

1. AI Agent技术全景解析&#xff1a;从概念到工业落地的完整路径 AI Agent&#xff08;人工智能代理&#xff09;正在成为改变人机交互方式的核心技术。不同于传统程序化的"输入-输出"模式&#xff0c;AI Agent具备自主感知、决策和执行能力&#xff0c;能够像人类员…

2026/7/24 12:20:15 阅读更多 →
医疗AI核心技术解析:从智能分诊到精准治疗

医疗AI核心技术解析:从智能分诊到精准治疗

1. 医疗AI革命&#xff1a;当算法穿上白大褂三甲医院挂号难、候诊3小时问诊5分钟、基层医院误诊率高……这些困扰患者多年的就医痛点正在被AI技术系统性解决。去年在深圳投入运营的"智慧医疗综合体"给出了惊艳答卷&#xff1a;通过部署147个医疗AI模块&#xff0c;实…

2026/7/24 12:20:15 阅读更多 →
郴州广告公司哪个信誉好

郴州广告公司哪个信誉好

在选择郴州地区的广告公司时&#xff0c;信誉是一个非常重要的考量因素。一个信誉良好的广告公司不仅能提供高质量的服务&#xff0c;还能确保项目的顺利进行。本文将从多个角度分析郴州地区几家知名广告公司的信誉情况&#xff0c;帮助您做出明智的选择。引言随着市场经济的发…

2026/7/24 12:20:15 阅读更多 →
靠谱的斗拱安装机构

靠谱的斗拱安装机构

如果你正在寻找靠谱的斗拱安装机构&#xff0c;那么选择时需要考虑几个关键因素&#xff1a;专业背景、服务质量、以及是否能提供一体化解决方案。基于这些标准&#xff0c;这里推荐几家在行业内享有良好声誉的企业。推荐一&#xff1a;邯郸市骏宸新材料科技有限公司核心优势&a…

2026/7/24 12:19:14 阅读更多 →

日新闻

用Highcharts 创建可拖拽三维散点立方体3D图表

用Highcharts 创建可拖拽三维散点立方体3D图表

该案例基于Highcharts scatter3d 三维散点图实现空间立方体散点可视化&#xff0c;核心特色&#xff1a;三维 X/Y/Z 三轴空间&#xff0c;所有散点分布在 0~10 立方体空间内&#xff1b;散点使用径向渐变实现立体 3D 圆球质感&#xff1b;支持鼠标 / 触屏拖拽画布&#xff0c;…

2026/7/24 0:00:29 阅读更多 →
AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls&#xff1a;进程创建路径上的 DLL 入口 AppCertDlls 位于 HKLM\System\CurrentControlSet\Control\Session Manager\AppCertDlls。本文的程序功能是只读列出这个键在 64 位和 32 位注册表视图中的全部值&#xff0c;并显示每条值的来源、名称、类型和可安全显示的数…

2026/7/24 0:00:29 阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好&#xff0c;我是一名编程初学者&#xff0c;同时这也是我编程学习之路上的第一篇博客。在这里&#xff0c;我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手&#xff0c;目前在学习c语言&#xff0c;我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:29 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中&#xff0c;我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源&#xff0c;还是配置文件、证书等&#xff0c;都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下&#xff0c;但这…

2026/7/24 3:59:20 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP&#xff08;轻量级目录访问协议&#xff09;作为企业级身份认证的黄金标准&#xff0c;已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时&#xff0c;发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 1:23:39 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”&#xff0c;而是以可解释、可审计、可迭代的方式&#xff0c;赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 17:49:47 阅读更多 →

月新闻