Skip to content
01.版本控制»02.repo工具»LV010-初始化repo项目.md

LV010-初始化repo项目

这一部分我们来看一下 repo 的第一个命令:repo init

操作环境:CNB 的默认云原生开发环境

一、初始化 repo 管理的项目

1. repo init

1.1 基本命令

shell
repo init -u url [options]

在当前目录中安装 Repo。这会创建一个 .repo/ 目录。

options

  • -u:指定要从中检索清单代码库的网址。您可以在 https://android.googlesource.com/platform/manifest 中找到通用清单
  • -m:选择代码库中的一个清单文件。如果未选择任何清单名称,则会默认选择 default.xml。
  • -b:指定修订版本,即特定的清单分支。

注意:对于其余的所有 Repo 命令,当前工作目录必须是 .repo/ 的父目录或相应父目录的子目录。

1.2 使用示例

这里我们直接参考安卓的源码文档:下载源代码 | Android Open Source Project (google.cn),从文档中可知,我们可以运行 repo init 获取最新版本的 Repo 及其最新的 bug 修复。Android 源代码中包含的各个仓库在工作目录中的放置位置是通过清单文件来指定的,必须为该清单指定一个网址。

shell
repo init --partial-clone -b main -u https://android.googlesource.com/platform/manifest

"Partial Clone" 功能是针对 Git 的一项性能优化,允许 Git 在没有完整存储库副本的情况下运行。这项工作的目标是让 Git 更好地处理极大的存储库。

【例】

shell
  /test repo init --partial-clone -b main -u https://android.googlesource.com/platform/manifest
Downloading Repo source from https://gerrit.googlesource.com/git-repo
remote: Total 9447 (delta 5032), reused 9447 (delta 5032)
repo: Updating release signing keys to keyset ver 2.3
warning: gpg (GnuPG) is not available.
warning: Installing it is strongly encouraged.

Updating files: 100% (3/3), done.

Your Name  [xxx]:
Your Email [xxx@noreply.cnb.cool]:

Your identity is: xxx <xxx@noreply.cnb.cool>
is this correct [y/N]? y

repo has been initialized in /test

1.3 源的问题

因为上面我是在 CNB 中执行,所以对于一些网址可能做了加速处理,是没有问题的,但是之前在本地 VMware 虚拟机中的 ubuntu 中操作时可能会有报错:

image-20240926231714368

这里大概还是因为网络的问题,我们换用国内的:AOSP | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror,从这里可知,我们可以执行下面这个命令:

shell
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest

不出意外的话,又又又出意外了:

image-20240926232134894

这里我们看清华源哪里的帮助文档吧:

image-20240926232219048

我们来到帮助页面 git-repo | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror

image-20240926232316884

那我们就按照这里说的操作吧,搞完之后,就可以成功啦:

image-20240926232355572

其实这里要是自己在 gitee 上 fork 了 repo 源码仓库的话,也可以写成自己的。

二、 .repo 目录

我们来看一下.repo 目录都有什么,我们执行:

shell
tree .repo/ -L 1

【例】

shell
  /test tree .repo/ -L 1
.repo/
├── TRACE_FILE
├── manifest.xml
├── manifests
├── manifests.git
└── repo

4 directories, 2 files

可以看到里面还有两个目录,我们都进去看一下:

image-20251108215134352

1. 项目清单库(.repo/manifests)

AOSP 项目清单 git 库下,有一个文件 default.xml,是一个标准的 XML,描述了当前 repo 管理的所有信息。

xml
<?xml version="1.0" encoding="UTF-8"?>
<manifest>

  <remote  name="aosp"
           fetch=".."
           review="https://android-review.googlesource.com/" />
  <default revision="main"
           remote="aosp"
           sync-j="4" />

  <manifest-server url="http://android-smartsync.corp.google.com/android.googlesource.com/manifestserver" />

  <superproject name="platform/superproject/main" remote="aosp"/>
  <contactinfo bugurl="go/repo-bug" />

  <project path="build/make" name="platform/build" groups="pdk" >
    <linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
    <linkfile src="buildspec.mk.default" dest="build/buildspec.mk.default" />
    <linkfile src="core" dest="build/core" />
    <linkfile src="envsetup.sh" dest="build/envsetup.sh" />
    <linkfile src="target" dest="build/target" />
    <linkfile src="tools" dest="build/tools" />
  </project>
  <project path="build/bazel" name="platform/build/bazel" groups="pdk" >
    <linkfile src="bazel.WORKSPACE" dest="WORKSPACE" />
    <linkfile src="bazel.BUILD" dest="BUILD" />
  </project>
  <project path="build/bazel_common_rules" name="platform/build/bazel_common_rules" groups="pdk" />
  <project path="build/blueprint" name="platform/build/blueprint" groups="pdk,tradefed" />
  <project path="build/pesto" name="platform/build/pesto" groups="pdk" />
  <project path="build/release" name="platform/build/release" groups="pdk,tradefed" />
  <project path="build/soong" name="platform/build/soong" groups="pdk,tradefed" >
    <linkfile src="root.bp" dest="Android.bp" />
    <linkfile src="bootstrap.bash" dest="bootstrap.bash" />
  </project>
  <project path="art" name="platform/art" groups="pdk" />
  <project path="bionic" name="platform/bionic" groups="pdk" />
  <!-- ...... -->
  <project path="external/OpenCL-Headers" name="platform/external/OpenCL-Headers" />
  <!-- ...... -->
  <project path="trusty/vendor/google/aosp" name="trusty/vendor/google/aosp" groups="trusty" >
    <copyfile src="lk_inc.mk" dest="lk_inc.mk" />
  </project>
  <!-- END open-source projects -->

  <repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" />


  <!--
    Merge marker to make it easier for git to merge AOSP-only manifest
    changes to a custom manifest.  Please keep this marker here and
    refrain from making changes on or below it.
  -->
