How does the repo of android source code work ?
.repo
通常情况下, Android 的 .repo
里面有如下内容:
1 2
| $ ls .repo manifests manifests.git manifest.xml project.list project-objects projects repo
|
manifests
manifests
路径是项目 manifest 仓的 git checkout
,其中的 .git
是 manifest.git
的软链接,追踪 repo init --manifest-branch
指定的分支。
1 2 3 4 5 6 7
| .repo$ ls manifests/.git/ config HEAD index logs ORIG_HEAD refs shallow description hooks info objects packed-refs rr-cache svn
.repo$ ls manifests.git/ branches description HEAD info objects refs svn config FETCH_HEAD hooks logs packed-refs rr-cache
|
不管远程分支名字是什么,manifests
的本地分支命名为 default。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| .repo$ cat manifests/.git/HEAD ref: refs/heads/default
.repo$ cat manifests.git/config
[core] repositoryformatversion = 0 filemode = true [filter "lfs"] smudge = git-lfs smudge --skip -- %f [remote "origin"] url = https://<url>/platform/manifest.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "default"] remote = origin merge = refs/heads/<remote_branch_name>
|
manifests.git
manifests.git
是当前项目 manifest
仓的一个没有工作空间的 checkout
,即只 checkout
.git
,追踪repo init --manifest-url
指定的 Git 仓。不能手动修改这部分,如果需要修改的话,可重新运行 repo init
来更新设置。
.repo_config.json
缓存 manifests.git/config
,用来提升 repo
的速度。
manifest.xml
repo
使用的 manifest
, 此文件由 repo init --manifest-name
指定链接到 manifests
中的哪一个文件,如下:
1
| manifest.xml -> manifests/<manifest-name>.xml
|
以 default.xml in Android 为例简单介绍下 manifest 的格式。
详细格式介绍见 repo Manifest Format 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| <?xml version="1.0" encoding="UTF-8"?> <manifest>
<remote name="aosp" fetch=".." review="https://android-review.googlesource.com/" />
<default revision="master" remote="aosp" sync-j="4" />
<manifest-server url="http://android-smartsync.corp.google.com/android.googlesource.com/manifestserver" />
<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/bazel" name="platform/build/bazel" groups="pdk" > <linkfile src="bazel.WORKSPACE" dest="WORKSPACE" /> </project> <project path="build/blueprint" name="platform/build/blueprint" 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" /> ... <project path="tools/treble" name="platform/tools/treble" groups="tools,pdk" /> <project path="tools/trebuchet" name="platform/tools/trebuchet" groups="tools,cts,pdk,pdk-cw-fs,pdk-fs" /> <repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" /> </manifest> ```
## repo hook
[hook](https://android.googlesource.com/platform/tools/repohooks) 主要在允许执行步骤之前(例如在将提交上载到Gerrit之前),运行 linters,检查格式和运行单元测试。
> linter 的维基百科解释是:a tool that analyzes source code to flag programming errors, bugs, stylistic errors, and suspicious constructs.<br/>简单来说就是分析源码,查找问题。
如下是一个 Android 中的使用范例,在战’pre-upload'(即,`repo upload`) 阶段运行名为 ’platform/tools/repohooks‘ 的 hook 。 ```xml <project path="tools/repohooks" name="platform/tools/repohooks" /> <repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" />
|
project.list
repo sync
基于此文件内容增删 projects ,并更新对应的 checkout
工作路径。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| .repo$ more project.list art bionic bootable/bootloader/edk2 bootable/recovery build/blueprint build/kati build/make build/soong cts dalvik developers/build ... device/qcom/common device/qcom/sepolicy ...
|
projects
存放 repo 克隆的 manifest 中指定的所有 project 的 git 仓库,repo 将基于此 git 仓库链接 .git 并创建工作路径,然后 checkout 对应分支,并更新 .repo/project.list。一些 git 将进一步拆分到如下的 project-objects。
1 2 3 4 5 6
| .repo$ ls projects art.git dalvik.git frameworks packages shortcut-fe.git vendor bionic.git developers hardware pdk.git system bootable development.git kernel platform_testing.git test build device libcore.git prebuilts toolchain cts.git external libnativehelper.git sdk.git tools
|
project-objects
可以在多个 git chekcout
中安全共享的 Git 对象,例如,可以将 foo/bar.git 的不同分支 checkout
到 foo/bar-master,foo/bar-release 等, 在 projects 下将为每一个分支创建路径,而 project-objects 下面将会只有一个路径。
1 2
| .repo$ ls project-objects/ abl device kernel platform toolchain
|
repo
完整的 Repo 工具,接收并处理 Repo-Launcher 转发的命令。
1 2 3 4
| $ ls .repo/repo/ color.py command.pyc editor.py error.pyc git_config.py gitc_utils.pyc git_ssh manifest_xml.py pager.pyc project.py pyversion.pyc repoc tests wrapper.py color.pyc COPYING editor.pyc git_command.py git_config.pyc git_refs.py hooks manifest_xml.pyc progress.py project.pyc README.md subcmds trace.py wrapper.pyc command.py docs error.py git_command.pyc gitc_utils.py git_refs.pyc main.py pager.py progress.pyc pyversion.py repo SUBMITTING_PATCHES.md trace.pyc
|