跳转至

repo常用操作

repo简介

repo是Google开发的用于管理Android版本库的一个工具,repo是使用Python对git进行了一定的封装,并不是用于取代git,它简化了对多个Git版本库的管理。用repo管理的版本库都需要使用git命令来进行操作。

在我们初始化 Repo 仓库之后,会出现一个. repo 的文件夹,里面有如下内容:

$ tree .repo -L 1
.repo
├── manifests
├── manifests.git
├── manifest.xml
├── repo
└── TRACE_FILE

当执行**repo init** 命令来初始化仓库,该脚本会到我们指定的地方去下载 manifest 仓库,以及 repo 命令主体部分。下载好之后就放在当前目录下面的**.repo**目录下,其中:

文件夹 用途
manifests 清单文件的仓库
manifests.git 清单文件的 Git 裸仓库,不带工作区
manifest.xml 这是一个链接文件,指向你的用于初始化工作区的清单文件,即manifests/default.xml
project.list 一个文本文件,里面包含所有项目名字的列表
projects 该文件夹下包含所有 git project 的裸仓库,文件夹的层次结构跟工作区的布局一样
repo 这是 repo 命令的主体,其中也包含最新的 repo 命令,推荐使用这里面的 repo 命令

manifest 元素

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

    <remote name="aosp"
            fetch="https://mirrors.tuna.tsinghua.edu.cn/git/AOSP"
            review="https://android-review.googlesource.com/"/>
    <default revision="main"
             remote="aosp"
             sync-j="4"/>

    ...

    <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>

    <remove-project name="platform/build/release"/>    
    <include name="rtfsc-override.xml"/>

</manifest>

清单文件是xml的格式,一个清单库可以包含多个清单文件和多个分支,每个清单文件和分支都有对应的版本。

remote 元素

可以存在一个或者多个 remote 元素,remote 元素指定了使用 repo upload 命令的时候,会将改变提交到哪个服务器。

  • name: 远程git服务器的名字,直接用于git fetch, git remote 等操作

  • alias: 远程git服务器的别名,如果指定了,则会覆盖name的设定。在一个manifest(可以理解为default.xml)中, name不能重名,但alias可以重名。

  • fetch: 所有projects的git URL 前缀

  • review: 指定Gerrit的服务器名,用于repo upload操作。如果没有指定,则repo upload没有效果。

default 元素

default 元素中指定的属性都是一些缺省的属性。即如果 project 元素中不存在该属性,则使用在 default 元素中指定的属性。

  • revision:Git 分支的名字。如果 project 元素没有指定 revision 属性,那么就使用 default 元素的该属性。revision 属性的值可以是一个 git branch,git tag,也可以是一个 commit id。

  • sync-j:sync 的时候,并行工作的任务数。

  • sync-c:如果设置为 true,则在同步代码的时候,将只会同步 project 元素中 revision 属性中指定的分支。如果 project 元素没有指定 revision 属性,则使用 default 元素的 revision 属性。

  • sync_s: 如果设置为true,则会同步git的子项目

  • remote: 之前定义的某一个remote元素中name属性值,用于指定使用哪一个远程git服务器。

project 元素

xml 文件中可以指定一个或者多个 project 元素。 每一个 project 元素都描述了一个需要 pull 到本地的 git 仓库。
project 元素中有很多可以使用的属性,在此只介绍几个我们经常使用的属性。

  • name: 唯一的名字标识project,同时也用于生成git仓库的URL。格式如下:

  • path:可选的路径,该 指定git clone出来的代码存放在本地的子目录。如果没有指定,则以name作为子目录名。

  • remote: 指定之前在某个remote元素中的name。

  • revision:指定需要获取的git提交点,可以是master, refs/heads/master, tag或者SHA-1值。如果不设置的话,默认下载当前project,当前分支上的最新代码。

  • sync_c: 如果设置为true,则只同步指定的分支(revision 属性指定),而不是所有的ref内容。

  • sync_s: 如果设置为true,则会同步git的子项目。

  • groups: 列出project所属的组,以空格或者逗号分隔多个组名。

  • upstream: 在哪个git分支可以找到一个SHA1。用于同步revision锁定的manifest(-c 模式)。该模式可以避免同步整个ref空间。

  • annotation: 可以有多个annotation,格式为name-value pair。在repo forall 命令中这些值会导入到环境变量中。

