一. 背景

在工作中大家应会碰到需要频繁在两个分支中切换工作的情况,我们通常做法是利用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. HarmonyOS属性动画开发示例(ArkTS)

      介绍 利用ArkUI组件不仅可以实现属性变化引起的属性动画,也可以实现父组件状态变化引起子组件产生动画效果,这种动画为显式动画.效果如图所示: 相关概念 显式动画:提供全局animateTo显式动 ...

  2. HarmonyOS极客松“上分秘籍”! 高手们顶峰相见!

      HarmonyOS 极客马拉松2023 火热进行中,我们期待与各位开发者相聚一起,践行极客精神,创造无限可能! 我们鼓励各位极客们自由组队,挥洒创意,用HarmonyOS 探索移动应用和服务的更多 ...

  3. 一种新的姿势:程序try/catch抛出异常之绕过canary pwn121

    一种新的姿势:程序try/catch抛出异常之绕过canary 我前面发了不少关于绕过canary的姿势,先总结一下,现在绕过canary的姿势有泄露,爆破,格式化字符串绕过,多线程劫持TLS绕过, ...

  4. 收藏 | 超详细的Oracle19c安装步骤-CentOS Linux

    ORACLE学习-DBA数据库工程师 收藏 | 超详细的Oracle19c安装步骤 挨踢-IT人加油 [微思网络]IT培训-思科/华为/红帽/ORACLE... 2 人赞同了该文章 DBA数据库管理必 ...

  5. Jedis连接踩坑日记

    Jedis连接踩坑日记 背景: 线上某块业务的增删改功能全部都不可用.页面发送了xhr请求之后 状态一直处于pending状态,后端没有日志产生 排查路线与解决办法 第一:由于服务在内网里面,无法进行 ...

  6. pycharm更换主题,pycharm更换皮肤,pycharm更换不同颜色

    1.首先  点击File→进入setting 2. 在settings里面找到appearance 3.选择 Theme,下拉即可修改 4.选择不同的主题,darcula是黑色,其他两个是白色

  7. 力扣125(java)-验证回文串(简单)

     题目: 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写. 说明:本题中,我们将空字符串定义为有效的回文串. 示例 1: 输入: "A man, a plan ...

  8. 如何使用 Serverless Devs 部署静态网站到函数计算(上)

    简介:部署个静态网站到函数计算~ ​ 前言 公司经常有一些网站需要发布上线,对比了几款不同的产品后,决定使用阿里云的函数计算(FC)来托管构建出来的静态网站. FC 弹性实例自带的500 Mb 存储空 ...

  9. 2018-5-28-WPF-Process.Start-出现-Win32Exception-异常

    title author date CreateTime categories WPF Process.Start 出现 Win32Exception 异常 lindexi 2018-05-28 10 ...

  10. Django之ORM操作Mysql

    一.单表操作 # 单表查询操作基本方法 class BookList(models.Model): title = models.CharField(max_length=32) price = mo ...