前言

上一篇文章 Git Worktree 大法真香 带大家了解了 git worktree 是如何帮助我同时在多个分支工作,并且互不影响的。但是创建 worktree 的目录位置不是在当前项目下,总感觉创建好的这些 worktree 不属于当前项目,这对于磁盘管理强迫症的我来说是十分难受的,今天就带大家了解一种高级用法来解决这个痛点

准备知识

在使用高级用法之前,你需要知道一点 bare repo 知识,我们先从你熟悉的命令开始

git init
git clone https://github.com/FraserYu/amend-crash-demo.git

这两个命令就会生成一个 non-bare repo,我们通常都在这样的 repo 中进行日常工作, 你可以在这里面 add/commit/pull/push

要想生成一个 bare repo 也很简单, 只需在上面两个命令的基础上加上 --bare 参数即可

git init --bare
git clone --bare https://github.com/FraserYu/amend-crash-demo.git

来执行这两个 clone 命令,并查看文件内容你就会看出差别了

  1. bare repo 仅仅包含 Git 相关信息,并不包含我们的实际项目文件(.java/.js/.py), 而 non-bare repo 却包含我们的全部信息
  2. bare repo 名称默认是带有 .git 后缀的,这也恰恰证明了第一点
  3. bare repo 中是不存在 .git 文件夹的,这也就导致它不能像 non-bare repo 那样 add/commit/pull/push

看到这,你可能感觉 bare repo 就是一个 Git 空壳文件夹,一无是处。其实不然,正因为 bare repo 的这些特性(不能对它进行更改),也就避免 repo 里面的内容被弄的一团糟,所以可以被用来做私有的中心化 repo,一张图解释,其实就是这样的:

如果你有兴趣,可以按照下面的命令在本地实验一下整个过程:

user@server:$~  git init --bare name_to_repo.git

user@machine1:$~ git clone user@server:/path/to/repo/name_to_repo.git .
user@machine1:$~ cd name_to_repo
user@machine1:$~ touch README
user@machine1:$~ echo "Hello world" >> README
user@machine1:$~ git add README
user@machine1:$~ git commit -m "Adding a README"
user@machine1:$~ git push origin master user@server:$~ ls /path/to/repo/name_to_repo.git/
branches/ config description HEAD hooks/ info/ objects/ refs/ user@machine2:$~ git clone user@server:/path/to/repo/name_to_repo.git .
user@machine2:$~ ls name_to_repo.git/
README
user@machine2:$~ cat README
Hello world

实验结果就是:无论在 machine1 下怎么 push 文件,bare repo 中都不会存在你 push 的文件,只有 Git 相关信息。但是 machine2 clone 最新的 repo 时,却能看到machine1 push 的文件,这正是 Git 的魔法所在

到这里,bare repo 就解释完了。接下来,接上一篇 Git Worktree 大法真香 内容,借助 bare repo 的特性,来优化同时在多个分支工作的做法吧

Git Worktree 高级用法

首先,在你选定的目录下为你的项目(比如这里叫 amend-crash-demo)单独创建一个文件夹, 并 cd 进去

mkdir amend-crash-demo
cd amend-crash-demo

接下来以 bare 的形式 clone 项目代码, 并将内容 clone 到 .bare 文件夹内:

git clone --bare git@github.com:FraserYu/amend-crash-demo.git .bare

