一. 背景

在工作中大家应会碰到需要频繁在两个分支中切换工作的情况,我们通常做法是利用git stash命令暂存当前工作区中的变更,然后git checkout到目标分支中工作,工作完成后回到刚刚分支使用git stash pop命令还原历史工作区变动。

整体流程大致如下:

# 当前工作分支,存在变更
$ worktree-test (dev1) git status
On branch test
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: bbb.txt no changes added to commit (use "git add" and/or "git commit -a") # 暂存变更
$ worktree-test (dev1) git stash
Saved working directory and index state WIP on test: 2bc59f3 add bbb.txt # 切换分支
$ worktree-test (dev1) git checkout dev2 #........在dev2上进行代码修改并提交 # 切换回原先的dev1分支
$ worktree-test (dev2) git checkout dev1 # 还原工作区变更,继续开发
$ worktree-test (dev1) git stash pop
On branch test
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: bbb.txt no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (3890bfc0568be86c8ba2a26c7138966bf8776e5c)

上述流程如果在我们需要反复多次在两个分支间切换工作的时候会很不方便,因为你每一次checkout都会使得IDEA重建索引,如果在项目比较大的情况下会非常耗时。

此时有很多小伙伴可能会选择重新clone一份代码下来,在两个本地仓库中并行开发,这么做固然可以解决问题,但是Git官方给出了更优雅的解决方案,那就是git worktree

二. 什么是worktree

Git worktree严格意义上说已经不是一个新的功能了,它推出也已经好几年了,是在2015年7月发布的2.5版引入的。worktree是链接到统一仓库的多个工作区(目录,树)。一个git仓库可以支持多个工作树,分别对应不同的分支。我们在git中通过git initgit clone创建一个(主)工作区(树)(main working tree)。

同理,我们使用 git worktree 创建一个(和工作区)不同目录的工作区(树),我们称之为为"链接工作区(树)(linked working tree)"。git仓库有一个主工作树(裸库)和零个或多个链接工作树。与重建的孤立的目录不同,链接工作树和主仓库直接就行分支一样是有机关联的,任何一个链接工作树的变更提交都在仓库内部。链接工作树用完后,可以直接通过git worktree remove删除。

三. 基本使用

我们当前工作区处在test分支上,假设我们需要在testdev两个分支间来回切换,此时我们可以创建一个worktree并行去开发:

$ worktree-test (test) git worktree add ../worktree-test-dev dev
Preparing worktree (checking out 'dev')
HEAD is now at 7e8e244 add aaa.txt

此时Git就会在我们指定的目录(../worktree-test-dev)中创建一个新的worktree,

这样我们就能将worktree-test-dev这个文件夹导入IDEA,这样就能在不切换分支的情况下,在两个分支下并行开发,这样就能节约频繁分支切换导致的效率问题。

不同的worktree之间共用同一个 commit 树,这样我们在 worktree-test-dev 文件夹做变更并提交后,commit信息也会在别的 worktree 的commit tree中看到。

当我们在临时创建的 worktree 中完成工作后,我们可以通过 git worktree remove 删除这个 worktree

# 查看当前有哪些worktree
$ worktree-test (test) git worktree list
C:/Users/JindongTian/Desktop/worktree-test 2bc59f3 [test]
C:/Users/JindongTian/Desktop/worktree-test-dev 7e8e244 [dev] # 删除临时创建的 worktree-test-dev worktree
$ worktree-test (test) git worktree remove ../worktree-test-dev/

执行完成后,我们就能发现worktree-test-dev文件夹被删除,而刚刚在worktree-test-dev的提交,仍然保留在 commit 树中。

四. 常用命令

4.1 新建worktree

git worktree add <新路径> <分支/commit ID>

需要注意的是,使用 git worktree 创建的多个目录,不能有任何两个目录在同一个分支下,这样是防止两个文件夹在相同的分支下做不同的修改。所以我们在创建worktree时,<分支>一定是不能是当前分支。如果我们想基于当前分支创建一个新分支,并创建基于新分支的worktree可以这样做:

git worktree add -b <新分支名> <新路径> <分支/commit ID>

4.2 查看 worktree 列表

git worktree list

4.3 删除 worktree

git worktree remove <路径>

需要注意的是:

  1. 该命令只能删除干净的工作树(没有未跟踪的文件,也没有对已跟踪文件进行修改但未提交的情况称为干净的工作树)。不干净的工作树或带有子模块的树需要使用–force删除。

  2. 主工作树无法删除。

4.4 清理worktree的配置信息

git worktree prune

清理worktree的配置信息 $GIT_DIR/worktrees。例如手动删除了一个worktree的文件夹但是没有执行git worktree remove,git并不能识别出已经删除了。此时就可以使用git worktree prune手动更新项目的woktree配置。

4.5 移动 worktree 目录

git worktree move <原路径> <新路径>

将working tree目录移动到新位置。主目录和带有子模块(submodules)的目录不可以移动。

