当前位置: 首页 > 工具软件 > repo > 使用案例 >

repo入门和基本用法

漆雕宏浚
2023-12-01

repo是什么?

官方的定义:Repo是谷歌用Python脚本写的调用git的一个脚本,可以实现管理多个git库。

个人理解:repo这个工具,是一个脚本。这个脚本是对git库的管理。

类似什么呢,类似makfile。功能是使你简单一敲make,就ok了。repo 呢,简单一敲,repo init -u <url> <option> 。url 指的是 manifest仓库地址,option 一般是所在分支,比如-b 你的分支,就行了。再执行一句,repo sync 。刷刷刷,等待个几十个小 时,(网速好的,时间相对短一点)。就把你需要的安卓整个源码同步在本地了(几十个G这么大吧)。

值得提一下的是,为什么有repo这个功能?

repo呢,其实说来,就是很多个git clone 的集成,如果有一个工程,有一百个git,你下载下来,按逻辑是敲一百次git clone xxxx,下载下来。但是使用repo呢,只需要敲一次,喝喝茶,等待下载完成就可以了。

怎么使用?

第一步,得下载一个git,这个是大前提。

第二步,下载repo的源码,注意是源码。可以使用git clone xxx,在一些网站获取。

第三步,最好把repo配置环境变量,这样的话,在随便一个目录直接敲命令即可。否则,就写repo xxx之前,要在repo前面加repo的路径,像我的放在~/git-repo/里面,我就得每次这样敲 ~/git-repo/repo init -u xxx。

安装Repo

要安装 Repo,请执行以下操作:

1.安装GIT

省略

2.确保主目录下有一个 bin/ 目录,并且该目录包含在环境变量路径中:

$ mkdir ~/bin
$ PATH=~/bin:$PATH

3.下载 Repo 工具,并确保它可执行:

$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

初始化Repo客户端

安装 Repo 后,设置您的客户端以访问 Android 源代码代码库:
1.创建一个空目录来存放您的工作文件。如果您使用的是 MacOS,必须在区分大小写的文件系统中创建该目录。为其指定一个您喜欢的任意名称:

$ mkdir WORKING_DIRECTORY
$ cd WORKING_DIRECTORY

2.使用您的真实姓名和电子邮件地址配置 Git。要使用 Gerrit 代码审核工具,您需要一个与​已注册的 Google 帐号​关联的电子邮件地址。确保这是您可以接收邮件的有效地址。您在此处提供的姓名将显示在您提交的代码的提供方信息中。

$ git config --global user.name "Your Name"
$ git config --global user.email "you@example.com"

3.运行 repo init 以获取最新版本的 Repo 及其最近的所有错误更正内容。您必须为清单指定一个网址,该网址用于指定 Android 源代码中包含的各个代码库将位于工作目录中的什么位置。

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

初始化repo成功

我们要管理自己的仓库,所以要建立一个自己的manifest.git

建立自己的manifest.git

1.打开 WORKING_DIRECTORY 文件夹

2.进入.repo文件夹

3.进入manifest文件夹,修改其中的defaule.xml文件

大体格式如下:

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

<manifest>
    <remote name="local" fetch="git://localhost/" />
    <default remote="local" revision="master"/>
    <project path="hello" name="helo"/>
</manifest>

可以看到,根元素manifest,里边定义了remote,default,project.

remote可以多个,每个定义了一个远程拉取仓库,fetch是仓库的url, 可以使用”..”表示使用repo init -u url里的url

default则设置每个项目的默认仓库和默认分支

