天天看点

Android源码同步工具Repo0. 前言1. repo常用命令2. manifest介绍3 参考文献

0. 前言

整个android系统源码大约有500个左右大大小小的project,其中每个project都是使用git进行管理。为了对所有的这些project进行统一的管理操作,谷歌就用python开发了repo工具。本文主要介绍如何使用repo工具来对android源码进行管理。

1. repo常用命令

repo的命令操作很简单,常用的也就几个,只要操作过很快就能够熟练使用了。下面对这些常用命令进行介绍。

1.1 init

repo init -u <URL> [<OPTIONS>]
           

该操作将会在当前目录创建一个

.repo

目录,其中包括一个repo的源代码的git仓库和一个包含Android manifest文件的git仓库。在

.repo

目录下还包含了一个

manifest.xml

文件,它是一个软连接,指向

.repo/manifest

目录的一个manifest文件(当前选择的manifest)。

该命令包含的选项包括:

  • -u

    :指定一个URL用于获取manifest仓库
  • -m

    :从.repo/manifest目录选择一个manifest,如果没有指定的话,那就是default.xml
  • -b

    :指定manifest仓库的分支

如在《Android AOSP源码下载》一篇中,使用的init的命令如下:

../repo/repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest -b android-_r6
           

可以看到-u指定了manifest仓库的URL,-b指定分支,-m并没有指定,所以使用的是default.xml。

1.2 sync

repo sync [<PROJECT_LIST>]
           

该命令将会根据之前

init

中选择的manifest文件,将新的变化下载到本地环境中。如果没有指定任何参数,将会同步manifest文件中的所有project。

当执行rep sync的时候,主要做了如下操作:

  • 如果该工程之前从未同步过,那么repo sync就等效于执行git clone操作,会将指定的project从远程仓库拷贝到本地。
  • 如果工程之前有同步过一次,那么rep syn就等效于执行以下操作:
git remote update 
git rebase origin/<BRANCH>
           

<BRANCH>

是当前本地的project所checked-out的分支。如果本地分支没有跟踪一个远程分支,那么该project将不会有同步发生。

当成功执行repo sync命令后,指定project的代码将会与远程仓库的代码同步。

该命令包含的选项有:

  • -d

    : 将指定的project切换回manifest文件中指定的分支
  • -s

    : 根据当前manifest文件中

    manifest-server

    元素所的指定,切换到一个已知好的版本
  • -f

    : 即使当前project同步失败了,也会继续处理其他的project

1.3 diff

repo diff [<PROJECT_LIST>]
           

该命令就是对指定的每个project用

git diff

命令显示project的修改状态。

1.4 forall

在每个project中执行给定shell命令,有以下附加的环境变量可以使用:

  • REPO_PROJECT 是该project的唯一的名字
  • REPO_PATH 是该project的与根目录的相对路径
  • REPO_REMOTE 是manifest中指定的

    remote

  • REPO_LREV 是将manifest中指定的

    revision

    的值变换为本地跟踪的分支名
  • REPO_RREV 是manifest文件中写的

    revision

    的值

该命令有以下选项:

  • -c

    : 指定要执行的shel命令和参数(使用

    /bin/sh

    执行)
  • -p

    : show project headers before output of the specified command. This is achieved by binding pipes to the command’s stdin, stdout, and sterr streams, and piping all output into a continuous stream that is displayed in a single pager session.
  • -v

    : 显示命令写到stderr的消息

1.5 start

repo start <BRANCH_NAME> [<PROJECT_LIST>]
           

基于manifest中指定的revision创建一个新分支用于开发。

1.6 status

repo status [<PROJECT_LIST>]
           

对于每个指定的project,将工作树、暂存区和当前分支最近的commit进行比较。对于有差异的文件将其用一行显示出来。其中有差异的文件的修改状态使用两个字母进行表示。

第一个字母是大写,表示该文件在暂存区与当前分支的最新commi有不同:

letter meaning description
- no change same in HEAD and index
A added not in HEAD, in index
M modified in HEAD, modified in index
D deleted in HEAD, not in index
R renamed not in HEAD, path changed in index
C copied not in HEAD, copied from another in index
T mode changed same content in HEAD and index, mode changed
U unmerged conflict between HEAD and index; resolution required

第二个字母是小写的,表示该文件在当前工作目录与暂存区不一致:

letter meaning description
- new/unknown not in index, in work tree
m modified in index, in work tree, modified
d deleted in index, not in work tree

1.7 help

如果有不熟悉的命令就通过

repo help

查看手册,其中对于每个命令,还可以通过指定–help 查看该命令的手册,如:

2. manifest介绍

默认.repo/manifest.xml指向当前的sd的manifest文件,即位于.repo/manifests目录下(默认下载的aosp代码为default.xml)。repo工具就是根据这个manifest文件来管理android 500个大大小小的project,下面我们就来看一下该文件。

<manifest>

  <remote name="aosp" fetch=".." />
  <default revision="refs/tags/android-5.1.1_r6" remote="aosp" sync-j="4" />

  <project path="build" name="platform/build" groups="pdk,tradefed">

  </project>
  <project path="abi/cpp" name="platform/abi/cpp" groups="pdk" />
  <project path="art" name="platform/art" groups="pdk" />
  <project path="bionic" name="platform/bionic" groups="pdk" />
  <project path="bootable/bootloader/legacy" name="platform/bootable/bootloader/legacy" groups="pdk-cw-fs" />
  <project path="bootable/recovery" name="platform/bootable/recovery" groups="pdk" />

......

  <project path="tools/studio/cloud" name="platform/tools/studio/cloud" groups="notdefault,tools" />
  <project path="tools/studio/translation" name="platform/tools/studio/translation" groups="notdefault,tools" />
  <project path="tools/swt" name="platform/tools/swt" groups="notdefault,tools" />
  <project path="tools/tradefederation" name="platform/tools/tradefederation" groups="notdefault,tradefed" />

</manifest>
           

可以看到该xml文件主要包括3种元素:

remote

default

project

2.1 remote

预先定义每个project中能够指定的remote,remote的功能见下面。

2.2 default

默认的remote,如果project中没有指定remote,则使用该remote。

2.3 project

指定整个Android源码的每一个project的配置,它包括以下属性值:

1) name

唯一的该project的名字。

2) remote

remote为project的远程仓库的URL字符串前面的定义,需要与name拼接成该project的远程仓库的实际的URL地址。每个project的仓库的在源码服务器中的实际路径应该为,remote中指定的路径 + project的

name

属性值,即:

${remote_fetch}/${project_name}.git 
           

如果project没有指定remote,就使用default元素中定义的remote。

platform/abi/cpp

,该project在源码服务器中的远程仓库的实际路径为:

<URL_TO_MANIFEST>/../platform/abi/cpp.git
           

3) path

该project在本地源码中的路径,如果没有指定,那就使用project的

name

的值,如果该project还有一个父元素,那么path会以父元素的path作为前缀。

4) revision

该project需要跟踪的远程git仓库的分支名。

5) upstream

该project的Git ref名,可以是一个sha1值。用于当以以-c模式同步一个revision的时候锁定manifest,从而避免同步全部的ref空间。

6) group

该project属于的组列表,可以用空格或者逗号分隔。所有的project都会属于

all

组,并且每个project都会属于它的

name

path

组。如果将project放置于组

notdefault

,那么repo将不会自动下载该project。

3 参考文献

[1] http://source.android.com/source/using-repo.html

[2] https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.txt

[3] https://wiki.cyanogenmod.org/w/Doc:_Using_manifests