我们还要在当前目录下创建一个 .git 文件,文件内容是以 gitdir 的形式指向我们的 .bare 文件夹 (如果不理解 gitdir 的含义,请回看 Git Worktree 大法真香

echo "gitdir: ./.bare" > .git

然后我们要编辑 .bare/config 文件,并修改 [remote "origin"]内容,和下面内容保持一致(也就是添加第 6 行内容),这确保我们创建 worktree 切换分支,可以显示正确的分支名称

vim .bare/config

# -----------------------------------------------
[remote "origin"]
url = git@github.com:FraserYu/amend-crash-demo.git
fetch = +refs/heads/*:refs/remotes/origin/*

接下来我们就可以创建 worktree 了,首先我们要为 main 分支创建 worktree,因为 main 分支 HEAD 的指向的 commit-ish 就是你创建其他 worktree 的 commit-ish

git worktree add main

# --------------------------------
Preparing worktree (checking out 'main')
HEAD is now at 82b8711 add main file

通常我们不会直接在 main 分支上直接工作,而是创建其它类型的分支,继续创建名为 feature/JIRA234-feature3 的 worktree

git worktree add -b "feature/JIRA234-feature3" feature3

# ------------------------------------------------
Preparing worktree (new branch 'feature/JIRA234-feature3')
HEAD is now at 82b8711 add main file

查看当前文件夹的内容,你会发现只有 mainfeature3 两个文件夹(因为 .bare.git 是隐藏文件夹/文件),这样是不是相当清爽呢?

ls -l

# -------------------------------------------
total 0
drwxr-xr-x 10 rgyb staff 320 Nov 23 21:44 feature3
drwxr-xr-x 10 rgyb staff 320 Nov 23 21:36 main ls -al
# -------------------------------------------
total 8
drwxr-xr-x 6 rgyb staff 192 Nov 23 21:44 .
drwxr-xr-x 3 rgyb staff 96 Nov 23 21:14 ..
drwxr-xr-x 12 rgyb staff 384 Nov 23 21:36 .bare
-rw-r--r-- 1 rgyb staff 16 Nov 23 21:29 .git
drwxr-xr-x 10 rgyb staff 320 Nov 23 21:44 feature3
drwxr-xr-x 10 rgyb staff 320 Nov 23 21:36 main

接下来就可以尽情的在我们的各种分支上,彼此互不影响的进行 add/commit/pull/push 操作了

echo "feature3 development" > feature3.yaml
git add feature3.yaml git commit -m "feat: [JIRA234-feature3] feature3 development"
# ------------------------------------------------------------------
[feature/JIRA234-feature3 aeaac94] feat: [JIRA234-feature3] feature3 development
1 file changed, 1 insertion(+)
create mode 100644 feature3.yaml git push --set-upstream origin feature/JIRA234-feature3

通过上一篇文章 worktree 的四个命令,多分支协同开发不再是问题:

git worktree add
git worktree list
# ------------------------------------------------------------------------------------------------
/Users/rgyb/Documents/projects/amend-crash-demo/.bare (bare)
/Users/rgyb/Documents/projects/amend-crash-demo/feature3 aeaac94 [feature/JIRA234-feature3]
/Users/rgyb/Documents/projects/amend-crash-demo/main 82b8711 [main] git worktree remove
git worktree prune

总结

通过借助 bare repo 的特性,我们可以非常整洁的将所有 worktree 只管理在当前项目目录下,多分支协同开发,就像这样:

.
└── amend-crash-demo
├── feature3
│   ├── README.md
│   ├── config.yaml
│   ├── feat1.txt
│   ├── feature3.yaml
│   ├── file1.yaml
│   ├── hotfix.yaml
│   ├── main.properties
│   └── main.yaml
└── main
├── README.md
├── config.yaml
├── feat1.txt
├── file1.yaml
├── hotfix.yaml
├── main.properties
└── main.yaml 3 directories, 15 files

如果你有磁盘管理强迫症,这绝对是个好办法。

如果你想更好的理解整个过程,你需要在操作本文命令的同时,查看 Git 相关的文件信息

有什么问题,留言区交流

参考

  1. https://www.blopig.com/blog/2017/06/using-bare-git-repos/
  2. https://lists.mcs.anl.gov/pipermail/petsc-dev/2021-May/027448.html
  3. https://www.saintsjd.com/2011/01/what-is-a-bare-git-repository/
  4. https://infrequently.org/2021/07/worktrees-step-by-step/
  5. https://morgan.cugerone.com/blog/how-to-use-git-worktree-and-in-a-clean-way/

    个人博客:https://dayarch.top

    加我微信好友, 进群娱乐学习交流,备注「进群」

欢迎持续关注公众号:「日拱一兵」

  • 前沿 Java 技术干货分享
  • 高效工具汇总 | 回复「工具」
  • 面试问题分析与解答
  • 技术资料领取 | 回复「资料」

以读侦探小说思维轻松趣味学习 Java 技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,请持续关注......


接上篇:Git Worktree 高级使用,这样清爽多了的更多相关文章

  1. git worktree

    git clone,不管是single-branch,还是non-single-branch,如果同时存在几个clone出来的branches,随着时间的推移,不停的编译.更新.编译...每个bran ...

  2. git worktree 是什么及其使用场景

    先上总结: 在git worktree出现之前, git切换分支前后的文件都只存在在当前文件夹下, git worktree出现之后, 我们可以将分支切换到其他文件夹下 比如如果你的项目有很多个版本分 ...

  3. 再也不用克隆多个仓库啦!git worktree 一个 git 仓库可以连接多个工作目录

    我在 feature 分支开发得多些,但总时不时被高优先级的 BUG 打断需要临时去 develop 分一个分支出来解 BUG.git 2.6 以上开始提供了 worktree 功能,可以解决这样的问 ...

  4. 问题: 查看某个文件的修改记录| git log 高级用法

    参考文章: git查看某个文件的修改历史 5.3 Git log 高级用法 基本步骤 git log --pretty=oneline [文件名] git show [节点] git log 两周高级 ...

  5. Git worktree 使用笔记【转】

    gitworktree 本地仓库的多个分支在对应的文件夹内管理,能够减少很多操作,便捷高效~ 一 worktree 的基本概念和操作 再也不用克隆多个仓库啦!git worktree 一个 git 仓 ...

  6. git worktree 使用笔记

    一 worktree 的基本概念和操作 再也不用克隆多个仓库啦!git worktree 一个 git 仓库可以连接多个工作目录 - walterlv的专栏 - CSDN博客 再也不用克隆多个仓库啦! ...

  7. git worktree 目录修复

    三种方式挨个尝试,1不行用2 2不行用3 1.拉取阶段失败 git worktree add -f -B xxx_branch ./xxx_branch origin/xxx_branch 强制拉取 ...

  8. git worktree 稀疏检出(sparseCheckout)

    稀疏检出配置: git config core.sparsecheckout true echo another_folder/xxxx/ >> .git/info/sparse-chec ...

  9. Git log高级用法

    格式化Log输出 首先,这篇文章会展示几种git log格式化输出的例子.大多数例子只是通过标记向git log请求或多或少的信息. 如果你不喜欢默认的git log格式,你可以用git config ...

随机推荐

  1. 题解 51nod 1597 有限背包计数问题

    题目传送门 题目大意 给出 \(n\),第 \(i\) 个数有 \(i\) 个,问凑出 \(n\) 的方案数. \(n\le 10^5\) 思路 呜呜呜,傻掉了... 首先想到根号分治,分别考虑 \( ...

  2. 4.1 The Example Domain 领域示例代码

    4.1 The Example Domain 领域示例代码 The examples will use some concepts those are used by GitHub, like Iss ...

  3. javascript-jquery介绍

    jquery优势 1.轻量级 2.强大的选择器 3.出色的DOM封装 4.可靠的事件处理机制 5.完善的Ajax 6.不污染顶级变量 7.出色的浏览器兼容 8.链式操作方式 9.隐式迭代 10.行为层 ...

  4. AgileConfig 轻量级配置中心 1.5 发布 - 支持多环境配置

    AgileConfig 从发布到现在,收到不同学的 issue 说需要多环境的支持.也就是一个应用在不同的环境下可以配置不同的配置项.这是一个非常有用的功能,就跟我们开发的时候会设置多个 appset ...

  5. Java:NIO 学习笔记-3

    Java:NIO 学习笔记-3 根据 黑马程序员 的课程 JAVA通信架构I/O模式,做了相应的笔记 3. JAVA NIO 深入剖析 在讲解利用 NIO 实现通信架构之前,我们需要先来了解一下 NI ...

  6. Java:NIO 学习笔记-1

    Java:NIO 学习笔记-1 说明:本笔记是根据bilibili上 尚硅谷 的课程 NIO视频 而做的笔记 主要内容 Java NIO 简介 Java NIO 与 IO 的主要区别 缓冲区(Buff ...

  7. 方阵里面的dp

    打了一场luogu的信心赛,惊讶地发现我不会T2,感觉像这样在矩阵里面的dp看起来很套路的样子,但是仔细想想还是有很多需要注意的细节. 又想到之前貌似也考过一些类似的题目 然而我并没有改 ,于是打算补 ...

  8. MVC之三个单选按钮的切换选择

    实现需求: 1.三个多选按钮中:只能同时选择限时抢购和分享金或者拼团特惠和分享金,其中限时抢购和拼团特惠不能同时选择.并且点击后显示,再次点击赢隐藏. 1 @*活动信息*@ 2 <div> ...

  9. C#写TXT文档

    //C#写TXT文档 String strDir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAs ...

  10. cm3 逆向分析

    目录 cm3 逆向分析 前言 逆向分析 cm3 逆向分析 前言 这道题没加壳,也没加密算法,主要看代码逻辑. 逆向分析 代码很短,一共这么几句. 看提示知道只让我们输入w.s.a.d这几个字符,并且用 ...