project定义了一个项目,它指明一个远程仓库,和clone到本地来后的目录名称。name为项目的远程仓库名,以上代码拉取的项目是git://localhost/helo

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote fetch="git://[http://xxx.xxx.xxx**]" name="origin" review="[http://xxx.xxx.xxx:8080**](https://link.zhihu.com/?target=http%3A//xxx.xxx.xxx%3A8080/)"/>
<default remote="origin" revision="main_dev"/>
<project name="platform/mediatek/modem/buildscript" path="buildscript">
<copyfile dest="m" src="m"/>
<copyfile dest="Make.bat" src="Make.bat"/>
<copyfile dest="make.pl" src="make.pl"/>
<copyfile dest="make.sh" src="make.sh"/>
<copyfile dest="M.bat" src="M.bat"/>
<copyfile dest="BuildMMAA.pl" src="BuildMMAA.pl"/>
</project><project name="platform/mediatek/modem/driver" path="driver"revision="352b1d8fb184a0169c6a17b5f6a858730fc51966"upstream="main_release" />
<project name="platform/mediatek/modem/make" path="make"revision="main_release" />
<project name="platform/mediatek/modem/middleware" path="middleware"revision="tag_20160316" />
<project name="platform/mediatek/modem/modem" path="modem" />
<project name="platform/mediatek/modem/mtk_rel" path="mtk_rel"/>
<project name="platform/mediatek/modem/custom" path="custom"/>
<project name="platform/mediatek/modem/tools" path="tools"/>
<project name="platform/mediatek/modem/interface" path="interface"/>
<project name="platform/mediatek/modem/service" path="service"/>
</manifest>

先看remote部分,fetch是服务器地址,可以用“..”来代替;name是默认的remote name,就是git push origin里面那个origin;review是gerrit地址(这点是我猜的,不确定)。

然后是default部分,里面定义了默认的remote和revision。

下面是project部分,这部分定义了整包代码由哪些git组成。name是git在服务器上的相对路径,path是把代码下载下来后在本地的相对路径,path是可以省略的,如果省略那么就认为path和name一样,revision是指下载下来的代码要checkout到哪个revision上,这里的revision可以是commit id、branch name、tag name,反正本质上都是commit id。

利用branch name的特性,revision写branch name的话,那总可以下载到并且checkout出该branch上最新的代码,default.xml中通常用branch name做revision。而commit id和tag name就是固定的某个commit了。如果revision用commit id的话,那后面必须跟上upstream,upstream的值是个branch name。revision部分如果省略的话,就等于使用default部分定义的revision。project还有个group属性,但我没实际用过,就不展开了。

还有copyfile部分,这是用来处理一些无法或者不方便直接归类到某个git中去的文件的,譬如项目代码根目录下的几个零散文件,这几个文件所在目录做成一个git的话,等于把整包代码做成了一个git。虽然git是可以嵌套的,但这样不方便。repo的做法是将这些文件先放到某个已知git中去,本例就是先放到project buildscript里面去。当然,放到某个git里去的动作是由你来做的。然后下载完后再将它们copy到应该在的地方,本例就是根目录下。dest是相对于根目录的路径,src是相对于project path的路径。

要管理的仓库 要管理的仓库是普通的git. 当以上一切准备完毕. 我们就可以

$ repo sync

远程仓库被拉取到了本地。


repo常用命令

repo start  ##创建并切换分支

repo start  newbranchname [--all | projectName]

repo start是对git checkout -b 命令的封装。这条指令与git checkout -b 还是有很大的区别的,git checkout -b 是在当前所在的分支的基础上创建特性分支,而repo start是在清单文件中设定的分支的基础上创建特性分支。例如:repo start  stable  --all(所有项目)

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

repo start  stable  platform/build platform/bionic

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

repo checkout 分支名称  ##默认是切换所有仓库中的分支

repo checkout 分支名称 本地仓库相对路径 ##切换指定仓库的分支

repo tmerge --branch-name 源分支名称 --merge-message 提交说明  ##分支合并命令,此命令会跳过那些公共仓库(即单独配置了reversion的仓库)

repo branch  ##查看分支

repo manifest  ##查看清单文件

repo list  ##列出本地下载的所有project的path和name,冒号分隔。

repo manifest -ro aaaaa.xml  ##生成tag文件

repo status(查看文件状态),是对git diff-index、git diff-filse命令的封装,同时显示暂存区的状态和本地文件修改的状态

repo abandon branchName ##删除分支

repo version  ##查看repo版本号

repo grep  ##在项目中进行内容查找

repo sync  ##默认同步所有仓,可以指定project 。