remove-project

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

include元素

通过name属性可以引入另外一个manifest文件(路径相对与manifest repository’s root)。

常用命令

repo init

repo init -u manifest_git_path -m manifest_file_name -b branch_name --repo-url=repo_url --no-repo-verify

选项:

  • -u:指定manifest项目清单库地址。

  • -m:指定manifests库中的清单文件,默认为maniftests/default.xml。

  • -b:指定manifest仓的分支,默认为master分支。

不常用参数:

  • –-repo-url:指定远程repo库地址,当引导脚本中的地址不可访问时,可以通过该参数指定可访问的repo地址。

  • –-repo-branch:同manifest这个git库一样,repo这个git库也是有版本差异的,可以通过该参数来指定下载repo这个远程git库的特定分支。

  • –-no-repo-verify:在下载repo库时,会对repo的源码进行检查。通过–repo-url指定第三方repo库时,可能会导致检查不通过,所以可以配套使用该参数,强制不进行检查。

  • --depth {number}:限制下载记录次数,加速代码下载。

repo sync

repo sync [project_name]

执行了repo init 命令后,我们需要执行 repo sync 命令同步代码。

常用参数: - -j:开启多线程同步操作,这会加快sync命令的执行速度。该参数在default.xml中有默认设置。

  • -c, –current-branch:只同步指定的远程分支。默认情况下,sync会同步所有的远程分支。

不常用参数:

  • -d, –detach:脱离当前的本地分支,切换到manifest.xml中设定的分支。
  • -f, –force-broken:当有git库sync失败了,不中断整个同步操作,继续同步其他的git库。
  • –no-clone-bundle:在向服务器发起请求时,为了做到尽快的响应速度,会用到内容分发网络(CDN, Content Delivery Network)。
  • -q:遇到错误只显示,不退出

常用命令如下:

repo sync -c -q -j16

只同步frameworks/base库。

repo sync platform/frameworks/base -c -j16

repo start

repo start <newbranchname> [--all|<project>...]

创建并切换分支。刚克隆下来的代码是没有分支的,repo start实际是对git checkout -b命令的封装。 为指定的项目或所有的项目(若使用-all),以清单文件中为设定的分支,创建特定的分支。 这条指令与git checkout -b 还是有很大区别的。 - git checkout -b 是在当前所在的分支的基础上创建特性分支。 - 而repo start 是在清单文件设定的分支的基础上创建特性分支。

# 整个android都在 android-14.0.0_r30 的基础上创建分支 dev。
repo start dev --all

# 针对 platform/build、platform/bionic 仓,在 android-14.0.0_r30 的基础上创建分支 dev。
repo start dev platform/build platform/bionic

repo checkout

repo checkout <branchname> [<project>...]

切换分支。 实际上是对git checkout命令的封装,但不能带-b参数,所以不能用此命令来创建特性分支。

# 整个android都切换到分支 dev。
repo checkout dev
# 针对 platform/build platform/bionic 仓切换到分支 dev。
repo checkout dev platform/build platform/bionic

repo branches

repo branches [<project>...]

查看分支。

repo branches
repo branches platform/build platform/bionic

查看可切换的分支:

cd .repo/manifests
git branch -a | cut -d / -f 3

repo diff

repo diff [<project>...]

查看工作区文件差异。实际是对git diff命令的封装,用于分别显示各个项目工作区下的文件差异。在 commit 和工作目录之间使用 git diff 显示明显差异的更改。

#查看所有项目
repo diff

#只查指定的仓
repo diff platform/build platform/bionic

repo status

repo status [<project>...]

示例:

#查看所有项目的修改状态
repo status

#只查指定的仓的修改状态
repo status platform/build platform/bionic

每个小节的首行显示项目名称,以及所在的分支的名称。
每个字母表示暂存区的文件修改状态。

