对于Android系统这种超大型项目,一般都会将其拆分为很多个git仓库进行管理(多达几百个)。如果这个时候还单一使用Git管理将会非常耗时,因此现在管理Android系统项目用的是repo工具。repo是一种使用python语言构建的基于git的仓库管理工具,可以批量且有效的组织众多的git仓库。
1. 下载并配置repo工具(掌握)
sun@ubuntu:~$ curl https://storage.googleapis.com/git-repo-downloads/repo > /bin/repo
sun@ubuntu:~$ chmod a+x /bin/repo
2. 下载Android源码步骤(掌握)
以AOSP(Android Open Source Project)的Android9为例
2.1 初始化repo
sun@ubuntu:~/projects/AOSP4$ repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-9.0.0_r9 --repo-url=https://aosp.tuna.tsinghua.edu.cn/git-repo
2.2 同步源码到本地
sun@ubuntu:~$ repo sync -c
...
...
正在检出文件: 100% (4084/4084), 完成.prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9正在检出文件: 0% (14/4084)
正在检出文件: 100% (10157/10157), 完成.
正在检出文件: 100% (1150/1150), 完成.
Checking out: 100% (668/668), done in 19m37.235s
repo sync has finished successfully.
3 下载源码过程解析(了解)
这部分有时间可以进行了解,内容较多。
3.1 repo init
3.1.1 常用选项
-u: 指定项目清单库的url地址 -m: 指定使用哪个项目清单文件 -b: 指定具体的分支,默认情况下指定master分支 –repo-url: 指定repo库的url地址 –config-name: 指定访问服务器的用户名和邮箱。这个选项后面不接内容,运行的时候会提示你输入用户名和邮箱
3.1.2 主要作用
repo init主要有两部分工作:下载两个git管理的仓库(repo库和manifest库) repo库: 主要存放一些python脚本,配合之前说的repo脚本来共同管理众多源码仓库 manifest库: 项目清单库,用来管理各个版本的清单文件 完成后AOSP目录的会出现一个.repo 的隐藏文件夹,文件夹结构如下:
sun@sun-pc:~/project/AOSP4/.repo$ ll
总用量 24
drwxrwxr-x 5 sun sun 4096 1月 18 15:23 ./
drwxrwxr-x 3 sun sun 4096 1月 18 15:22 ../
drwxrwxr-x 2 sun sun 4096 1月 18 15:23 manifests/
drwxrwxr-x 8 sun sun 4096 1月 18 15:23 manifests.git/
-rw-rw-r-- 1 sun sun 500 1月 18 15:23 manifest.xml
drwxrwxr-x 11 sun sun 4096 1月 18 15:23 repo/
3.1.3 解析repo init产生的内容
此时AOSP根目录下还没有代码,只有.repo目录中有所变化。
3.1.3.1 manifests
这个文件夹是由3.1.3.2所说的manifests.git进行维护的。文件夹中包含该分支(android-9.0.0_r9)的项目清单文件(AOSP目前每个分支下只维护default.xml这一个清单)
sun@sun-pc:~/project/AOSP/.repo/manifests$ git branch -avv
* default d69a58cdc [origin/android-9.0.0_r9] Manifest for Android 9.0.0 Release 9
remotes/origin/android-10.0.0_r1 151c2f061 Manifest for Android 10.0.0 release 1
remotes/origin/android-10.0.0_r10 e3bacc7b4 Manifest for Android 10.0.0 Release 10
...
sun@sun-pc:~/project/AOSP/.repo/manifests$ ls
default.xml GLOBAL-PREUPLOAD.cfg
sun@sun-pc:~/project/SIM8000/.repo/manifests$ git branch -avv
* default 0427dac [origin/master] SIM8000_PHONE.xml
remotes/m/master -> origin/master
remotes/origin/master 0427dac SIM8000_PHONE.xml
sun@sun-pc:~/project/SIM8000/.repo/manifests$ ls
SIM8000_PHONE.xml SIM8000_AUTOMOTIVE.xml SIM8000_TV.xml SIM8000_POS.xml
截取一部分default.xml的内容进行分析:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote name="aosp"
fetch=".."
review="https://android-review.googlesource.com/" />
<default revision="refs/tags/android-9.0.0_r9"
remote="aosp"
sync-j="4" />
<project path="build/make" name="platform/build" groups="pdk" >
<copyfile src="core/root.mk" dest="Makefile" />
<linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
<linkfile src="buildspec.mk.default" dest="build/buildspec.mk.default" />
<linkfile src="core" dest="build/core" />
<linkfile src="envsetup.sh" dest="build/envsetup.sh" />
<linkfile src="target" dest="build/target" />
<linkfile src="tools" dest="build/tools" />
</project>
<project path="build/blueprint" name="platform/build/blueprint" groups="pdk,tradefed" />
<project path="build/kati" name="platform/build/kati" groups="pdk,tradefed" />
<project path="build/soong" name="platform/build/soong" groups="pdk,tradefed" >
<linkfile src="root.bp" dest="Android.bp" />
<linkfile src="bootstrap.bash" dest="bootstrap.bash" />
</project>
<project path="art" name="platform/art" groups="pdk" />
<project path="bionic" name="platform/bionic" groups="pdk" />
● remote标签: 包含一些远程仓库的一些信息 (1) name:远程仓库在本地的别名,可以理解为讲解git仓库时提到的origin (2) fetch:项目名称的前缘,在构造项目仓库远程地址时使用到 (3) review:code review的服务器地址
● default标签: 默认标签,下面的<project>标签会默认包含这个标签的属性,当然也可以在<project>里重新更改这几个属性 (1) revision:repo init -b的时候指定的分支或tag,默认是master分支。当然如果直接在manifests里切换分支并git pull,这里也会相应改变。 (2) remote:对应上面的<remote>标签的名字 (3) sync-j:指定同步工作的并行数量,个人理解最大数不宜超过cpu的线程数 (4) sync-c:【sync-c=“true”】代表repo sync的时候只同步revision指定的分支或tag
● project标签: 每个<project>标签指定的都是一个git管理的源码库 (1) path:源码库下载后存放的本地路径 (2) name:远程仓库的名称
3.1.3.2 manifests.git
这其实就是一个正常的git库,用来管理上面说的项目清单文件(比如上面的default.xml),查看里边的refs 文件夹
sun@ubuntu:~/projects/AOSP/.repo/manifests.git/refs$ ls -l
总用量 84
drwxrwxr-x 5 sun sun 4096 1月 19 16:40 ./
drwxrwxr-x 8 sun sun 4096 1月 19 16:40 ../
drwxrwxr-x 2 sun sun 4096 1月 19 16:40 heads/
drwxrwxr-x 3 sun sun 4096 1月 19 16:40 remotes/
drwxrwxr-x 2 sun sun 69632 1月 19 16:40 tags/
heads目录分析
sun@ubuntu:~/projects/AOSP/.repo/manifests.git/refs/heads$ ls
default
remotes目录分析
sun@ubuntu:~/projects/AOSP/.repo/manifests.git/refs/remotes$ ls
origin
sun@ubuntu:~/projects/AOSP/.repo/manifests.git/refs/remotes/origin$ ls -l
总用量 6904
drwxrwxr-x 2 sun sun 69632 1月 19 16:40 ./
drwxrwxr-x 3 sun sun 4096 1月 19 16:40 ../
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 adt_23.0.3
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 afw-test-harness-1.5
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 afw-test-harness-2.1
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 afw-test-harness-marshmallow-dev
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 afw-test-harness-nougat-dev
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 android-10.0.0_r1
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 android-10.0.0_r10
...
tags目录分析 和上面remotes/origin里的内容差不多,只不过这里保存的是tags的id
sun@ubuntu:~/projects/AOSP/.repo/manifests.git/refs/tags$ ls -l
总用量 5408
drwxrwxr-x 2 sun sun 69632 1月 19 16:40 ./
drwxrwxr-x 5 sun sun 4096 1月 19 16:40 ../
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 adt_23.0.3
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 afw-test-harness-1.5
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 afw-test-harness-2.1
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 android-10.0.0_r1
-rw-rw-r-- 1 sun sun 41 1月 19 16:40 android-10.0.0_r10
...
3.1.3.3 manifest.xml
在repo同步源码仓库的时候是通过该文件间接的访问manifests里的清单的 AOSP: 如下图所示,直接包含目标清单 实际开发: 如下所示,这个文件也会做成链接文件,链接到manifests里的某个清单。
sun@sun-pc:~/project/SIM8971_AP/.repo$ ll
总用量 104
drwxrwxr-x 7 sun sun 4096 12月 14 02:24 ./
drwxrwxr-x 32 sun sun 4096 1月 25 09:08 ../
drwxrwxr-x 3 sun sun 4096 1月 21 11:04 manifests/
drwxrwxr-x 10 sun sun 4096 12月 14 00:36 manifests.git/
lrwxrwxrwx 1 sun sun 28 12月 14 00:36 manifest.xml -> manifests/SIM8500_PHONE.xml*
-rw-rw-r-- 1 sun sun 17394 1月 24 17:56 project.list
drwxrwxr-x 3 sun sun 4096 12月 14 00:36 project-objects/
drwxrwxr-x 29 sun sun 4096 12月 14 02:19 projects/
drwxrwxr-x 7 sun sun 4096 12月 14 00:25 repo/
3.1.3.4 repo
这个就是前边说的repo库,存放一些python脚本等,与文章开头下载的repo脚本一起组成了完整的repo工具,从而管理众多源码库。
3.2 repo sync
3.2.1 常用选项
-j: 指定sync工作的并行数,最大应不超过cpu核心线程数 -c: 只同步指定的远程分支,默认会同步所有的源码分支,如下所示
sun@sun-pc:~/project/AOSP/art$ git branch -av
remotes/aosp/android-s-beta-4 9e050ab1a0 Remove the need of VerifiedMethod in the compiler.
remotes/aosp/android-s-beta-5 7306984909 Snap for 7670480 from 8d44c3d61d4bde412f06190cd4acc4afc2ea469c to sc-beta5-release
...
remotes/m/android-9.0.0_r9 -> android-9.0.0_r9
* (非分支) b151df3511 Snap for 4829593 from f0e3a368c80b7d32e2f85ffa948751525a9f903b to pi-release
sun@sun-pc:~/project/AOSP2/art$ git branch -av
remotes/m/android-9.0.0_r9 -> android-9.0.0_r9
* (非分支) b151df3511 Snap for 4829593 from f0e3a368c80b7d32e2f85ffa948751525a9f903b to pi-release
一般情况直接repo sync就可以同步源码了,不过也可以指定仓库进行同步:
sun@sun-pc:~/project/AOSP$ repo sync platform/art
3.2.2 主要作用
就是同步repo init所指定的代码,几十个G的东西,时间还是挺久的。
sun@sun-pc:~/project/AOSP2$ ./repo sync -c -j16
Fetching: 100% (668/668), done in 1h6m18.282s
Garbage collecting: 100% (668/668), done in 4.875s
正在检出文件: 100% (87/87), 完成.
正在检出文件: 100% (184/184), 完成.
正在检出文件: 100% (378/378), 完成.
...
正在检出文件: 100% (4084/4084), 完成.
正在检出文件: 100% (10157/10157), 完成.
正在检出文件: 100% (1150/1150), 完成.
Checking out: 100% (668/668), done in 11m44.738s
repo sync has finished successfully.
完成后,AOSP目录下就有代码了,再来看一下.repo目录的变化
sun@sun-pc:~/project/AOSP/.repo$ ll
总用量 92
drwxrwxr-x 7 sun sun 4096 2月 8 10:57 ./
drwxrwxr-x 28 sun sun 4096 2月 8 11:09 ../
-rw-rw-r-- 1 sun sun 190 2月 8 10:57 copy-link-files.json
drwxrwxr-x 2 sun sun 4096 2月 8 09:50 manifests/
drwxrwxr-x 8 sun sun 4096 2月 8 11:09 manifests.git/
-rw-rw-r-- 1 sun sun 500 2月 8 09:50 manifest.xml
-rw-rw-r-- 1 sun sun 14975 2月 8 10:57 project.list
drwxrwxr-x 6 sun sun 4096 2月 8 10:27 project-objects/
drwxrwxr-x 27 sun sun 4096 2月 8 10:48 projects/
drwxrwxr-x 11 sun sun 4096 2月 8 09:50 repo/
-rw-rw-r-- 1 sun sun 36965 2月 8 10:57 .repo_fetchtimes.json
3.2.3 解析repo sync产生的内容
依次讲解一下.repo新增内容
3.2.3.1 copy-link-files.json
此json文件记录了一些项目中的链接文件
3.2.3.2 project.list
依据清单文件每个项目的path属性,所生成的本地路径记录。 如果将清单文件中某个仓库的path属性改变后进行repo sync,那么同步下来的代码位置在本地也会有相应改动,而且此文件的内容也会有相应变化。
3.2.3.3 projects和project-objects
这两个目录用于存放所有git仓库的提交记录,以及各个分支和标签的信息等,可以从目录结构看出他们的关系: ● 源码目录(以art仓库为例):
sun@sun-pc:~/project/AOSP/art$ ll
总用量 228
drwxrwxr-x 29 sun sun 4096 2月 8 18:09 ./
drwxrwxr-x 28 sun sun 4096 2月 8 18:09 ../
drwxrwxr-x 2 sun sun 4096 2月 8 18:09 adbconnection/
...
lrwxrwxrwx 1 sun sun 25 2月 8 18:09 .git -> ../.repo/projects/art.git/
...
● projects目录:
sun@sun-pc:~/project/AOSP/.repo/projects/art.git$ ll
总用量 1124
drwxrwxr-x 6 sun sun 4096 2月 8 18:09 ./
drwxrwxr-x 27 sun sun 4096 2月 8 18:10 ../
drwxrwxr-x 2 sun sun 4096 2月 8 09:50 branches/
-rw-rw-r-- 1 sun sun 430 2月 8 10:57 config
-rw-rw-r-- 1 sun sun 73 2月 8 09:50 description
-rw-rw-r-- 1 sun sun 185814 2月 8 18:09 FETCH_HEAD
-rw-rw-r-- 1 sun sun 41 2月 8 18:09 HEAD
lrwxrwxrwx 1 sun sun 44 2月 8 09:50 hooks -> ../../project-objects/platform/art.git/hooks/
-rw-rw-r-- 1 sun sun 920330 2月 8 18:09 index
drwxrwxr-x 2 sun sun 4096 2月 8 09:50 info/
drwxrwxr-x 3 sun sun 4096 2月 8 09:56 logs/
lrwxrwxrwx 1 sun sun 46 2月 8 09:50 objects -> ../../project-objects/platform/art.git/objects/
drwxrwxr-x 5 sun sun 4096 2月 8 09:56 refs/
-rw-rw-r-- 1 sun sun 640 2月 8 10:57 .repo_config.json
lrwxrwxrwx 1 sun sun 47 2月 8 09:50 rr-cache -> ../../project-objects/platform/art.git/rr-cache/
● project-objects目录:
sun@sun-pc:~/project/AOSP/.repo/project-objects/platform/art.git$ ll
总用量 44
drwxrwxr-x 8 sun sun 4096 2月 8 09:50 ./
drwxrwxr-x 25 sun sun 4096 2月 8 10:48 ../
drwxrwxr-x 2 sun sun 4096 2月 8 09:50 branches/
-rw-rw-r-- 1 sun sun 66 2月 8 09:50 config
-rw-rw-r-- 1 sun sun 73 2月 8 09:50 description
-rw-rw-r-- 1 sun sun 23 2月 8 09:50 HEAD
drwxrwxr-x 2 sun sun 4096 2月 8 09:50 hooks/
drwxrwxr-x 2 sun sun 4096 2月 8 09:50 info/
drwxrwxr-x 4 sun sun 4096 2月 8 09:50 objects/
drwxrwxr-x 4 sun sun 4096 2月 8 09:50 refs/
drwxrwxr-x 2 sun sun 4096 2月 8 09:50 rr-cache/
注:上面这些结构大体上和git仓库的结构是一样的,其中具体的意义对于普通开发并不是很重要,如果后续有时间我在补上。
3.2.3.4 .repo_fetchtimes.json
此文件会记录上次执行repo sync所获取目标仓库源码的时间
{
"platform/build": 0.32880017161369324,
"platform/build/blueprint": 0.3119065761566162,
"platform/art": 0.3138986825942993,
"platform/bionic": 0.3228146731853485,
...
}
4. repo常用命令补充
4.1 对每个git仓库执行相同的shell命令
用法:
repo forall -c "命令"
举例:恢复用repo管理的Android系统源码
repo forall -c "git clean -df" && repo forall -c "git checkout ."
4.2 帮助命令
用法:
repo help 命令选项
举例:查看repo forall的使用帮助
repo help forall
5. 后记
这篇文章真的是写了好久,是结合了各位大神以及自己实践得到的结果,其中也加入了一些自己在工作中的理解。毕竟水平有限,如有不足之处,还请不吝赐教。
|