git subtree使用说明

为什么要使用subtree

在实际的项目开发过程中,公共的代码或者模块是必定会出现的,为了不重复写相同的代码;普遍的做法就是将其抽取成一个公共模块,这个模块由不同的使用者引用;作为java工程师,可能会选择将这一部分打包封装成一个jar,并且将其推送到Maven的私有仓库,各个使用者将其添加到pom文件即可;但是有没有更好的方式呢?因为使用这种方式,对使用者来说,并不是透明的,当前可能已经更新版本了,但是我作为使用者并不知道当前已经更新了,知道更新了可能也不知道最新版本是多少,我还得通过咨询模块开发人员或者说到私有仓库去查看才能知道,那有没有更好的方式呢?
接下来,就一起探讨一种更好的管理方式:git subtree,如果说你现在还不知道git是啥或者怎么用?强力建议去学习一下。

什么是git subtree?有啥优势?
  • git subtree可以将一个仓库作为仓库的子仓库
  • 各个仓库之前的版本管理是相对独立的
  • 对于使用者来说,是透明的,可能使用者根本都不知道有子仓库的存在;
  • 主子仓库的分支同步,即你切换主项目分支的时候,关联的子仓库也会同步切换
缺点
  • 需要学习新的操作指令,git subtree有自己的一套指令
  • 指令的复杂度比较高,相比于常规的操作指令,其更加的复杂;
  • 子仓库操作的时候,由于关联了其他仓库,因此指令的响应速度没有单仓库快
  • 子仓库的分支管理比较麻烦
指令列表
git subtree add   --prefix=<prefix> <commit>
git subtree add   --prefix=<prefix> <repository> <ref>
git subtree pull  --prefix=<prefix> <repository> <ref>
git subtree push  --prefix=<prefix> <repository> <ref>
git subtree merge --prefix=<prefix> <commit>
git subtree split --prefix=<prefix> [OPTIONS] [<commit>]

几条指令而已,再复杂也只有这么几条,所以相对于他的优点来说,上面说的缺点也就只是微乎其微了

操作说明


在码云上面创建了三个仓库用于做测试:praent(主仓库), childa、childb(子仓库)

  • 引入子仓库

    git remote add -f <仓库别名> <仓库地址>
    #如 git remote add -f childa https://gitee.com/pengfeilu/subtree-childa.git
    

    这条指令不是git subtree的指令,只是为了方便后续的操作,把仓库引入到当前项目作为一个remote,并且给其取了个别名,后续的操作 childa = https://gitee.com/pengfeilu/subtree-childa.git


  • 添加子仓库
    git subtree add --prefix=<prefix> <repository> <ref>
    #如: git subtree add --prefix=childa childa master --squash
    #等价于: git subtree add --prefix=childa https://gitee.com/pengfeilu/subtree-childa.git master --squash
    
  • 第一个参数 --prefix=modulea
    指明子仓库放在父仓库存放的路径,--prefix可以使用大写的-P简写;这里是放在childa目录,也允许设置多级目录,如childa/a/b/c
  • 第二个参数 modulea
    子远程仓库地址,由于上面一个做了关联,所以这里直接使用的别名,直接使用远端地址也是可以的
  • 第三个参数 master : 添加的子仓库的分支名称,这里使用标签或者commitId也是可以的
  • 第四个参数 --squash: 只将本次操作在主仓库生成一条commit记录,子仓库的历史记录并不会合并进来,可以根据实际情况使用

  • 推送更新到子仓库
    git subtree push  --prefix=<prefix> <repository> <ref>
    #如:git subtree push  --prefix=childa childa master
    #等价于: git subtree push  --prefix=childa https://gitee.com/pengfeilu/subtree-childa.git master
    

    参数说明等价于上面添加的参数


  • 更新子仓库代码
    git subtree pull  --prefix=<prefix> <repository> <ref>
    #如:git subtree pull  --prefix=childa childa master --squash
    #等价于: git subtree pull  --prefix=childa https://gitee.com/pengfeilu/subtree-childa.git master --squash
    
    测试:
    1. 子仓库childa添加文件并上传
    2. 主仓库基于分支获取最新的 childa的提交

  • 对已有的项目目录进行拆分
    以上的操作是我们从一开始就考虑好那一部分是子仓库,从一开始就将子仓库定义好了,这种场景比如在RPC(thrift、grpc等)相关框架自动生成的代码,那么这个子仓库就是用于保存自动生成的那部分代码,而且从一开始就有了,客户端和服务端直接引用就好了;但是业务开发,可能会出现做到一半,发现某一部分可以抽离出来作为一个公共的子模块,那该怎么做呢?
    git subtree split --prefix=<prefix> [OPTIONS] [<commit>]
    
    如当前我的项目下有个文件夹myfile,我需要将其剥离成一个新的子项目childb
  1. 第一步,将myfile目录剥离成一个新的分支
     git subtree split -P myfiles -b childb
    
  2. 在主项目的同级目录创建一个用于保存这个分支的文件夹
    # 创建文件夹
    mkdir ../subtree-childb
    # 切到对应的文件夹
    cd ../subtree-childb/
    # 初始化成一个git仓库
    git init
    
  3. 将剥离出来的分支并到当前目录来
     # ../subtree-praent 为主仓库的路径
     # childb 为第一步剥离出来的分支名称
     git pull ../subtree-praent childb
    
    
  4. 将新的仓库关联到远端仓库
    git remote add origin https://gitee.com/pengfeilu/subtree-childb.git
    
  5. 推送到远端代码
    git push -u origin  master
    

到此!git subtree的常规操作都覆盖了,具体可以在实际使用中去体会!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一行Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值