字母 含义 描述
- 无变化 没有修改,在 HEAD 和在索引中是一样的
A 添加 不在HEAD中,在暂存区中
M 修改 在HEAD中, 在暂存区中,内容不同
D 删除 在HEAD中,不在暂存区
R 重命名 不在HEAD中,在暂存区中
C 拷贝 不在HEAD中,在暂存区,从其他文件拷贝
T 文件状态改变 在HEAD中,在暂存区,内容相同
U 未合并 需要冲突解决

第二个字符表示工作区文件的更改状态。

字母 含义 描述
- 新/未知 不在暂存区,在工作区
m 修改 在暂存区,在工作区,被修改
d 删除 在暂存区,不在工作区

两个表示状态的字母后面,显示文件名信息。如果有文件重名还会显示改变前后的文件名及文件的相似度。

repo forall

repo forall [<project>...] -c <command>

迭代器,可以在所有指定的项目中执行同一个shell指令。

选项: - -c 后面所带的参数是shell指令,即执行命令和参数。命令是通过 /bin/sh 评估的并且后面的任何参数就如 shell 位置的参数通过。 - -p 在shell指令输出之前列出项目名称,即在指定命令的输出前显示项目标题。这是通过绑定管道到命令的stdin,stdout,和 sterr 流,并且用管道输送所有输出量到一个连续的流,显示在一个单一的页面调度会话中。 - -v 列出执行shell指令输出的错误信息,即显示命令写到 sterr 的信息。

附加环境变量: - REPO_PROJECT: 指定项目的名称 - REPO_PATH: 指定项目在工作区的相对路径 - REPO_REMOTE: 指定项目远程仓库的名称 - REPO_LREV: 指定项目最后一次提交服务器仓库对应的哈希值 - REPO_RREV: 指定项目在克隆时的指定分支,manifest里的revision属性

如果-c后面所带的shell指令中有上述环境变量,则需要用单引号把shell指令括起来。

添加环境变量
repo forall -c 'echo $REPO_PROJECT'
repo forall -c 'echo $REPO_PATH'
合并多个分支
# 将topic分支合并到master分支。
repo forall -p -c git merge topic
打标签
repo forall -c git tag dev-1.6
设置远程仓库
# 引用环境变量REPO_PROJECT添加远程仓库。
repo forall -c 'git remote add asop ssh://solo@10.0.12.8/$REPO_PROJECT.git'
特性分支
repo forall -c git branch dev
repo forall -c git checkout -b dev

repo upload

repo upload [--re --cc] [<project>]...

repo upload 相当于git push,但是又有很大的不同。它不是将版本库改动推送到代码审核服务器(Gerrit软件架设)的特殊引用上,使用SSH协议。代码审核服务器会对推送的提交进行特殊处理,将新的提交显示为一个待审核的修改集,并进入代码审核流程,只有当审核通过后,才会合并到官方正式的版本库中。

repo upload 相当于git push,但是又有很大的不同。它不是将版本库改动推送到代码审核服务器(Gerrit软件架设)的特殊引用上,使用SSH协议。代码审核服务器会对推送的提交进行特殊处理,将新的提交显示为一个待审核的修改集,并进入代码审核流程,只有当审核通过后,才会合并到官方正式的版本库中。

repo download

repo download {project change[/patchset]}
  • project:git仓
  • change[/patchset]:commit id

开发中常用命令

repo指定url

如指定清华源:

repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-14.0.0_r30 --repo-url=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo

repo --depth=1

有时候拉一套Android代码非常大,可以加参数 --depth,相当于只拉 git log -1 这层代码,节省时间空间。

repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-14.0.0_r30 --depth=1

切换分支

到manifests目录下找到分支名字

cd .repo/manifests
git branch -av

根据分支名字切换

repo init -b android-13.0.0_r9

同步并清除本地修改

repo forall -c 'git clean -dfx && git reset --hard' && repo sync -c -q -j16

depth=1后,查看全log

平时为了节省空间,加快拉代码速度,可以使用:

--depth=1

如果需要查看某个仓的全部 git log 信息,需要 unshallow :

git fetch --unshallow origin 分支名字

评论