没有合适的资源?快使用搜索试试~ 我知道了~
Android源代码仓库及其管理工具Repo分析详解
9 下载量 17 浏览量
2020-08-28
09:12:05
上传
评论
收藏 201KB PDF 举报
温馨提示
本篇文章主要介绍了Android源代码仓库及其管理工具Repo分析详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
资源推荐
资源详情
资源评论
Android源代码仓库及其管理工具源代码仓库及其管理工具Repo分析详解分析详解
本篇文章主要介绍了Android源代码仓库及其管理工具Repo分析详解,小编觉得挺不错的,现在分享给大家,也
给大家做个参考。一起跟随小编过来看看吧
软件工程由于需要不断迭代开发,因此要对源代码进行版本管理。Android源代码工程(AOSP)也不例外,它采用Git来进行
版本管理。AOSP作为一个大型开放源代码工程,由许许多多子项目组成,因此不能简单地用Git进行管理,它在Git的基础上
建立了一套自己的代码仓库,并且使用工具Repo进行管理。工欲善其事,必先利其器。本文就对AOSP代码仓库及其管理工
具repo进行分析,以便提高我们日常开发效率。
《《Android系统源代码情景分析》系统源代码情景分析》——点击下载
现代的代码版本管理工具,SVN和Git是最流行的。SVN是一种集中式的代码管理工具,需要有一个中心服务器,而Git是一种
分布式的代码管理工具。不需要一个中心服务器。不需要中心服务器意味着在没有网络的情况下,Git也能进行版本管理。因
此,单从这一点出发,Git就比SVN要方便很多。当然,Git和SVN相比,还有许多不同的理念设计,但是总的来说,Git越来越
受到大家的青睐,尤其是在开源社区。君不见,Linux是采用Git进行版本管理,而越来越火的GitHub,提供也是Git代码管理服
务。本文不打算分析Git与SVN的区别,以及Git的使用方法,不过强烈建议大家先去了解Git,然后再看下面的内容。这里推荐
一本Git书籍《Pro Git》,它是GitHub的员工Scott Chacon撰写的,对Git的使用及其原理都介绍得非常详细和清晰。
前面提到,AOSP是由许许多项目组成的,例如,在Android 4.2中,就包含了329个项目,每一个项目都是一个独立的Git仓
库。这意味着,如果我们要创建一个AOSP分支来做feature开发,那么就需要到每一个子项目去创建对应的分支。这显然不能
手动地到每一个子项目里面去创建分支,必须要采用一种自动化的方式来处理。这些自动化处理工作就是由Repo工具来完成
的。当然,Repo工具所负责的自动化工作不只是创建分支那么简单,查看分支状态、提交代码、更新代码等基础Git操作它都
可以完成。
Repo工具实际上是由一系列的Python脚本组成的,这些Python脚本通过调用Git命令来完成自己的功能。比较有意思的是,组
成Repo工具的那些Python脚本本身也是一个Git仓库。这个Git仓库在AOSP里面就称为Repo仓库。我们每次执行Repo命令的
时候,Repo仓库都会对自己进行一次更新。
上面我们讨论的是Repo仓库,但是实际上我们执行Repo命令想操作的是AOSP。这就要求Repo命令要知道AOSP都包含有哪
些子项目,并且要知道这些子项目的名称、仓库地址是什么。换句话说,就是Repo命令要知道AOSP所有子项目的Git仓库元
信息。我们知道,AOSP也是不断地迭代法变化的,例如,它的每一个版本所包含的子项目可能都是不一样的。这意味着需要
通过另外一个Git仓库来管理AOSP所有的子项目的Git仓库元信息。这个Git仓库在AOSP里面就称为Manifest仓库。
到目前为止,我们提到了三种类型的Git仓库,分别是Repo仓库、Manifest仓库和AOSP子项目仓库。Repo仓库通过Manifest
仓库可以获得所有AOSP子项目仓库的元信息。有了这些元信息之后,我们就可以通过Repo仓库里面的Python脚本来操作
AOSP的子项目。那么,Repo仓库和Manifest仓库又是怎么来的呢?答案是通过一个独立的Repo脚本来获取,这个Repo脚本
位于AOSP的一个官方网站上,我们可以通过HTTP协议来下载。
现在,我们就通过一个图来来勾勒一下整个AOSP的Picture,它由Repo脚本、Repo仓库、Manifest仓库和AOSP子项目仓库
组成,如图1所示:
图1 Repo脚本、Repo仓库、Manifest仓库和AOSP子项目仓库
接下来我们就看看上述脚本和仓库是怎么来的。接下来我们就看看上述脚本和仓库是怎么来的。
1. Repo脚本脚本
从官方网站可以知道,Repo脚本可以通过以下命令来获取:
$ curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
也就是可以通过curl工具从http://commondatastorage.googleapis.com/git-repo-downloads/repo获得,并且保存在文件
~/bin/repo中。由于~/bin/repo是一个python脚本,我们通过chmod命令赋予它可执行的权限,以便接下来我们可以通过repo命
令来运行它。
2. Repo仓库仓库
我们下载好Repo脚本之后,要选通过以下命令来安装一个Repo仓库:
$ repo init -u https://android.googlesource.com/platform/manifest
这个命令实际上是包含了两个操作:安装Repo仓库和Manifest仓库。其中,Manifest仓库的地址由-u后来带的参数给出。这一
小节我们先分析Repo仓库的安装过程,在接下来的第3小节中,再分析Manifest仓库的安装过程。
我们看看Repo脚本是如何执行repo init命令的:
def main(orig_args):
repo_main, rel_repo_dir = _FindRepo()
cmd, opt, args = _ParseArguments(orig_args)
wrapper_path = os.path.abspath(__file__)
my_main, my_git = _RunSelf(wrapper_path)
if not repo_main:
if opt.help:
_Usage()
if cmd == 'help':
_Help(args)
if not cmd:
_NotInstalled()
if cmd == 'init':
if my_git:
_SetDefaultsTo(my_git)
try:
_Init(args)
except CloneFailure:
......
sys.exit(1)
repo_main, rel_repo_dir = _FindRepo()
else:
_NoCommands(cmd)
if my_main:
repo_main = my_main
ver_str = '.'.join(map(str, VERSION))
me = [repo_main,
'--repo-dir=%s' % rel_repo_dir,
'--wrapper-version=%s' % ver_str,
'--wrapper-path=%s' % wrapper_path,
'--']
me.extend(orig_args)
me.extend(extra_args)
try:
os.execv(repo_main, me)
except OSError as e:
......
sys.exit(148)
if __name__ == '__main__':
main(sys.argv[1:])
_FindRepo在从当前目录开始往上遍历直到根据目录。如果中间某一个目录下面存在一个.repo/repo目录,并且该.repo/repo存
在一个main.py文件,那么就会认为当前是AOSP中执行Repo脚本,这时候它就会返回文件main.py的绝对路径和当前查找目
录下的.repo子目录的绝对路径给调用者。在上述情况下,实际上是说明Repo仓库已经安装过了。
_FindRepo的实现如下所示:
repodir = '.repo' # name of repo's private directory
S_repo = 'repo' # special repo repository
REPO_MAIN = S_repo + '/main.py' # main script
def _FindRepo():
"""Look for a repo installation, starting at the current directory.
"""
curdir = os.getcwd()
repo = None
olddir = None
while curdir != '/' \
and curdir != olddir \
and not repo:
repo = os.path.join(curdir, repodir, REPO_MAIN)
if not os.path.isfile(repo):
repo = None
olddir = curdir
curdir = os.path.dirname(curdir)
return (repo, os.path.join(curdir, repodir))
_ParseArguments无非是对Repo的参数进行解析,得到要执行的命令及其对应的参数。例如,当我们调用“repo init -u
https://android.googlesource.com/platform/manifest”的时候,就表示要执行的命令是init,这个命令后面跟的参数是“-u
https://android.googlesource.com/platform/manifest”。同时,如果我们调用“repo sync”,就表示要执行的命令是sync,这个
命令没有参数。
_RunSelf检查Repo脚本所在目录是否存在一个Repo仓库,如果存在的话,就从该仓库克隆一个新的仓库到执行Repo脚本的
目录来。实际上就是从本地克隆一个新的Repo仓库。如果不存在的话,那么就需要从远程地址克隆一个Repo仓库到本地来。
这个远程地址是Hard Code在Repo脚本里面。
_RunSelf的实现如下所示:
def _RunSelf(wrapper_path):
my_dir = os.path.dirname(wrapper_path)
my_main = os.path.join(my_dir, 'main.py')
my_git = os.path.join(my_dir, '.git')
if os.path.isfile(my_main) and os.path.isdir(my_git):
for name in ['git_config.py',
'project.py',
'subcmds']:
if not os.path.exists(os.path.join(my_dir, name)):
return None, None
return my_main, my_git
return None, None
从这里我们就可以看出,如果Repo脚本所在的目录存在一个Repo仓库,那么要满足以下条件:
(1). 存在一个.git目录;
(2). 存在一个main.py文件;
(3). 存在一个git_config.py文件;
(4). 存在一个project.py文件;
(5). 存在一个subcmds目录。
上述目录和文件实际上都是一个标准的Repo仓库所具有的。
我们再回到main函数中。如果调用_FindRepo得到的repo_main的值等于空,那么就说明当前目录还没有安装Repo仓库,这
时候Repo后面所跟的参数只能是help或者init,否则的话,就会显示错误信息。如果Repo后面跟的参数是help,就打印出
Repo脚本的帮助文档。
我们关注Repo后面跟的参数是init的情况。这时候看一下调用_RunSelf的返回值my_git是否不等于空。如果不等于空的话,那
么就说明Repo脚本所在目录存一个Repo仓库,这时候就调用_SetDefaultsTo设置等一会要克隆的Repo仓库源。
_SetDefaultsTo的实现如下所示:
GIT = 'git'
REPO_URL = 'https://gerrit.googlesource.com/git-repo'
REPO_REV = 'stable'
def _SetDefaultsTo(gitdir):
global REPO_URL
global REPO_REV
REPO_URL = gitdir
proc = subprocess.Popen([GIT,
'--git-dir=%s' % gitdir,
'symbolic-ref',
'HEAD'],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
REPO_REV = proc.stdout.read().strip()
proc.stdout.close()
proc.stderr.read()
proc.stderr.close()
if proc.wait() != 0:
_print('fatal: %s has no current branch' % gitdir, file=sys.stderr)
sys.exit(1)
如果Repo脚本所在目录不存在一个Repo仓库,那么默认就将https://gerrit.googlesource.com/git-repo设置为一会要克隆的
Repo仓库源,并且要克隆的分支是stable。否则的话,就以该Repo仓库作为克隆源,并且以该Repo仓库的当前分支作为要克
剩余17页未读,继续阅读
资源评论
weixin_38531630
- 粉丝: 2
- 资源: 887
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功