1. 关于repo
repo是Google开发的用于管理Android版本库的一个工具。repo并不是用来取代Git,而是用Python对Git进行了一定的封装,简化了对多个Git版本库的管理。对应repo管理的任何一个版本库,都需要使用Git命令进行操作。
repo的使用过程大致如下:
l 运行repo init命令,克隆Android的一个清单库。这个清单库是通过XML技术建立的版本库清单。
l 清单库中的manifest.xml文件,列出了几百个多个版本库的克隆方式。包括版本库的地址和工作区地址的对应关系,以及分支的对应关系。
l 运行repo sync命令,开始同步,即分别克隆这几百个版本库到本地的工作区。
l 同时对这几百个版本库执行切换分支操作,切换到某个分支。
首先下载repo的引导脚本,可以使用wget、curl甚至浏览器从指定网址下载(当前有效网址:http://php.webtutor.pl/en/wp-content/uploads/2011/09/repo ) 上下载。把repo脚本设置为可执行,并复制到只执行的路径中。
由于原站点被黑,当前一下网址是有效的:
1、http://php.webtutor.pl/en/2011/09/05/kernel-org-hacked-how-to-get-android-repo/
2、https://www.codeaurora.org/gitweb/quic/la/
$ curl -L -k http://php.webtutor.pl/en/wp-content/uploads/2011/09/repo> ~/bin/repo
$ chmod a+x ~/bin/repo
$ export PATH=~/bin:$PATH
这里下载的repo只是一个引导脚本,repo的大部分功能代码不在其中,这个repo脚本只是一个帮助完成整个repo程序继续下载和加载的工具。
2. repo和清单库
下载并保存repo引导脚本后,建立一个工作目录。在工作目录中执行repo init -u <url> <option>,完成repo完整的下载及项目清单版本库(manifest.git)的下载。
$ mkdir workspace
$ cd workspace
$ repo init -ugit://android.git.kernel.org/platform/manifest.git
在repo引导脚本的前几行,定义了默认的repo.git的版本库位置及要检出的默认分支。
REPO_URL = ‘git://android.git.kernel.org/tools/repo.git’
REPO_REV = ‘stable
repo脚本有如下可用参数:
--repo-url 设定repo的版本库地址。
--repo-branch 设定需要检出的分支。
--no-repo-verify 设定不要对repo的里程碑签名进行严格的验证。
-u(--manifest-url) 设定清单库的Git服务器地址。
-b(--manifest-branch) 检出清单库的特定分支。
--mirror 只在repo第一次初始化的时候使用,建立本地镜像
-m(--manifest-name) 当有多个清单文件时,指定清单库中的某个清单为有效的清单文件。默认为default.xml。
执行完repo init之后,工作目录就已经包含了一个.repo的隐藏目录。在该目录下除了一个包含repo实现的repo克隆库外,就是manifest库的克隆,已经一个符号链接,链接到清单库中的default.xml文件。
下面是我的PC上的.repo目录
(repo init -u ssh://webgod@10.203.121.96/home/webgod/N2S/Fxn-DT/manifests.git-m baseline之后的)
在工作目录下的.repo/manifest.xml文件就是Android项目的众多版本库的清单文件。repo命令的操作都要参考这个清单文件。
Ø 这个XML的顶级元素是manifest,位于第2行和第554行。
Ø 第3行通过一个remote元素,定义了名为”ldc-gerrit”的远程版本库,其Git库的基址为”.”,即ssh://webgod@10.203.121.96/home/webgod/N2S/Fxn-DT/。还定义了代码审核服务器的地址ldc-gerrit.googltcode.com。当然,还可以定义更多的remote元素。
Ø 第4行用于设置各个项目默认的远程版本库(remote)为ldc-gerrit,默认的分支为baseline。各个项目(project元素)可以定义自己的remote和revision覆盖该默认配置。
Ø 第5行定义了一个项目,该项目的远程版本库相对路径为:a/aosp/device/asus/deb,在工作区目录中克隆的位置为:device/asus/deb。
Ø 第34行,定义了project元素的子元素copyfile,定义了项目克隆后的一个附加动作:从core/root.mk拷贝文件到Makefile。
Ø 后续的500多行定义了其他500多个项目,都是采用类似的project元素语法。name参数定义远程版本库的相对路径,path参数帝国一克隆到本地工作区的路径。
3. 同步项目
同步项目的全部内容:
$ repo sync
同步项目中某部分:
$ repo sync [project]
在repo sync后面跟上项目的名称,项目的名称来自于.repo/manifest.xml这个XML文件中project元素的name属性值。
repo支持通过本地清单对默认的清单文件进行补充及覆盖。
4. repo的命令集
repo子命令实际上是Git命令的或简单或复杂的封装。每一个repo子命令都对应于repo源码树中subcmds目录下的一个同名的Python文件。每一个repo子命令都可以通过下面的命令获得帮助。
$ repo help <command>
1) repo init
完成检出清单版本库(manifest.git),以及配置Git用户的用户名和邮件地址的工作。
2) repo sync
参照清单文件克隆或同步版本库。
3) repo start
实际上是对git checkout -b命令的封装。为指定的项目或所有项目(使用--all参数),以清单文件中为项目设定的分支或里程碑为基础,创建特性分支。
repo start <newbranchname> [--all|<project>…]
4) repo status
实际上是对git diff-index、gitdiff-files命令的封装,同时显示暂存区的状态和本地文件修改的状态。
repo statuc [<project>…]
5) repo checkout
实际上是对git checkout命令的封装。检出之前由repostart创建的分支。
repo checkout <branchname> [<project>…]
6) repo branches
repo branches读取各个项目的分支列表并汇总显示。该命令实际上通过直接读取.git/refs目录下的引用来获取分支列表,以及分支的发布状态等。
repo branches [<project>…]
7) repo diff
实际上是对git diff命令的封装,用于分别显示各个项目工作区下的文件差异。
repo diff [<project>…]
8) repo stage
实际上是读git add--interactive命令的封装,用于挑选各个项目工作区中的改动(修改、添加等)以加入暂存区。
repo stage -I [<project>…]
9) repo upload
相当于git push
10) repo download
用于代码审核者下载和评估贡献者提交的修订。
repo download {project change [/patchset]}…
11) repo rebase
12) repo prune
该命令用于扫描项目的各个分支,并删除已经合并的分支。
repo prune [<project>…]
13) 其他命令
repo grep
repo smartsync
repo forall
repo manifest
repo version
repo selfupdate
5. repo命令的工作流
下图是repo的工作流,每个代码贡献者都起始于repo start创建的本地工作分支,最终都以repo upload命令将代码补丁发布到代码审核服务器。