repo工具介绍

转自文章《Android内核开发:理解和掌握repo工具》和《Repo的理解和用法小结2》

1. repo是什么?

repo是一种代码版本管理工具,它是由一系列的Python脚本组成,封装了一系列的Git命令,用来统一管理多个Git仓库。

2. 为什么要用repo?

因为Android源码引用了很多开源项目,每一个子项目都是一个Git仓库,每个Git仓库都有很多分支版本,为了方便统一管理各个子项目的Git仓库,需要一个上层工具批量进行处理,因此repo诞生。

repo也会建立一个Git仓库,用来记录当前Android版本下各个子项目的Git仓库分别处于哪一个分支,这个仓库通常叫做:manifest仓库。

3. 怎么安装repo?

官方的repo脚本下载方法:

curl http://commondatastorage.googleapis.com/git-repo-downloads/repo >  ./repo

由于官网被墙,目前可以使用的repo脚本下载方法如下(两者选一):

$ git clone git://git.omapzoom.org/git-repo.git
$ git clone git://aosp.tuna.tsinghua.edu.cn/android/git-repo.git/  

$ cp git-repo/repo  ./repo

或者修改手头已有的被墙的repo文件:

REPO_URL = ‘git://git.omapzoom.org/git-repo.git‘
REPO_URL = ‘git://aosp.tuna.tsinghua.edu.cn/android/git-repo‘ 

REPO_REV = ‘stable‘

当然,你也可以去我的GitHub下载这个repo文件,地址:

https://github.com/Jhuster/AOSP/blob/master/repo

4. 怎么下载源码?

上面说过,Android源码分支其实由一个叫manifest仓库来管理起来的,因此,下载源码首先要clone这个manifest仓库。这个仓库里面有一个XML文件,其实就是一个文件清单,列出了本代码仓库依赖哪些代码,该去哪下载,分支是什么。

一般用repo init命令来clone这个manifest仓库,例如,如果要下载Android源码,则方法如下:

$ repo init -u https://android.googlesource.com/platform/manifest

当然,上面的官网被墙了,因此,推荐如下镜像(两者选一):

$ repo init -u git://git.omapzoom.org/platform/manifest.git
$ repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest

初始化完毕后,你会在本地的.repo文件夹中看到manifest仓库的内容,这个文件夹中最重要的文件是manifest.xml(有的仓库用的是default.xml,然后指向具体的xml),它就是上面说到的文件清单。

如果要选择特定版本的Android源码,或者在已下载的源码基础上切换到其他版本,则可以使用-b选项:

$ repo init -u git://git.omapzoom.org/platform/manifest.git -b android-5.0.2_r1 
$ repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest -b android-5.0.2_r1

然后使用 repo sync 命令进行同步即可下载好全部的Android源码了。

5. manifest.xml文件清单的组成

上面提到了repo init需要初始化一个manifest仓库,仓库中含有一个很重要的manifest.xml文件清单,其实这个manifest.xml并不复杂的,它就是用XML文件的格式记录了本项目依赖的各个Git仓库的名称、地址,以及分支等信息。常用的元素如下所示:

(1) manifest 最顶层的XML元素

(2) remote  设置远程git服务器的属性,如名称、根URL地址等

(3) project 需要clone的Git仓库,path表示本机路径,name表示远程版本库的相对路径

(4) copyfile 执行拷贝操作,把URL/$src地址的文件拷贝到./$dest

其实,如果不使用repo工具,也是可以对照manifest.xml文件清单直接使用“git clone”的方式一个project一个project的下载的,然后对每个project进行git checkout特定的分支。

7. 常用repo命令

这一块网上文章很多,我就不详细讲解了,只列出常用命令。

(1) repo init   // 初始化repo仓库

(2) repo sync   // 下载源码

(3) repo start  // 创建分支

(4) repo checkout //切换分支

(5) repo branches //查看分支

(6) repo status   //查看文件状态

下面对其中的命令进行详细介绍:

1. repo init

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

  在当前目录下安装 Repo。这会产生一个 .repo/ 目录,目录包括装 Repo 源代码和标准 Android 清单文件的 Git 仓库。.repo/ 目录还包括 manifest.xml,是一个在 .repo/manifests/ 目录选择清单的符号链接。

  选项:

-u: 指定Manifest库的Git访问路径。 
-m: 指定要使用的Manifest文件。 
-b: 指定要使用Manifest仓库中的某个特定分支。 
–repo-url: 指定要检查repo是否有更新的远端repoGit库的访问路径。 
–no-repo-verify: 指定不检查repo库是否需要更新。

2. repo sync

repo sync [project_name]
 
 
  • 1

  用于参照清单文件克隆并同步版本库。可以使用repo sync project_name的形式只克隆某个项目。。

  实现参照清单.repo/manifests.xml克隆并同步版本库,如果版本库不存在,则相当于执行

git clone
 
 
  • 1

  如果版本库已经存在,则相当于执行