如果是第一次运行 repo sync ,则相当于 git clone,会把server所有内容都拷贝到本地。根据manifests中的xml文件中git的commit进行同步,这个xml文件在repo init的时候指定;
如果不是第一次运行 repo sync ,则相当于 git remote update ;  git rebase origin/branch 将server上的code与本地合并;如果在rebase 的过程中出现冲突,这需要手动解决冲突,然后运行:git  rebase --continue

注意:repo sync 是不会更新 .repo/repo这个仓的!

repo sync 的参数:

-j:开启多线程同步操作,会加快sync命令的执行速度。默认情况下,使用4个线程并发进sync。 

-c, –current-branch:只同步指定的远程分支。默认情况下,sync会同步所有的远程分支,当远程分支比较多的时候,下载的代码量就大。使用该参数,可以缩减下载时间,节省本地磁盘空间。 

-d, –detach:脱离当前的本地分支,切换到manifest.xml中设定的分支。在实际操作中这个参数很有用,当我们第一次sync完代码后,往往会切换到dev分支进行开发。如果不带该参数使用sync, 则会触发本地的dev分支与manifest设定的远程分支进行合并,这会很可能会导致sync失败。 

-f, –force-broken:当有git库sync失败了,不中断整个同步操作,继续同步其他的git库。 

–no-clone-bundle:在向服务器发起请求时,为了做到尽快的响应速度,会用到内容分发网络(CDN, Content Delivery Network)。同步操作也会通过CDN与就近的服务器建立连接, 使用HTTP/HTTPS的$URL/clone.bundle来初始化本地的git库,clone.bundle实际上是远程git库的镜像,通过HTTP直接下载,这会更好的利用网络带宽,加快下载速度。

repo init -u xxx/manifest.git -b xxx -m xxx --repo-url=git://codeaurora.org/tools/repo.git --repo-branch=caf-stable

repo相当于一个批处理文件,使用repo脚本可以一次下载多个Git 仓库的内容,避免多次git clone,并能进行更好的管理和使用。

用 repo 拿的时候其实 .git 统统会放在 .repo 里,然后外面的.git都只是link。

repo脚本有如下可用参数:

--repo-url=URL        repo 工具本身的 git 库地址。缺省为:git://android.git.kernel.org/tools/repo.git

--repo-branch=REVISION    使用repo的版本库,即repo git库的分支或者里程碑名称。缺省为caf-stable

--no-repo-verify                 设定不要对repo的里程碑签名进行严格的验证。

-u(--manifest-url)               设定清单库的Git服务器地址。

-b(--manifest-branch)        检出清单库的特定分支。

--mirror                              只在repo第一次初始化的时候使用,建立本地镜像

-m(--manifest-name)         指定清单库中的某个清单为有效的清单文件。默认为default.xml。

--no-tags                           don't fetch tags                                      

repo 命令参数的含义,可以执行repo help command(sync)来看。

命令rep init完成如下操作:

1.完成repo工具的完整下载,执行的repo脚本只是一个引导工具,并不是下载代码的脚本。

2.克隆清单库manifest.git到目录.repo/manifests/下。(地址来自于-u参数)

3.清单文件.repo/manifest.xml只是符号链接,它指向.repo/manifests/default.xml。

4.如果.repo/manifests/目录中有多个xml文件,repo init -m 参数可以任意选择其中一个,默认是default.xml。

清单文件解析:(前文已有)

一个清单库文件可以包含多个清单文件(标签include)和多个分支(标签revision)。

remote元素:<remote  fetch="../"  name="origin"  review="http://IP:8080"/>

属性fetch:下载的相对路径

属性name:远程版本库命

属性review:基址

default元素:<default remote="origin" revision="branch-name" sync-j="4"/>

设置默认版本库和分支。各个项目(project元素)可以定义自己的remote和revision覆盖默认的配置。

project元素:
<project name="device/mediatek/common" path="device/mediatek/common">
        <copyfile dest="mk" src="mk"/>
</project>

属性path:工作区克隆的位置
属性name:远程版本库的相对路径

子元素copyfile:定义了克隆后的一个附加动作,从src拷贝到dest

PS:以下命令非常有用!-p参数可以打印出project,注意顺序。

repo forall -p -c "git push origin HEAD:refs/heads/mtk_8.1_6763 2>&1 | tee" >> push.log

 类似资料: