开发者学堂课程【Git从入门到进阶:Git的十年变化(三)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1194/detail/18117
Git的十年变化(三)
内容介绍:
一、使用 Git filer-repo 拆分一个已有的仓库
二、用 submodule 管理多仓库
三、repo工具管理多仓库
一、使用 Git filter-repo 拆分一个已有的仓库
1. 在Git中使用 Git filter-repo 拆分原仓库将主仓库分为三个部分——车身仓库,车轮仓库,主仓库。
如果将仓库的管理比作汽车生产的流水线,汽车的流水线生产分为两个步骤,一个是车身的生产,一个是车轮的生存,在 Git 中可以通过魔法工具 Git filter-repo 来实现。该工具可以去 github 上查询。Git filtre-rep 的目的是将主仓库分为车身部分和车轮部分以及主仓库三个部分。
cd car
tree //克隆仓库,可看到仓库的目录组成,主要是一个组合的一个文件以及两个子模块的文件夹
gcc body/body.c wheel/.c car.c-o car//通过编译可以得到仓库,其内容主要是得到一辆汽车,得知车身和车轮的型号和颜色
./car
clear
cd . .
rm-rf car
git clone git@codeup.aliyun.co:agit/car.git--bare git-car-body 克隆到纯仓库 ‘giti-car-body 克隆到纯仓库 ’git-car-body//因为要将车身和车轮分离出来,所以将原仓库单独的克隆到两个不同的目录,使用--bare 在裸仓库中进行全分支的改动,避免远端分支
git clone git@codeup.aliyun.com:agit/car.git--bare gir-car-wheel克隆到纯仓库 ’git-car-wheel’...
cd git-car-body
tree .//裸仓库的内容一般不像检出(checkou)空间或者是工作区域(work-tree)的内容
cd . .
git clone git-car-body gcb//在裸仓库中用正常的克隆命令进行克隆,可以看到带有工作区的内容
cd gcb
tree .
cd . .
rm-rf gcb
cd git-car-body
git filter-repo--path body//通过 git filter 的 --path 的命令,其后跟上想要保留的文件夹就能得到使用者的目的,即保留车身部分
cd . .
以下是验证
git clone git-car-body gcb//裸仓库克隆
tree . //通过 tree 命令看到工作区域的数据只剩下车身的内容
j wo
通过以上程序,可以对车轮以及子仓库做一些操作
二、用 submodule 管理多仓库
通过前面的程序得到两个独立的子仓库:一个是车身,另一个是车轮
Git clone git@codeup.aliyun.com:agit/car-factory-submodule.git//克隆 super project 中文名叫主仓库
cd car-factory-submodule
tree.//现在主仓库里面只有一个主文件和一个 readme 的两个比较单一的文件
git submodule add git@codeup.sliyun.com:agit/git-car-body.git car-body-factory//通过 git submodule add 为主仓库添加一个子模组,这个子模组的内容就是子仓库的一个路径,以及子模组在主仓库里面存在的一个路径
tree .//回车之后子仓库的内容克隆到子模组里面
git status//通过 git status 看到两个改动,即产生了一个 gitmodules 文件,另一个是新文件 car body factory 而非文件夹
bat.gitmodules//gitmodules 的内容主要包含三个部分,一个是 submodule 子模组的名字,第二个是子模组在仓库里面相对路径,第三个是URL即子模组对应的仓库的地址。
1.利用 git add 或者 git add-p 探究子模组的内容
通过对象查找方式探究 car body factor 为什么是新文件而不是文件夹
git add .
git add-p//利用 git add 或者 git add-p 探究子模组的内容
git status//通过 git status 可以看到新文件: .gitmodules 和新文件: car--body-factory 已经add过,所以直接 commit 提交
git commit -m’add car body factory project’
git --no-pager log -n 1//通过 git log 去查找 commit ,通过加上--no-pagers可以制止翻页
git cat-file-p//得到 commit id 之后,通过 git cat-file-p看到内容
git cat-file -p//可以看到 car body factory 其实既不是一个 bold 也不是一个 tree 而指向的是一个 commit 而这个 commit 的ID和 gir car body 仓库的最新的主分支上的 commit 是一样的,所以子仓库里面不会存放子仓库的内容而是存放子仓库内容的一个指针指向,这对于数据安全体系来说有好处
cd../git-car-body
git --no-pager log -n 1
2.查找子模组的版本信息
git clone
git@codeup.aliyun.com:agit/car-factory-submodule.git new-car-factory-submodule//克隆一个新的主仓库
cd new-car-factory-submodule
tree .
ls
cd car-body-factory
s
ls//第一次用正常的克隆只会克隆两个子的目录以及对应的一个版本
ls-al
cd ..
tree .//通过 tree 可以看到两个文件夹
git submodule status//通过 gitmodules 只能看到简单的URL,
git module 里提供了一个 git submodule status 的方式看到指向
的 commit ID 通过这种方式去查找子模组的版本信息。用 status
看到两个 commit ID 是带着减号的,因为这两个子模组在没有注册
的情况下默认是未激活状态
git submodule init car-body-factory//通过 git submodules-- init 加上子模组的名字,为子模组进行注册,注册之后对此子模组进行一些文件级的更新等操作
tree .git//实际上 init操作只是将子模组的一些仓库的信息注册到主仓库的.git/config 里面,这样后续操作一些 git 命令的时候才能操作到子模组,这些操作主要是数据更新git status。
3.更新子模组
首先将两个子模组都进行一个 init 再通过 git submodule status 看到两个子模组都是未检出的状态
git submodule update//通过 git submodule update 做数据的检出,这时提示 factory 已经检出到了 commit
tree .git//通过 tree 看到git仓库里面的文件数变多,因为已经将子模组仓库完整的克隆到了主仓库里面
git submodule init car-wheel-factory//将车轮子模组进行初始化和检出
git submodule update//init 和 update 是静态操作用于拉取仓库里面已经更新配置的一些数据
4.修改子模组的一个最终分支
对子模组的最终分支进行一些修改,首先要在子模组的子仓库里面做一个分支的切换及修改、推送,再回到子仓库里
cd ../new-car-factory-submodule
git submodule set-branch --branch geat/update_car_body_version_2021 car_body_factory//通过 git submodle set-branch --branc 指定最终分支和作用域作用的子模组
git status
bat .gitmodules//通过 git status 看到 .gitmodules已经改动,发现在 car factory 子模组里面已经多了一个 branch 配置,该配置会告诉 modules 这个子模块应该是追踪哪个分支
bat car-body-factory/body/dody.c
git submodule update//通过 git submodule update 发现文件没有改动,因为 git submodules 没有真正的update 就像 git pull 一样,git pull 更新的是本地的
bat car-body-factory/body/body.c
git submodule status
git submodule update --remote//通过 git submodule update 与远端交互,取得远端的配置
bat car-body-fatory/body/body.c
git status//此时发现文件和版本得到对应的更新
git submodule status//git submodule status 对应的commit 已经发生了变化
5.注销子模组
有一种递归模式可以在 git 克隆的时候将所有的子模组都克隆下来,这个方式其实就是在克隆之间加上 --recurse-submodules 该方式会将克隆的操作递归的执行到所有的子模组里去
git submodule deinit//有时仓库加上子模组之后的体积太大通过 deinit 的方式注销子模组的内容
dit submodule status
tree .//将车轮注销掉之后发现其已经是一个未检出的状态且文件已经被删除
三、repo工具管理多仓库
思路:定义一个 manifest 的 XML文件,在XML文件里描述整个仓库路径构造,再填写子仓库,接着用repo工具做一个本地的开发管理过程。
git clone
git@codeup.aliyun.com:agit/car-factory-manitest.gif//先克隆一个 manifest 文件,观察典型的 manifest 的 XML文件里面大概需要的元素,以及这些元素代表的意义
cd car-factory-manifest
tree .//进入 manifest 文件,看到 default.xml文件,default.xml 文件分成了几块分别是 remote 、default 和 project 。default用来管理中央仓库的一些配置信息,包括应该使用的 remote 以及它的并发度,project 管理子仓库的信息,可以在其中定义子仓库的一个路径,path 指子仓库克隆到本地后,通过逻辑组织放置位置,通过简单描述之后可进行多仓库的管理。
asciinema play
mkdir test-local-repo//在本地创建工作目录
cd test-local-repo
git repo init -u//在工作目录中通过 repo init 加上manifest 的远端仓库可以初始化工作目录
is -al
tree .//在工作目录中生成了 .repo 的工具(文件夹),.repo 其实就是后续一些 manifest 和一些原始数据存放地方
git repo sync//通过 git repo sync 直接将manifest定义好的仓库数据直接初始化到本地,看到定义好的 car body 和 wheel factory 被拉到本地
Git repo start --all top/new_version//通过 git repo start 后面加上开发分支的方式创建工作分支来开展工作,加上--all是用来对所有的子仓库创建工作分支。