#对每个remote源进行fetch操作
git remote update
#针对当前分支的跟踪分支进行rebase操作
git rebase/origin/branch
 
 
  • 1
  • 2
  • 3
  • 4

  选项:

-d:切换指定项目回到清单修正。如果该项目目前是一个主题分支那就有帮助,但清单修正是暂时需要。 
-s:同步到一个已知的构建 manifest-server 在当前清单指定的元素。 
-f:继续同步其他项目,即使有项目同步失败。

3. repo start

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

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

repo start stable --all
 
 
  • 1

  假设清单文件中设定的分支是gingerbread-exdroid-stable,那么执行以上指令就是对所有项目,在gingerbread-exdroid-stable的基础上创建特性分支stable。

repo start stable platform/build platform/bionic
 
 
  • 1

  假设清单文件中设定的分支是gingerbread-exdroid-stable,那么执行以上指令就是对platform/build、platform/bionic项目,在gingerbread-exdroid-stable的基础上创建特性分支stable。

4. repo checkout

 <branchname> [<rpoject>...]{{{
   repo checkout <branchname> [<project>...]
 }}} 
 
 
  • 1
  • 2
  • 3

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

  示例:

repo checkout liuq-dev
repo checkout liuq-dev skipper/build platform/bionic
 
 
  • 1
  • 2

5. repo branches

repo branches [<project>...]
 
 
  • 1

  查看分支。 
  示例:

repo branches
repo branches skipper/build skipper/release
#查看可切换的分支
cd .repo/manifests
git branch -a | cut -d / -f 3
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

6. repo diff

repo diff [<project>...]
 
 
  • 1

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

#查看所有项目
repo diff
#只查看其中的两个项目
repo diff skipper/build skipper/release
 
 
  • 1
  • 2
  • 3
  • 4

7. repo stage

repo stage -i [<project>...]
 
 
  • 1

  把文件添加到index表中。实际上是对git add –interactive命令的封装,用于挑选各个项目中的改动以加入暂存区。 
  -i表示git add –interactive命令中的–interactive,给出一个界面供用户选择。

8. repo prune

repo prune [<project>...]
 
 
  • 1

  删除已经合并分支。实际上是对git branch -d 命令的封装,该命令用于扫描项目的各个分支,并删除已经合并的分支。

9. repo abandon

repo abandon <branchname> [<rpoject>...]
 
 
  • 1

  删除指定分支。实际是对git brance -D命令的封装。

10. repo status

repo status [<project>...]
 
 
  • 1

  查看文件状态。 
  示例:

#输出skipper/build项目分支的修改状态
repo status skipper/build
 
 
  • 1
  • 2

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

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

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

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

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

11. repo remote

repo remote add <remotename> <url> [<project>...]
repo remote rm <remotename> [<project>...]
 
 
  • 1
  • 2

  设置远程仓库。 
  示例:

repo remote add org ssh://10.11.10.11/git_repo
 
 
  • 1

  这个指令根据xml文件添加的远程分支,方便于向服务器提交代码,执行之后的build目录下看到新的远程分支org。

#删除远程仓库
repo remote rm org
 
 
  • 1
  • 2

12. repo push

repo push <remotename> [--all|<project>...]
 
 
  • 1

  向服务器提交代码。repo会自己查询需要向服务器提交的项目并提示用户。 
  示例:

repo push org
 
 
  • 1

13. repo forall

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

  迭代器,可以在所有指定的项目中执行同一个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指令括起来。

13.1. 添加环境变量
repo forall -c 'echo $REPO_PROJECT'
repo forall -c 'echo $REPO_PATH'
 
 
  • 1
  • 2
13.2. 合并多个分支
repo forall -p -c git merge topic
 
 
  • 1

  把所有项目都切换到master分支,执行上述指令将topic分支合并到master分支。

13.3. 打标签
repo forall -c git tag crane-stable-1.6
 
 
  • 1

  在所有项目下打标签。

13.4. 设置远程仓库
repo forall -c 'git remote add korg ssh://xiong@172.16.31/$REPO_PROJECT.git'
 
 
  • 1

  引用环境变量REPO_PROJECT添加远程仓库。

#删除远程仓库。
repo forall -c git remote rm korg
 
 
  • 1
  • 2
13.5. 创建特性分支
repo forall -c git branch crane-dev
repo forall -c git checkout -b crane-dev
 
 
  • 1
  • 2

14. repo grep

repo grep {pattern | -e pattern} [<project>...]
 
 
  • 1

  打印出符合某个模式的行。相当于对 git grep 的封装,用于在项目文件中进行内容查找。 
  示例:

#要找一行, 里面有#define, 并且有'MAX_PATH' 或者 'PATH_MAX':
repo grep -e '#define' --and -\( -e MAX_PATH -e PATH_MAX \)
#查找一行, 里面有 'NODE'或'Unexpected', 并且在一个文件中这两个都有的.
repo grep --all-match -e NODE -e Unexpected
 
 
  • 1
  • 2
  • 3
  • 4

