来历
repo 是 Google 为了管理 Android 源码开发的一个小工具,由于 Android 代码量巨大,目前有接近 800 个git 仓储,为了高效管理如此庞大的工程,Google 开发了 repo 工具。现在这个工具可以应用到各自领域,来管理多个 git 仓储组合起来的代码工程。
补充一个知识点
有repo,就必现有 manifest,manifest 是多个 git 仓储的配置文件,repo 通过解析 manifest 里面的内容,来同步代码,下面是一个简单的 manifest 示例,帮助大家理解manifest 里面的内容:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<!-- 这里指定每个 git 仓储的 remote 是 aosp,默认 code review 地址是 https://android-review.googlesource.com -->
<remote name="aosp" fetch=".." review="https://android-review.googlesource.com/" />
<!-- 这里指定每个使用 aosp 作为 remote 的 git 仓储默认同步的分支是 refs/tags/android-11.0.0_r45,repo sync 时默认是 4 线程并行同步 -->
<default revision="refs/tags/android-11.0.0_r45" remote="aosp" sync-j="4" />
<superproject name="platform/superproject" remote="aosp"/>
<contactinfo bugurl="go/repo-bug" />
<!-- 这里的 path 是指定代码实际存放的目录位置,name 是 git 仓储的名字,group 是这部分代码所属的组,repo 可以根据组别来决定处理规则 -->
<project path="build/make" name="platform/build" groups="pdk" >
<!-- 这里的 copyfile 和 linkfile 是指,在这个仓储代码同步完成后的后续动作,可以复制文件到目标位置,或者链接文件 -->
<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>
...
<!-- repo-hooks 是一个比较有趣的新功能,可以在 repo 某个指令执行时出发另外要给动作,比如 repo upload 执行时,触发代码检查工具来检查代码 -->
<repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" />
</manifest>
更详细的 manifest 说明,可以参考:
https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.md
常用指令
下载工具
$ mkdir ~/bin
$ echoPATH=~/bin:$PATH
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
# 如果上述 URL 不可访问,可以用下面的:
# curl -sSL 'https://gerrit-googlesource.proxy.ustclug.org/git-repo/+/master/repo?format=TEXT' |base64 -d > ~/bin/repo
$ chmod a+x ~/bin/repo
基础指令 - 以同步清华镜像为例
# repo init - 初始化 manifest
$ mkdir android-aosp
$ cd android-aosp
$ repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest
# 还可以同步添加 -b 和 -m 来指定 manifest-git 的分支以及具体的manifest,例如:
$ repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-10.0.1_r1 -m android-stable.xml
# repo sync - 同步代码
$ repo sync
# repo branch - 查看每个 git 仓储当前分支
$ repo branch
# repo start [branch-name] --all - 为所有的 git 仓储创建分支
$ repo start mydev --all
# repo status - 查看所有 git 仓储的状态,类似遍历每个 git 仓储,并执行 git status
$ repo status
高级指令 repo forall - 对于代码管理工作会非常有帮助
# repo forall - 对每个 git 仓储执行指令。
# -c 执行一个指令
$ repo forall -c 'git diff'
# -p 打印当前 git 仓储的路径
$ repo forall -p -c ‘git diff'
# -v 打印指令执行过程中是否报错
$ repo forall -p -v -c 'git diff'
# 或者如下
$ repo forall -pvc 'git diff'
# 这个指令通常在规模化 merge 代码时使用,我经常这么用
$ repo forall -pvc 'git merge remotes/aosp/androidxxx'
$ repo forall -pvc 'git push $REPO_REMOTE HEAD:$REPO_RREV'
# 还可以更牛,为每个远程仓储推送分支
$ repo forall -pv -c 'git push --no-thin ssh://xxgerrit/`var=$REPO_PROJECT;echo ${var#*/}` HEAD:refs/heads/androidxxx'