文档章节

Repo用法详解

鲜鲜
 鲜鲜
发布于 2015/03/03 14:30
字数 2840
阅读 1231
收藏 7

Android 为企业提供一个新的市场,无论大企业,小企业都是处于同一个起跑线上。研究 Android 尤其是 Android 系统核心或者是驱动的开发,首先需要做的就是本地克隆建立一套 Android 版本库管理机制。

Android 使用 Git 作为代码管理工具,开发了 Gerrit 进行代码审核以便更好的对代码进行集中式管理,还开发了 Repo 命令行工具,对 Git 部分命令封装,将 百多个 Git 库有效的进行组织。要想克隆和管理这百多个 Git 库,还真不是一件简单的事情。

在研究 Repo 的过程中,发现很多文档在 Google Group 上,非“翻墙”不可看。非法的事情咱不干,直接阅读 repo 的代码吧。

创建本地 Android 版本库镜像的思路

如果了解了 Repo 的实现,参考 《Using Repo and Git》 , 建立一个本地的 android 版本库镜像还是不难的:

  • 下载 repo bootstrap 脚本

    $ curl http://android.git.kernel.org/repo >~/bin/repo
    
    $ chmod a+x ~/bin/repo
    
    $ export PATH=$PATH:~/bin
  • 提供 –mirror 参数调用 repo init ,建立 git 版本库克隆

    $ repo init -u git://android.git.kernel.org/platform/manifest.git --mirror
    • 使用 –morror 则下一步和源同步的时候,本地按照源的版本库组织方式进行组织,否则会按照 manifest.xml 指定的方式重新组织并检出到本地

  • 开始和源同步

    $ repo sync
  • 修改 manifest ,修改 git 库地址,指向本地的 git 服务器

    • 修改 platform/manifest.git 库中现有的 xml 文件,或者创建一个新的 xml 文件

    • 将 git 的地址改为本地地址,提交并 push

  • 本地 repo 镜像建立完毕之后,就可以在执行 repo init 时,使用本地更改后的 manifest 库,之后执行 repo sync 就是基于本地版本库进行同步了。

  • 也可以改造 repo,使得不必为 repo 工具初始化,也在本地网络完成操作…

Repo init 干了些什么?

实际上,得到客户使用 repo 的信息后,首先下载 repo 执行脚本开始研究。

curl http://android.git.kernel.org/repo >~/bin/repo

难道只有 600 行的 python 代码么?要是这样应该很简单的呀。可以看下来,却发现远非如此。

Shell script or python?

首先 repo 脚本使用了一个魔法:从脚本第一行的 shebang 来看应该是 shell 脚本,但是满眼却都是 python 语法,怎么回事?

 1 #!/bin/sh

 2

 3 ## repo default configuration

 4 ##

 5 REPO_URL='git://android.git.kernel.org/tools/repo.git'

 6 REPO_REV='stable'

 7

 8 # Copyright (C) 2008 Google Inc.

   ...



22 magic='--calling-python-from-/bin/sh--'

23 """exec" python -E "$0" "$@" """#$magic"

24 if __name__ == '__main__':

25   import sys

26   if sys.argv[-1] == '#%s' % magic:

27     del sys.argv[-1]

28 del magic

魔法就在第 23 行,巧妙的通过 python 三引号字串写出了一个能被 python 和 shell script 都能理解的代码,以此为界,代码由 Shell 脚本进入了 Python 的世界。

Bootstrap 和真正的 repo

通过 curl 下载的的 repo 并非完整的 repo 脚本,只是一个 bootstrap。当 repo 执行时,会负责下载完整的 repo 代码,并将控制权转移给真正的 repo。

通过 main 函数,可以看到 repo 运行的开始,就试图发现本地真正的完整的 repo 代码,以便移交控制权:

544 def main(orig_args):

545   main, dir = _FindRepo()



586   try:

587     os.execv(main, me)