15. repo manifest

repo manifest [-o {-|NAME.xml} [-r]]
 
 
  • 1

  manifest检验工具,用于显示manifest文件内容。 
  选项:

-h, –help 显示这个帮助信息后退出 
-r, –revision-as-HEAD 把某版次存为当前的HEAD 
-o -|NAME.xml, –output-file=-|NAME.xml 把manifest存为NAME.xml

16. repo version

repo version
 
 
  • 1

  显示repo的版本号。 
  选项:

-h, –help 显示这个帮助信息后退出.

17. repo upload

repo upload [--re --cc] {[<project>]...|--replace <project>}
 
 
  • 1

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

-h, –help 显示帮助信息 
-t 发送本地分支名称到Gerrit代码审核服务器 
–replace 发送此分支的更新补丁集 
–re=REVIEWERS 要求指定的人员进行审核 
–cc=CC 同时发送通知到如下邮件地址

18. repo download

repo download {project change[/patchset]}...
 
 
  • 1

  repo download命令主要用于代码审核者下载和评估贡献者提交的修订。 
  贡献者的修订在Git版本库中refs/changes//引用方式命名(缺省的patchset为1),和其他Git引用一样,用git fetch获取,该引用所指向的最新的提交就是贡献者待审核的修订。 
  使用repo download命令实际上就是用git fetch获取到对应项目的refs/changes//patchset>引用,并自动切换到对应的引用上。

19. repo selfupdate

repo selfupdate
 
 
  • 1

  用于 repo 自身的更新。如果有新版本的repo存在, 这个命令会升级repo到最新版本。通常这个动作在repo sync时会自动去做, 所以不需要最终用户手动去执行。 
  选项:

-h, –help 显示这个帮助信息后退出. 
–no-repo-verify 不要验证repo源码.

20. repo help

repo help [--all|command]
 
 
  • 1

  显示命令的详细帮助。 
  选项:

-h, –help 显示这个帮助信息后退出 
-a, –all 显示完整的命令列表





To make edits to changes after they have been uploaded, you should use a tool like git rebase -i or git commit --amend to update your local commits. After your edits are complete: Make sure the updated branch is the currently checked out branch. For each commit in the series, enter the Gerrit change ID inside the brackets: # Replacing from branch foo [ 3021 ] 35f2596c Refactor part of GetUploadableBranches to lookup one specific... [ 2829 ] ec18b4ba Update proto client to support patch set replacments # Insert change numbers in the brackets to add a new patch set. # To create a new change record, leave the brackets empty. After the upload is complete the changes will have an additional Patch Set. If you only want to upload the currently checked out Git branch, you can use the flag --current-branch (or --cbr for short). diff repo diff [<PROJECT_LIST>] Shows outstanding changes between commit and working tree using git diff. download repo download <TARGET> <CHANGE> Downloads the specified change from the review system and makes it available in your project's local working directory. For example, to download change 23823 into your platform/build directory: repo download platform/build 23823 A repo sync should effectively remove any commits retrieved via repo download. Or, you can check out the remote branch; e.g., git checkout m/master. Note: There is a slight mirroring lag between when a change is visible on the web in Gerrit and when repo download will be able to find it for all users, because of replication delays to all servers worldwide. forall repo forall [<PROJECT_LIST>] -c <COMMAND> Executes the given shell command in each project. The following additional environment variables are made available by repo forall: REPO_PROJECT is set to the unique name of the project. REPO_PATH is the path relative to the root of the client. REPO_REMOTE is the name of the remote system from the manifest. REPO_LREV is the name of the revision from the manifest, translated to a local tracking branch. Used if you need to pass the manifest revision to a locally executed git command. REPO_RREV is the name of the revision from the manifest, exactly as written in the manifest. Options: -c: command and arguments to execute. The command is evaluated through /bin/sh and any arguments after it are passed through as shell positional parameters. -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: show messages the command writes to stderr. prune repo prune [<PROJECT_LIST>] Prunes (deletes) topics that are already merged. start repo start <BRANCH_NAME> [<PROJECT_LIST>] Begins a new branch for development, starting from the revision specified in the manifest. The <BRANCH_NAME> argument should provide a short description of the change you are trying to make to the projects.If you don't know, consider using the name default. The <PROJECT_LIST> specifies which projects will participate in this topic branch. Note: "." is a useful shorthand for the project in the current working directory. status repo status [<PROJECT_LIST>] Compares the working tree to the staging area (index) and the most recent commit on this branch (HEAD) in each project specified. Displays a summary line for each file where there is a difference between these three states. To see the status for only the current branch, run repo status. The status information will be listed by project. For each file in the project, a two-letter code is used: In the first column, an uppercase letter indicates how the staging area differs from the last committed state. 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 In the second column, a lowercase letter indicates how the working directory differs from the index. 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 Was this page helpful? Let us know how we did:
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值