Android使用repo来管理多个Git项目。它需要一个manifest XML文件来指示这些git项目的属性。

这里对manifest 做个介绍:

1.manifest: 最顶层的XML元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>


可以包含的子元素
<!DOCTYPE manifest [
<!ELEMENT manifest (notice?,
remote*,
default?,
manifest-server?,
remove-project*,
project*,
extend-project*,
repo-hooks?,
include*)>

2.remote元素: 设置远程git服务器的属性,包括下面的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28


<!ELEMENT remote EMPTY>
<!ATTLIST remote name ID #REQUIRED>
<!ATTLIST remote alias CDATA #IMPLIED>
<!ATTLIST remote fetch CDATA #REQUIRED>
<!ATTLIST remote pushurl CDATA #IMPLIED>
<!ATTLIST remote review CDATA #IMPLIED>
<!ATTLIST remote revision CDATA #IMPLIED>



例子1:
<remote fetch=".." name="zsgit" review="gerrit.xxxxx.com"/>

例子2:
<remote fetch="ssh://gerrit-sw.example.com:20418/" name="gerrit_01" review="gerrit.xxxxx.com"/>
<remote fetch="ssh://gerrit-os.example.com:20418/" name="gerrit_02" review="gerrit.xxxxx.com"/>
这样配置了2个remote的, 如果project 元素分别用到了 这2个remote的, 这样下载下来的git仓库 查看 git remote -v会发现 有的仓库是 gerrit_01 有的是gerrit_02

如果这样配置个 alias="shgit" ,这样所有下载下来的git仓库 看到的都是 shgit


例子3:
<remote fetch="ssh://gerrit-sw.example.com:29418/" name="shgit" pushurl="ssh://gerrit-master.example.com:29418/" review="gerrit.xxxxx.com"/>
如果是这样配置的 查看git仓库的 git remote -v会发现 fetch 和push 2个是不一样的.


name: 远程git服务器的名字,直接用于git fetch, git remote 等操作
alias: 远程git服务器的别名,如果指定了,则会覆盖name的设定。在一个manifest中,name不能重名,但alias可以重名。
fetch: 所有projects的git URL 前缀
pushurl: 设置git push 使用的url地址, fetch 和 push 可以是2个不同的url
review: 指定Gerrit的服务器名,用于repo upload操作。如果没有指定,则repo upload没有效果
revision git分支的名字,例如master或者refs/heads/master

3.default元素:设定所有projects的默认属性值,如果在project元素里没有指定一个属性,则使用default元素的属性值。

1
2
3
4
5
6
7
8
9
10
11
12
 <default remote="zsgit" revision="msm8996_nougat_r01055_20161021"/>

<!ELEMENT default EMPTY>
<!ATTLIST default remote IDREF #IMPLIED>
<!ATTLIST default revision CDATA #IMPLIED>
<!ATTLIST default dest-branch CDATA #IMPLIED>
<!ATTLIST default upstream CDATA #IMPLIED>
<!ATTLIST default sync-j CDATA #IMPLIED>
<!ATTLIST default sync-c CDATA #IMPLIED>
<!ATTLIST default sync-s CDATA #IMPLIED>
<!ATTLIST default sync-tags CDATA #IMPLIED>

remote: 之前定义的某一个remote元素中name属性值,用于指定使用哪一个远程git服务器。
revision: git分支的名字,例如master或者refs/heads/master
sync_j: 在repo sync中默认并行的数目。
sync_c: 如果设置为true,则只同步指定的分支(revision 属性指定),而不是所有的ref内容。
sync_s: 如果设置为true,则会同步git的子项目
sync-tags: 控制是否下载tags标签

4.project元素:指定一个需要clone的git仓库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<project groups="zs_amss" name="AMSS/adsp_proc" path="AMSS/adsp_proc"  />


<!ELEMENT project (annotation*,
project*,
copyfile*,
linkfile*)>
<!ATTLIST project name CDATA #REQUIRED>
<!ATTLIST project path CDATA #IMPLIED>
<!ATTLIST project remote IDREF #IMPLIED>
<!ATTLIST project revision CDATA #IMPLIED>
<!ATTLIST project dest-branch CDATA #IMPLIED>
<!ATTLIST project groups CDATA #IMPLIED>
<!ATTLIST project sync-c CDATA #IMPLIED>
<!ATTLIST project sync-s CDATA #IMPLIED>
<!ATTLIST project sync-tags CDATA #IMPLIED>
<!ATTLIST project upstream CDATA #IMPLIED>
<!ATTLIST project clone-depth CDATA #IMPLIED>
<!ATTLIST project force-path CDATA #IMPLIED>
name: 唯一的名字标识project,同时也用于生成git仓库的URL。格式如下:${remote_fetch}/${project_name}.git
path: 可选的路径。指定git clone出来的代码存放在本地的子目录。如果没有指定,则以name作为子目录名。
remote: 指定之前在某个remote元素中的name。
revision: 指定需要获取的git提交点,可以是master, refs/heads/master, tag或者SHA-1值。
groups: 列出project所属的组,以空格或者逗号分隔多个组名。所有的project都自动属于"all"组。每一个project自动属于
        name:'name' 和path:'path'组。例如<project name="monkeys" path="barrel-of"/>,它自动属于default, name:monkeys, and path:barrel-of组。
        如果一个project属于notdefault组,则,repo sync时不会下载。
sync_c: 如果设置为true,则只同步指定的分支(revision 属性指定),而不是所有的ref内容。
sync_s: 如果设置为true,则会同步git的子项目。
upstream: 在哪个git分支可以找到一个SHA1。用于同步revision锁定的manifest(-c 模式)。该模式可以避免同步整个ref空间。
annotation: 可以有多个annotation,格式为name-value pair。在repo forall 命令中这些值会导入到环境变量中。
remove-project: 从内部的manifest表中删除指定的project。经常用于本地的manifest文件,用户可以替换一个project的定义。

5.include

通过name属性可以引入另外一个manifest文件(路径相对与当前的manifest.xml 的路径)

name :另一个需要导入的manifest文件名字

EXAMPLE :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<manifest>

<remote name="shift"
fetch="git://git.mygit.com/" />
<default revision="kk-shift"
remote="shift"
sync-j="1" />

<project path="packages/shift/VideoPlayer" name="platform/packages/shift/VideoPlayer" />
<include name="another_manifest.xml" />
</manifest>

<!ELEMENT include EMPTY>
<!ATTLIST include name CDATA #REQUIRED>

可以在当前的路径下添加一个another_manifest.xml,这样可以在另一个xml中添加或删除project

6.remove-project
从内部的manifest表中删除指定的project。经常用于本地的manifest文件,用户可以替换一个project的定义

1
2
3
4
5
 

<!ELEMENT remove-project EMPTY>
<!ATTLIST remove-project name CDATA #REQUIRED>

7.其他奇技淫巧

1
2
3
4
5
6
7
8
9
10
11
12
13
  
#比较2个xml中增加删除了哪些仓库
diff <(grep -Po "name=\"[^\"]*\"" SM8150_P_R54908.1_REBASE_20181014_import_LA.UM.7.1.R1.09.00.00.461.061.xml | sort) <(grep -Po "name=\"[^\"]*\"" SM8150_P_R00500.1_REBASE_20180929_import_LA.UM.7.1.R1.09.00.00.461.057.xml|sort)

#vim中添加upstream。
:715,$s/ \// upstream="sm8150_p_r54908.1_rebase_20181014"\//gg

#vim中删除revision和upstream
:%s/revision=".*" upstream=".*"//gg

#vim中删除groups
:%s/groups="[^"]*" //g