开发中你不得不知的一个Git小技巧的更多相关文章

  1. Windows Phone开发(8):关于导航的小技巧

    原文:Windows Phone开发(8):关于导航的小技巧 前文用几个例子对导航做了简单介绍,在一般应用中,使用上一篇文章中说到的方法,其实也够用了,不过,为了能够处理一些特殊的情况,有几个小技巧还 ...

  2. 开发中可能会用到的几个小tip----QT, pycharm, android, 等

    QT: 如果是在windows下开发的话,添加外部库,外部包含头文件路径的时候,要注意用相对路径,或者在项目上右键添加外部库的路径或者头文件路径,否则,会卡在这里开始怀疑人生... 如果是在linux ...

  3. Java开发中要避免的坑和一些代码优化技巧

    1:动态SQL遇到的坑,先看下面OGNL表达式的说明. Any object can be used where a boolean is required. OGNL interprets obje ...

  4. Git小技巧之使用Rebase命令合并提交

    想要获取更多文章可以访问我的博客 - 代码无止境. 在日常的开发过程中,我们一个功能可能会有很多次提交.而且我们公司的开发是不允许直接往公司仓库提交代码,所以需要fork到自己的仓库然后merge过去 ...

  5. Git 小技巧:忽略某些文件的更改

    *以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/dp9Mwq7vf0ASF_FftBN8Ww 作为一枚合格的代码贡献 ...

  6. Git小技巧 - 指令别名及使用Beyond Compare作为差异比较工具

    前言 本文主要写给使用命令行来操作Git的用户,用于提高Git使用的效率.至于使用命令还是GUI(Tortoise Git或VS的Git插件)就不在此讨论了,大家根据自己的的喜好选择就好.我个人是比较 ...

  7. Git 小技巧

    分享git的几个小技巧,后面会根据使用补充.目前包括git撤销本地修改.git回退到前n个版本.git多用户提交冲突解决.git 命令简化.欢迎大家补充^_* 1.git撤销本地修改 git rese ...

  8. 教你一个vue小技巧,一般人我不说的

    本文由云+社区发表 1. 需求 最近的项目中,需要实现在vue框架中动态渲染带提示框的单选/多选文本框,具体的效果如下图所示,在输入框聚焦时,前端组件通过接收的kv参数渲染出选项,用户点击选项,可以将 ...

  9. 不是吧?30秒 就能学会一个python小技巧?!

    大家好鸭!我是小熊猫 很多学习Python的朋友在项目实战中会遇到不少功能实现上的问题,有些问题并不是很难的问题,或者已经有了很好的方法来解决.当然,孰能生巧,当我们代码熟练了,自然就能总结一些好用的 ...

  10. 小程序语音红包开发中 汉字转拼音的问题 微信小程序红包开发遇到的坑

    公司最近在开发微信小程序的红包功能,语音红包需要用到文字转拼音的功能. 之前介绍过怎么将中文的汉字转为拼音的,具体看下面这篇文章. 微信语音红包小程序开发如何提高精准度 红包小程序语音识别精准度 微信 ...

随机推荐

  1. Linux 编译 libjpeg-9e

    jpeg的库有两个:一个是官方的 libjpeg  还有一个是 libjpeg-turbo JPEG库(libjpeg-turbo):https://libjpeg-turbo.org/ Libjpe ...

  2. Godot Label样式 Textrue纹理,实现样式修改,背景填充

    目录 前言 运行环境 新建项目 Style 样式讲解 StyleBoxEmpty:普通样式 StyleBoxTexture:字体样式 StyleBoxFlat:填充样式 StyleBoxLine:行样 ...

  3. 重学c#系列——什么是性能[外篇性能篇一]

    前言 简单写一下性能的简介. 正文 什么是性能,很多时候有一个问题,那就很多人喜欢说.这个服务有很多访问,我们需要这样设计. 这是一个无法验证的指标,访问次数是多少? 响应时间是多少. 我把这归纳为自 ...

  4. 什么是ip协议二

    前言 续前面一章. 正文 看下ip选项: 看一张图: 这个ip选项一般我们不用看,即使你去搞硬件,那么做c++或者c的人会告诉你填啥,按照他们设置即可. 那么ip是如何传输的呢? 先看这张图,这张图的 ...

  5. JS中通过url动态获取图片大小的方法小结(两种方法)

    很多时候再项目中,我们往往需要先获取图片的大小再加载图片,但是某些特定场景,如用过cocos2d-js的人都知道,在它那里只能按比例缩放大小,是无法设置指定大小的图片的,这就是cocos2d-js 的 ...

  6. 牛客网-SQL专项训练9

    ①假设有选课表course_relation(student_id, course_id),其中student_id表示学号,course_id表示课程编号,如果小易现在想获取每个学生所选课程的个数信 ...

  7. 这种精度高,消耗资源少的大模型稀疏训练方法被阿里云科学家找到了!已被收录到IJCAI

    简介: 论文通过减少模型稀疏训练过程中需要更新的参数量,从而减少大模型稀疏训练的时间以及资源开销,是首个大模型参数高效的稀疏训练算法PST. 作者:李深.李与超 近日,阿里云机器学习PAI关于大模型稀 ...

  8. 滴滴 Flink-1.10 升级之路

    简介: 滴滴实时计算引擎从 Flink-1.4 无缝升级到 Flink-1.10 版本,做到了完全对用户透明.并且在新版本的指标.调度.SQL 引擎等进行了一些优化,在性能和易用性上相较旧版本都有很大 ...

  9. 揭秘远程证明架构EAA:机密容器安全部署的最后一环 | 龙蜥技术

    ​简介:如果需要在云上 HW-TEE 环境里启动一个加密容器,如何在启动过程中获取容器的解密密钥? ​ 文 / 周亮, 云原生机密计算 SIG 核心成员. 在云原生场景下,基于HW-TEE(如Inte ...

  10. [FAQ] 钉钉 Excel 回车键不能换行 ? 在线编辑如何换行

      Win 端表格换行:AIT+ENTER Mac 端表格换行:AIT OPTION+ENTER Tool:ChatAI Refer:钉钉技巧 Refer:https://www.dingtalk.c ...