介绍
此repo
非彼repo
。这里的repo
,是指谷歌公司的一款小工具,名字就叫repo
(我承认,这不是一个好名字,Google里面怎么搜都搜不到它的真身)。
解决的问题
有时候,我们需要在一台电脑上克隆很多个代码仓库,编译它们,然后又要把他们作为一个完整的系统来运行。而每一个代码仓库,随时开发的进行,会有很多个不同的分支,或不同的版本(假设版本是以git tag为标记的)。于是,我们经常会犯一个小小的错误,那就是不同的代码仓库之间并不相互兼容,导致编译不能通过,或者运行的时候不能正常工作。对于前者,我们在编译的时候能发现问题;对于后者,可能就不是很方便找到问题原因了。
对于这样的一个问题,我们最简单的方法,是把各个代码仓库的版本信息记录在一个文件里面,然后需要的时候,就对比这个文件的版本信息,来确保系统的完整性。但是,问题又来了,对于这个文件,如果我们也经常修改呢?如何保证这个文件也是正确的呢?那只能把这个文件也管理起来,让它自己也有版本管理。
我们可以自己写一些脚本工具来管理这个版本管理文件,不过,既然已经有repo
这么好的工具了,那我们还是使用它吧!
安装 repo
正常情况下,我们可以这样子安装这个工具:
curl https://storage.googleapis.com/git-repo-downloads/repo > repochmod a+x reposudo mv repo /bin/
我们把它放到/bin/
目录下,这样使用起来更加方便一些。
在众所周知的情况下,额,还是访问我的 GitHub 来安装吧:
git clone https://github.com/one-third-robot/article-007-repo.gitcd article-007-repochmod a+x reposudo mv repo /bin/
用以上指令安装的repo是v2.8版本的,而且我已经把里面的源从google修改成 GitHub 的一个镜像了,于是这个工具就能正常使用了。
repo 初体验
讲解repo
是如何工作之前,我们还是先体验一下吧:
mkdir fsl-yoctocd fsl-yoctorepo init -u https://github.com/one-third-robot/fsl-yocto.git -b dunfell
这时在终端上能看到:
Downloading Repo source from https://github.com/GerritCodeReview/git-reporemote: Finding sources: 100% (7/7)remote: Total 7 (delta 6), reused 7 (delta 6)Unpacking objects: 100% (7/7), 1.76 KiB | 200.00 KiB/s, done.Downloading manifest from https://github.com/one-third-robot/fsl-yocto.gitremote: Enumerating objects: 7, done. remote: Counting objects: 100% (7/7), done. remote: Compressing objects: 100% (6/6), done. remote: Total 7 (delta 1), reused 7 (delta 1), pack-reused 0 Your identity is: [这里是乱码,将就一下,哈哈]If you want to change this, please re-run 'repo init' with --config-namerepo has been initialized in /home/kingsnake/fsl-yocto
这时候,如果我们使用ls
指令查看fsl-yocto
目录下的内容,发现什么也没有。不过,用ls -sl
指令查看,还是发现有一个隐藏的文件夹,叫.repo/
,这里暂时先记一下。
然后,我们运行:
repo sync -j4
这时,就能看到终端一直在滚动了,它正在同步代码仓库。等它完成,再查看一下fsl-yocto
目录下的内容:
fsl-yocto $ tree -L 1.├── meta-freescale├── meta-openembedded└── poky
现在多出了很多文件夹了。然后我们随便进入一个目录,比如meta-freescale
,然后执行git log
指令:
commit 46f54fdc5ad854a22bf759aac7fd65db1d1bb574 (HEAD, yocto/dunfell, m/dunfell)Author: Andrey Zhizhikin Date: Thu Nov 19 18:20:20 2020 +0000 linux-fslc-imx: update to v5.4.78 Kernel repository has been upgraded to v5.4.78 from stable korg. Following upstream commits are included in this version: ......(后面还有很多内容,就不展示了)......
我们又执行指令git remote -v
,可以看到:
yoctohttps://git.yoctoproject.org/git/meta-freescale (fetch)yoctohttps://git.yoctoproject.org/git/meta-freescale (push)
所以,这确实是一个git代码仓库。
最后,我们来看一下动画演示:
工作原理
前面我们说过,repo init
指令运行完之后,会生成一个.repo/
的文件夹,我们看一下里面有什么东西吧:
cd fsl-yocto/.repotree -L 1
我们看到以下内容:
.├── manifests├── manifests.git├── manifest.xml├── project.list├── project-objects├── projects└── repo
我们进入到mainfests
目录下,看到有两个文件以及一个.git
隐藏文件夹:
manifests $ ls -a. .. default.xml .git README.md
说明,这是一个git代码仓库!我们再来看一下这个代码仓库的源地址:
manifests $ git remote -voriginhttps://github.com/one-third-robot/fsl-yocto.git (fetch)originhttps://github.com/one-third-robot/fsl-yocto.git (push)
终于找到了,这就是前面运行repo init
指令时参数-u
后面的git地址。再来看一下defaults.xml
文件的内容吧:
<?xml version="1.0" encoding="UTF-8"?><manifest> <default sync-j="4" revision="dunfell"/> <remote fetch="https://git.yoctoproject.org/git" name="yocto"/> <remote fetch="https://github.com/openembedded" name="oe"/> <project remote="yocto" revision="dunfell" name="poky" path="poky"/> <project remote="yocto" revision="dunfell" name="meta-freescale" path="meta-freescale"/> <project remote="oe" revision="dunfell" name="meta-openembedded" path="meta-openembedded"/> manifest>
对于这个xml
文件,我们也基本上可以看出来,它“指导”了repo
从两个地址克隆了三个代码仓库。
因此,我们可以总结:谷歌repo
工具读取defaults.xml
文件,按照该文件的内容,把多个代码仓库克隆到本地。它有两个具体的步骤。
第一步,初始化文件夹:
repo init -u -b
该指令克隆
这个代码仓库的
分支到
.repo/manifests
目录。这要求这个代码仓库里必须有
defaults.xml
文件。第二步,同步代码仓库:
repo sync -j4
该指令根据
.repo/manifests/defaults.xml
文件,把最终想要的代码仓库克隆到指令目录。
如何写这个defaults.xml
文件呢?请看下一节的讲解。
文件解析:defaults.xml
前面讲了,谷歌repo
工具主要使用defaults.xml
文件。我们详细来讲解一下它的内容:
所有的正文都放在中间:
<?xml version="1.0" encoding="UTF-8"?><manifest> [这里是正文]manifest>
defaults.xml
文件的版本信息:<default sync-j="4" revision="dunfell"/>
这里的
revision="dunfell"
是大的版本号,它可以是任意的字符串,只要便于理解即可。比如,我们的fsl-yocto
这个代码仓库(不是fsl-yocto那个包含了很多git代码仓库的文件夹哦),它的git tree如下:因此,在
master
主分支,这里是revision="master"
。指定代码仓库源地址:
<remote fetch="https://git.yoctoproject.org/git" name="yocto"/><remote fetch="https://github.com/openembedded" name="oe"/>
这两行指定了代码仓库的源地址,并分别给了它们一个别名:
yocto
,oe
。明确代码仓库:
<project remote="yocto" revision="dunfell" name="poky" path="poky"/><project remote="yocto" revision="dunfell" name="meta-freescale" path="meta-freescale"/>
这两行,有四个内容:
remote
:这里为yocto
,即要从https://git.yoctoproject.org/git
这里克隆某个代码仓库;revision
:这里是版本,主要是分支名,应该也可以用git tag的版本,不过有兴趣的小伙伴可以测试一下吧。当然,要确保要克隆的代码仓库是有这个分支或tag标签的。name
:代码仓库的名字。第一行为poky
,因此,完整的git地址为:https://git.yoctoproject.org/git/poky
, 有兴趣的小伙伴可以用git clone
指令来单独克隆它。path
:确定目标目录,比如path="poky"
即确定了把poky
这个代码仓库克隆到当前目录下的poky
目录。
更高级一些的用法,有兴趣的小伙伴可以自行研究哦。
临时修改
实际工作当中,某个代码仓库是在不断开发的,它也是需要一直测试的。按照以上的步骤,我们总是要初始化一个文件夹,再同步,实际上还是挺麻烦的。
不过,还是有点小伎俩,可以要工作稍微简单一些。比如,我们可以直接修改代码仓库的代码,进行测试。我们也可以修改.repo/manifests/defaults.xml
文件里的内容,然后运行repo sync -j4
指令来同步它,再进行测试。对于第二个方法,我们可以测试一下:
我们把meta-freescale
的版本修改为master
,即:
<project remote="yocto" revision="master" name="meta-freescale" path="meta-freescale"/>
我们再运行repo sync -j4
,终端上显示:
Fetching projects: 100% (3/3), done.meta-freescale/: discarding 111 commitsrepo sync has finished successfully.
我们再进入metta-freescale
,运行git log
,我们看到:
commit 5a1b2c22a90a22e8d9d178324451e1c58d01cee7 (HEAD, yocto/master, m/dunfell)Author: Andrey Zhizhikin Date: Tue Nov 24 22:34:37 2020 +0000 linux-fslc-imx: update to v5.4.80 Kernel repository has been upgraded to v5.4.80 from stable korg. Following conflicts were resolved during merge: ---- - arch/arm64/boot/dts/freescale/imx8mn.dtsi: Fix minor merge conflict where commit [8381af1b684c] in stable tree removed one blank line.
总结
好工具还是要用起来。