repo xml 格式

来源:互联网 发布:php curl 伪装浏览器 编辑:程序博客网 时间:2024/05/16 12:57

Android是智能手机市场上炙手可热的开源操作系统,由Google推出后现在已经升级到了4.0版,受到了三星,HTC,摩托罗拉等大手机厂商的支持,最近一两年的增长速度超过了iPhone。

和苹果不一样,Android是开源系统,因此我们每个人都可以下载它的源码,修改,编译,生成自己的系统,然后刷到自己的手机上去。对于喜欢智能手机和DIY的程序员来说,这也是非常有趣的一件事。

Android源码的下载,编译的环境要求,编译步骤在上面的链接里都有,只要按步就班去做就没问题。不过DIYer们是不能满足于只用现成的,我们需要修改系统,而且最好有版本控制,就像Android源码的Repo工具一样。下面我们就来说说如何搭建自己的Repo版本控制服务器。

首先来说说Repo是干什么的。Android是一个非常庞大的项目,里面有很多相对独立的模块,例如Java虚拟机dalvik,例如libc实现bionic,例如浏览器引擎webkit,还有各个厂商的驱动与私有代码,等等。因此,Google将Android划分成多个子项目,每个子项目是一个独立的Git仓库,然后自己用python开发了一个Repo工具来对这几百个子项目(Git仓库)进行管理。

例如你可以通过下面的命令下载repo工具,然后初始化和下载Android的源代码(其中-j16表示使用16个链接同步下载,这段代码是从Android官网上摘录的,页面是Downloading the Source Tree):

从Google下载的Repo的代码很有意思,我们忽略无关的注释,截取开头一段来看:

代码的开头是Shell脚本,但是到了第七行,就神奇滴通过这个命令exec python -E "$0" "$@"…变成python代码,覆盖自身执行了。它利用了Python代码的长字符串”"”标记,使得第7行只会在Shell下执行,在python里就是一个常量字符串,开始的几行代码在Python和shell下都是有效的表达式。

从Google下载的repo只是一个初始化代码,通过repo initrepo sync,它不仅能下载Android源码,也能下载自身的最新代码。

如果我们要搭建自己的源码服务器,首先当然考虑的是Repo,不然我们自己重新构思一个多Git仓库管理的工具,也是非常麻烦的一件事。

下面我们就来看看如何利用Google的repo来管理我们自己的Android源码仓库。

首先我们需要理解repo所管理的Android代码的结构。这些结构都是在.repo/manifest.xml文件中给出的,我们给出一个例子:

在这个文件里主要的节点是remote,default和project。其中remote表示的是代码服务器的地址(fetch)和名称(name),另外还可以设定对应的审核服务器(review),当你通过repo向服务器提交代码的时候,会首先提交到审核服务器,通过了之后才能入库。当然,对于我们自己的内部代码服务器来说,一般是没有审核服务器的。

default表示的是当一个project没有设定remote属性时(例如下面的name属性为CyanogenMod/android_bionic的project节点),这个project从什么地址获取和提交代码。例如对于CyanogenMod/android_bionic项目来说,它的remote属性没有标明,因此就直接使用default的remote,即从github(git://github.com)获取代码,对应的分支是ics分支(refs/heads/ics)。

而对于name属性为platform/abi/cpp的项目来说,它则从aosp(https://android.googlesource.com/)获取代码,获取的只是android-4.0.3_r1这个标签的代码(refs/tags/android-4.0.3_r1)。另外,对于每个project来说,name对应的是远端服务器地址,path对应的是本地代码地址。例如CyanogenMod/android_bionic这个项目就是要将git://github.com/CyanogenMod/android_bionic的Git仓库的代码同步到本地./bionic目录。除此之外,还要注意的是,我们需要将服务器的Git仓库设置为裸仓库,这样才方便提交代码(git push)。

搞清楚了项目配置文件的结构以后,我们还需要知道如何让repo获取这个配置文件。实际上,repo init的-u参数对应的就是这个项目配置文件的Git仓库地址。这个Git仓库下只需要有一个名为default.xml的文件即可,文件内容即为上述内容。

假设服务器上存放源码的根目录是$REPOROOT,服务器地址是$REPOSVR。因为我们需要同时提供代码下载与提交功能,因此可以通过SSH协议来访问Git仓库。下面是搭建和使用自有Android源码服务器的步骤:

  1. 在$REPOROOT/myandroid目录下创建你需要自己修改的项目的Git仓库,例如假设你想修改recovery项目,则可以执行如下命令:
  2. 在$REPOROOT/manifest目录下创建项目配置文件。

    由于除了recovery项目以外,其他项目仍然使用Android自己的源代码,因此可以这样写default.xml文件:
  3. 配置好ssh和用户权限,保证每个用户得到授权以后才能访问源代码,而且不能直接登录服务器,例如可以在服务器上修改对应用户的.profile(debian)或者.bash_profile(ubuntu)文件,在最后加上exit命令(echo "exit" >> ~/.profile)
  4. 每个用户可以通过下面的命令来获取代码(其中$repouser_in_server对应的就是服务器上可以读写源代码目录,即$REPOROOT目录的用户名):
  5. 每个用户可以通过下面的命令来在本地创建myname/myfeature分支,修改与提交代码:

      为了方便起见,你可以在服务器上创建一个唯一的用户让大家来通过他读写代码,同时要向上面说的那样禁止任何人从远端通过这个用户登录服务器,以保证服务器的安全。你可以通过SSH的RSA证书避免每次登录SSH需要输入密码的麻烦,只需要运行ssh-keygen,然后将生成的~/.ssh/id_rsa.pub文件传给服务器管理员,让服务器管理员通过cat id_rsa.pub >> /home/$repouser_in_server/.ssh/authorized_keys命令添加证书即可。此外,你也需要手工ssh登录一下服务器,以保存服务器的指纹。就像这样,ssh $repouser_in_server@$REPOSVR

      这篇文章大量参考了《Git权威指南》这本书,特别是其中的第25章,非常感谢这本书的作者蒋鑫。当然,还需要感谢Android的作者Google,这是必须的。

      2012.4.25补充

      如果需要禁止任何人向服务器提交新的分支,可以写一个pre-receive钩子脚本(同时设为可执行),这个文件可以放在Git仓库的.git/hooks目录下。在每次Git仓库接收远程git push包之前就会调用这个文件。在pre-receive里代码可以从标准输入读取oldrev newrev refname三个参数,然后根据这三个参数判断是否需要阻止这次推送。如果不阻止就返回0,阻止就返回非零,同时可以通过标准输出打印错误提示信息。

      值得注意的是,由于参数里面并没有推动者的信息,因此无法根据推送者判断是否需要阻止推送。下面是一个pre-receive的例子:

    本条目发布于2012 年 3 月 23 日。属于互联网分类。
    原创粉丝点击