</manifest>

这里面有上百行,这里中间有一大部分省略掉了。接下来我们一部分部分了解。

2.1 remote 标签

xml
<remote  name="aosp"
         fetch=".."
         review="https://android-review.googlesource.com/" />

描述了远程仓库的基本信息。name 描述的是一个远程仓库的名称,通常我们看到的命名是 origin。fetch 用作项目名称的前缘,在构造项目仓库远程地址时使用到。review 描述的是用作 code review 的 server 地址。

2.2 default 标签

xml
<default revision="main"
         remote="aosp"
         sync-j="4" />

default 标签的定义的属性,将作为标签的默认属性,在标签中,也可以重写这些属性。属性 revision 表示当前的版本,也就是我们俗称的分支。属性 remote 描述的是默认使用的远程仓库名称,即标签中 name 的属性值。属性 sync-j 表示在同步远程代码时,并发的任务数量,配置高的机器可以将这个值调大.

2.3 project 标签

xml
<project path="build/make" name="platform/build" groups="pdk" >
    <linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
    <linkfile src="buildspec.mk.default" dest="build/buildspec.mk.default" />
    <linkfile src="core" dest="build/core" />
    <linkfile src="envsetup.sh" dest="build/envsetup.sh" />
    <linkfile src="target" dest="build/target" />
    <linkfile src="tools" dest="build/tools" />
</project>

每一个 repo 管理的 git 库,就是对应到一个 < project > 标签,path 描述的是项目相对于远程仓库 URL 的路径,同时将作为对应的 git 库在本地代码的路径; name 用于定义项目名称,命名方式采用的是整个项目 URL 的相对地址。 如,AOSP 项目的 URL 为 https://android.googlesource.com/,命名为 platform/build 的 git 库,访问的 URL 就是 https://android.googlesource.com/platform/build

如果需要新增或替换一些 git 库,可以通过修改 default.xml 来实现,repo 会根据配置信息,自动化管理。但直接对 default.xml 的定制,可能会导致下一次更新项目清单时,与远程 default.xml 发生冲突。 因此,repo 提供了一个种更为灵活的定制方式——local_manifests 。所有的定制是遵循 default.xml 规范的,文件名可以自定义,如 local_manifest.xml, another_local_manifest.xml 等, 将定制的 XML 放在新建的.repo/local_manifests 子目录即可。repo 会遍历.repo/local_manifests 目录下的所有*.xml 文件,最终与 default.xml 合并成一个总的项目清单文件 manifest.xml。

local_manifests 的修改示例如下:

xml
$ ls .repo/local_manifests
local_manifest.xml
another_local_manifest.xml

$ cat .repo/local_manifests/local_manifest.xml
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
    <project path="manifest" name="tools/manifest" />
    <project path="platform-manifest" name="platform/manifest" />
</manifest>

2. repo 脚本库(.repo/repo)

repo 对 git 命令进行了封装,提供了一套 repo 的命令集(包括 init, sync 等),所有 repo 管理的自动化实现也都包含在这个 git 库中。 在第一次初始化的时候,repo 会从远程把这个 git 库下载到本地。

3. 仓库目录和工作目录

仓库目录保存的是历史信息和修改记录,工作目录保存的是当前版本的信息。一般来说,一个项目的 Git 仓库目录(默认为.git 目录)是位于工作目录下面的,但是 Git 支持将一个项目的 Git 仓库目录和工作目录分开来存放。 对于 repo 管理而言,既有分开存放,也有位于工作目录存放的:

  • manifests: 仓库目录有两份拷贝,一份位于工作目录(.repo/manifests)的.git 目录下,另一份独立存放于.repo/manifests.git
  • repo:仓库目录位于工作目录(.repo/repo)的.git 目录下
  • project:所有被管理 git 库的仓库目录都是分开存放的,位于.repo/projects 目录下。同时,也会保留工作目录的.git,但里面所有的文件都是到.repo 的链接。这样,即做到了分开存放,也兼容了在工作目录下的所有 git 命令。

既然.repo 目录下保存了项目的所有信息,所有要拷贝一个项目时,只是需要拷贝这个目录就可以了。repo 支持从本地已有的.repo 中恢复原有的项目。

参考资料:

repo 工具安装和使用教程(windows+gitee)_repo 安装-CSDN 博客

Repo 工作原理及常用命令总结——2023.07-CSDN 博客

Android 源代码仓库及其管理工具 Repo 分析详解 Android 脚本之家 (jb51.net)

Repo 工作原理和使用介绍 Android 脚本之家 (jb51.net)

莫道桑榆晚 为霞尚满天.