其中 545 行的 _FindRepo() 会在当前目录开始向上递归查找 “.repo/repo/main.py”,如果找到则移交控制权(587行)。

Repo bootstrap 脚本调用 init 只完成第一阶段的初始化

Repo 的 bootstrap 脚本只支持两个命令 help 和 init,而 init 也只完成 repo 版本库克隆(即安装 repo 完整工具),之后就转移控制权。

在 Repo bootstrap 执行 init 可以提供很多参数,但实际上第一阶段初始化,只用到两个参数(而且都有默认值)

  • 参数:–repo-url=URL
    repo 工具本身的 git 库地址。缺省为:git://android.git.kernel.org/tools/repo.git

  • 参数:–repo-branch=REVISION
    使用 repo 的版本库,即 repo git 库的分支或者里程碑名称。缺省为 stable

第二阶段的 repo init

执行第二阶段的 repo init,控制权已经移交给刚刚克隆出来的 repo git 库的脚本。

Repo git 库被克隆/检出到执行 repo init 命令当前目录下的 .repo/repo 子目录中,主要的执行脚本为 .repo/repo/main.py。main.py 接着执行 repo init 命令。

Repo 的代码组织的非常好,在 .repo/repo/subcmds/ 子目录下,是各个 repo 命令的处理脚本。repo init 的第二阶段脚本正是由 .repo/repo/subcmds/init.py 负责执行的。第二阶段主要完成:

  • 克隆由 -u 参数提供的 manifest Git 库,如克隆 android 库时:

    $ repo init -u git://android.git.kernel.org/platform/manifest.git
  • 如果不提供 -b REVISION 或者 –manifest-branch=REVISION参数,则检出 manifest Git 库的 master 分支

  • 如果不提供 -m NAME.xml 或者 –manifest-name=NAME.xml 参数,则使用缺省值 default.xml

  • 如果提供 –mirror 参数,则后续同步操作会有相应的体现

Repo start 干了些什么?

Android 源码网站在介绍 repo 的使用模型中,有一个图片: http://source.android.com/images/git-repo-1.png , 介绍了 repo 的使用流程。其中 “repo start” 是紧接着 “repo sync” 后的第一个动作。那么这个动作是干什么的呢?

得益于 repo 对 git 操作的封装,”repo start” 命令的处理代码只有区区 68 行。

 37   def Execute(self, opt, args):



 41     nb = args[0]



 47     projects = []

 48     if not opt.all:

 49       projects = args[1:]



 54     all = self.GetProjects(projects)



 57     for project in all:



 59       if not project.StartBranch(nb):

 60         err.append(project)

看到第 59 行了么,就是对 repo 同步下来的项目的多个 Git 版本库,逐一执行 project.StartBranch 操作。 nb 是 repo start 的第一个参数,即分支名称。

关于 StartBranch 的代码,在 project.py 中:

 857   def StartBranch(self, name):

 858     """Create a new branch off the manifest's revision.

 859     """



 894     if GitCommand(self,

 895                   ['checkout', '-b', branch.name, revid],

 896                   capture_stdout = True,

 897                   capture_stderr = True).Wait() == 0:

 898       branch.Save()

 899       return True

原来如此, repo start <branch_name> 就是逐一为各个版本库创建工作分支,以便在此分支下进行工作。

读者可以按图索骥,找到 repo 各个命令的实现,破解心中的疑惑。

 

repo的用法(zz)

注:repo只是google用Python脚本写的调用git的一个脚本,主要是用来下载、管理Android项目的软件仓库。(也就是说,他是用来管理给git管理的一个个仓库的)

下载 repo 的地址: http://android.git.kernel.org/repo ,可以用以下二者之一来下载 repo

wget http://android.git.kernel.org/repo 

或者 

curl http://android.git.kernel.org/repo > ~/bin/repo  

下载完成后须修改repo的权限: chmod a+x ~/bin/repo 

