一. 背景

在工作中大家应会碰到需要频繁在两个分支中切换工作的情况,我们通常做法是利用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. 【#HDC2022】HarmonyOS体验官活动正式开启,赶快投稿赢限量奖品吧!

      1. [活动简介] HDC 2022 于11月4日线上线下正式开启.历时一年,在无数开发者的共同努力下,我们汇聚了HarmonyOS生态的新成果.新体验.新开放能力,邀你参与到HarmonyOS的 ...

  2. gRPC入门学习之旅(六)

    gRPC入门学习之旅(一) gRPC入门学习之旅(二) gRPC入门学习之旅(三) gRPC入门学习之旅(四) gRPC入门学习之旅(五) 3.3.客户端编译生成GRPC类 1. 在"解决方 ...

  3. 报表如何批量导出成 excel 文件

    需求说明 报表展现后可以通过工具栏中的导出按钮将当前展现的报表导出成 excel 文件,但是在实际使用中通常会要求报表不需要展现,直接通过一些操作将报表导出成 excel 文件,并且往往会要求批量导出 ...

  4. Webpack中常见的Loader?解决了什么问题?

    一.是什么 loader 用于对模块的源代码进行转换,在 import 或"加载"模块时预处理文件 webpack做的事情,仅仅是分析出各种模块的依赖关系,然后形成资源列表,最终打 ...

  5. Ubuntu下部署gitlab

    1.安装gitlab服务 1.安装依赖 在ubuntu下使用快捷键ctrl+alt+T打开命令行窗口,然后运行下面命令 sudo apt update sudo apt-get upgrade sud ...

  6. 我在阿里巴巴做 Serverless 云研发平台

    简介: Serverless 云研发平台经过这半年多的蜕变,已经从简单的解决工程链路的平台演进成一个面向研发.上线.运维的全生命周期研发平台,后续要解决的命题会集中在用户低门槛上. 作者 | 林昱(苏 ...

  7. 编译优化 | LLVM代码生成技术详解及在数据库中的应用

    简介: 作者:长别 1. 前言 随着IT基础设施的发展,现代的数据处理系统需要处理更多的数据.支持更为复杂的算法.数据量的增长和算法的复杂化,为数据分析系统带来了严峻的性能挑战.近年来,我们可以在数据 ...

  8. [TP5] ThinkPHP 默认模块和单模块的设置方式

    由于默认是采用多模块的支持,所以多个模块的情况下必须在URL地址中标识当前模块, 如果只有一个模块的话,可以进行模块绑定,方法是应用的入口文件中添加如下代码: // 绑定当前访问到index模块 de ...

  9. [php-src] Php内核的有趣高频宏

    内容均以php-5.6.14为例. 1. EXPECTED 和 UNEXPECTED 宏,用在判断条件的时候. ./Zend/zend.h:390 #if (defined (__GNUC__) &a ...

  10. win10 uwp 简单制作一个 Path 路径绘制的图标按钮

    本文告诉大家在 UWP 或 WinUI 3 里面如何简单制作一个由 Path 几何路径图形绘制的图标按钮 先在资源里面定义按钮的样式,重写 Template 属性,通过在 Template 里面放入 ...