用repo sync 在抓去 android source code 的时候,会经常出现一些错误导致 repo sync 中断,每次都要手动开始。 可以用如下的命令,来自动重复

$?=1; 

while [ $? -ne 0 ] ; 

do  repo sync ; 

done

获取帮助:

repo help [ command ]   //显示command 的详细的帮助信息内容

示例: repo help init 来获取 repo init 的其他用法

repo init -u URL 用以在当前目录安装 repository ,会在当前目录创建一个目录 ".repo"  -u 参数指定一个URL, 从这个URL 中取得repository 的 manifest 文件。   

示例:repo init -u git://android.git.kernel.org/platform/manifest.git

获取的manifest文件放在.repo目录中。命名为manifest.xml。这个文件的内容其实就是所有被git管理的仓库的列表!

可以用 -m 参数来选择获取 repository 中的某一个特定的 manifest 文件,如果不具体指定,那么表示为默认的 namifest 文件 (default.xml)

repo init -u git://android.git.kernel.org/platform/manifest.git -m dalvik-plus.xml

(有诸多供我们选择的manifest文件,所有的manifest文件都放在目录.repo/manifests中,该目录本身亦被git所管理,你可以cd进去看看)

可以用 -b 参数来指定某个manifest 分支。

repo init -u git://android.git.kernel.org/platform/manifest.git -b release-1.0

你会发现.repo/manifests是个被git管理的仓库,这里放的是所有的manifest文件(*.xml),因为被git管理,固然有分支,-b可以切换到你想要的分支然后再下载相关的xml文件,当然具体下载那个xml还要看-m参数了,所以如果你仅仅指定-b而没有-m的话,就是下载-b指定分支下的default.xml文件

如果不指定-b参数,那么会默认使用master分支

4. repo sync [project-list]

下载最新本地工作文件,更新成功,这本地文件和repository 中的代码是一样的。 可以指定需要更新的project , 如果不指定任何参数,会同步整个所有的项目。

如果是第一次运行 repo sync , 则这个命令相当于 git clone ,会把 repository 中的所有内容都拷贝到本地。 如果不是第一次运行 repo sync , 则相当于 git remote update ;  git rebase origin/branch .  repo sync 会更新 .repo 下面的文件。 如果在merge 的过程中出现冲突, 这需要手动运行  git  rebase --continue

5. repo update[ project-list ]

上传修改的代码 ,如果你本地的代码有所修改,那么在运行 repo sync 的时候,会提示你上传修改的代码,所有修改的代码分支会上传到 Gerrit (基于web 的代码review 系统), Gerrit 受到上传的代码,会转换为一个个变更,从而可以让人们来review 修改的代码。

6. repo diff [ project-list ]

        显示提交的代码和当前工作目录代码之间的差异。

7. repo download  target revision

        下载特定的修改版本到本地, 例如:  repo download pltform/frameworks/base 1241 下载修改版本为 1241 的代码

8. repo start newbranchname .

        创建新的branch分支。 "." 代表当前工作的branch 分支。

9.  repo prune [project list]

        删除已经merge 的 project

10. repo forall -c 

这个命令会遍历所有的git仓库,并在每个仓库执行-c所指定的命令(这个被执行的命令就不限于仅仅是git命令了,而是任何被系统支持的命令,比如:ls 、 pwd 、cp 等等的 )

当我想通过这个命令遍历所有的仓库并在每个仓库执行"git checkout . "用以将每个仓库的改动都清除的时候,我这么输入命令:

repo forall -c git checkout . 

我发现这样根本不行。看来repo不能遍历执行checkout这个命令。今天我终于想到了另外一个命令"git reset --hard HEAD" 哈哈

repo forall -c git git reset --hard HEAD

再说一个新发现:以前用repo forall 执行一些命令的时候,可能再遍历到某个仓库的时候出了问题,但是我却苦于不知道这个仓库到底是哪个!一直也没有解决。今天终于找到了。。。。  关键时候还是要看命令自己带的帮助手册呀。。。

repo help forall  用这个命令查看下针对forall的帮助吧。说的很清楚,repo执行的时候加上-p参数就可以在遍历到每个仓库的时候先打印出当前的pwd,然后再继续执行-c所指定的命令。举例如下:

repo forall -p -c git branch    

 

//该命令会遍历所有仓库并打印每个仓库的分支情况,由于有了-p参数,这样便会打印出每个仓库的路径!!!

 

11. repo status

       显示 project 中每个仓库的状态,并打印仓库名称


本文转载自:http://blog.csdn.net/sunweizhong1024/article/details/8055372

共有 人打赏支持
鲜鲜
粉丝 0
博文 13
码字总数 456
作品 0
成都
android源码下载方式

android源码下载方式: 方式一: repo init -u git://android.git.kernel.org/platform/manifest.git repo sync 这是官方提供的下载方式,但最近使用这种方式出现网络连接超时,据说是被hac...

鉴客
2012/03/09
54
0
android源码下载方式

android源码下载方式: 方式一: repo init -u git://android.git.kernel.org/platform/manifest.git repo sync 这是官方提供的下载方式,但最近使用这种方式出现网络连接超时,据说是被hac...

晨曦之光
2012/03/01
700
0
android源码下载方式

android源码下载方式: 方式一: 1) 创建~/bin 2) 下载repo 3) 创建保存Android源码文件 4) 下载Android源码(master主干) 下载Android源码(branch分支) 更多分支目录:https://andro...

长平狐
2013/01/06
106
0
rpmのyum详解

安装rpm包: 包后面加 --nodeps忽略依赖关系 加--test 测试安装不真安装 [root@yulong ~]# rpm -ivh axel-2.4-1.el6.rf.x86_64.rpmwarning: axel-2.4-1.el6.rf.x86_64.rpm: Header V3 DSA/S......

vi123456
2013/07/28
0
0
rpm包安装和卸载,rpm查询,yum工具详解,yum仓库搭建

rpm包安装和卸载 [root@binbinlinux Packages]# rpm -ivh zip-3.0-1.el6.x86_64.rpm 安装rpm包命令 ivh I=安装的意思install v=可视 h =显示安装进度 mount /dev/cdrom /mnt/ 挂载到mnt下 cd......

amenging
2017/11/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

大数据框架对比:Hadoop、Storm、Samza、Spark和Flink

简介 大数据是收集、整理、处理大容量数据集,并从中获得见解所需的非传统战略和技术的总称。虽然处理数据所需的计算能力或存储容量早已超过一台计算机的上限,但这种计算类型的普遍性、规模...

hblt-j
42分钟前
3
0
正则介绍及grep/egrep用法

10月16日任务 9.1 正则介绍_grep上 9.2 grep中 9.3 grep下 扩展 把一个目录下,过滤所有*.php文档中含有eval的行 grep -r --include="*.php" 'eval' /data 9.1 正则介绍_grep上 什么是正则 ...

zgxlinux
57分钟前
2
0
想用Unity3D引擎软件赚点钱的看过来

前言: 你可以不拥有很多钱 但你一定要有赚钱的能力 目前手上有项目, 需要熟练Unity3D引擎软件的伙伴 有意向的给我发私信

猿神出窍
59分钟前
2
0
Spring Boot全局异常处理

Spring Boot默认的异常处理机制 默认情况下,Spring Boot为两种情况提供了不同的响应方式。 一种是浏览器客户端请求一个不存在的页面或服务端处理发生异常时,一般情况下浏览器默认发送的请求...

狼王黄师傅
今天
8
0
Thinkphp5 优雅配置两个数据库

工作需要需要配置两个数据库,框架5.0的,步骤如下: 1、在database.php同级创建一个database2.php文件 在里面配置第二个数据库信息, 2、在config中配置这个数据库信息: 3、创建第二个表的...

wqzbxh
今天
5
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部