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

Git repo工具使用教程

卫招
2023-12-01

参考文档:

git repo工具详细使用教程——彻底学会Android repo的使用git-repo大魔王爱学习的博客-CSDN博客

Manifest Format – git-repo: a git wrapper from Alibaba

一、关于repo

repo是Google开发的用于管理Android版本库的一个工具,repo是使用Python对git进行了一定的封装,并不是用于取代git,它简化了对多个Git版本库的管理。用repo管理的版本库都需要使用git命令来进行操作。因此,使用repo工具之前,请先确保已经安装git。 为什么要用repo? 项目模块化/组件化之后各模块也作为独立的 Git 仓库从主项目里剥离了出去,各模块各自管理自己的版本。Android源码引用了很多开源项目,每一个子项目都是一个Git仓库,每个Git仓库都有很多分支版本,为了方便统一管理各个子项目的Git仓库,需要一个上层工具批量进行处理,因此repo诞生。 repo也会建立一个Git仓库,用来记录当前Android版本下各个子项目的Git仓库分别处于哪一个分支,这个仓库通常叫做:manifest仓库(清单库)。

二、repo工具安装

2.1 环境要求

需要安装python,git

2.2 软件下载安装

$ curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > /usr/local/bin/repo
​
$ chmod 777 /usr/local/bin/repo

如果没有root权限,可以尝试官方安装方法,装在自己的home下

$ mkdir -p ~/.bin
$ PATH="${HOME}/.bin:${PATH}"
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
$ chmod a+rx ~/.bin/repo

其实下载下来的repo文件只是一个Python编写的引导脚本,完整的repo(即repo的主题部分)还没有下载。

repo版本查看

repo version

三、repo工具的使用

3.1 Manifest文件介绍

在使用repo工具前,需要准备一个存放manifest文件的git仓库。

所谓manifest仓库(清单库)其实就是存放manifest(清单)文件的仓库,实际上可以是任意仓库,只要该仓库中存在repo init命令-m选项指定的manifest文件即可,清单库命名为manifest只不过是一种约定俗成的写法罢了。manifest仓库一般都会有一个default.xml文件,该文件为默认的manifest文件。

manifest文件格式举例:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
    <remote fetch="ssh://git@git.software.team/learn-repo" name="origin" review="http://xxx.xxx.xxx:8080"/>
    <remote fetch="https://github.com" name="github" alias="origin"/>
    <default remote="origin" revision="master" sync-j="4" />
    <project name="build" path="build">
        <linkfile dest="build.sh" src="build.sh"/>
    </project>
    <project name="docs" path="docs">
        <copyfile dest="README.md" src="README.md"/>
    </project>
    <project name="third_party/openssl" path="third_party/openssl" revision="OpenSSL_1_1_1l" />
    <project name="curl/curl" path="third_party/curl" remote="github" />
    <project name="src" path="src" revision="release" />
</manifest>
  • remote元素 remote元素可以有多个,用于存在多个git远程服务器的情况。

fetch:使用此remote的所有项目的Git URL前缀。 每个项目的名称都附加到此前缀以形成用于克隆项目的实际 URL。如果使用此remote的所有项目的前缀和manifest仓库前置一致的话,可以使用..代替。 name:此清单文件唯一的短名称。此处指定的名称用作每个项目的 .git/config 中的远程名称,因此可自动用于 git fetch、git remote、git pull 和 git push 等命令。 review:通过repo upload将评论上传到的 Gerrit 服务器的主机名。 该属性是可选的; 如果未指定,则repo upload将不起作用。 alias:该属性可以省略,当指定了该属性时,可以覆盖name属性设置每个项目的.git/config中的远程名称。不同remote元素的alias属性可以相同,比如不同remote元素的alias属性可以都是origin。

groups属性:所有的projects都属于group ”all“,如果你只想下载部分project,你可以在初始化的时候加入-g选型。

$ repo init -u https://android.googlesource.com/platform/manifest -g all,-notdefault,tools

示例中的-g all,-notdefault,tools表示下载所有default的project和tools project。

  • default元素 default元素只能有一个。

remote:project部分不单独指定remote的话就使用default部分的。 revision:project部分不单独指定revision的话就使用default部分的。 sync-j:同步时(执行repo sync命令时)使用的并行作业数 sync_c:如果设置为true,则只同步指定的分支(revision 属性指定),而不是所有的ref内容 sync_s:如果设置为true,则会同步git的子项目

  • project元素 该部分定义了项目代码由哪些子仓库组成

name:相对于remote部分fetch指定的前缀的相对路径 path:把代码下载下来后在本地的相对于当前路径的相对路径 revision:是指下载下来的代码要checkout到哪个revision上,这里的revision可以是commit id、branch name、tag name,本质上都是commit id。default.xml中通常用branch name做revision,可以下载到并且checkout出该branch上最新的代码,标签和/或commit id在理论上应该有效,但尚未经过广泛测试。如果revision用commit id的话,那后面必须跟上upstream,upstream的值是个branch name。revision部分如果省略的话,就等于使用default部分定义的revision。 remote:前面定义的远程元素的名称。如果未提供,则使用默认元素提供的值。

  • copyfile元素 project元素的子元素,每个元素描述了一对 src-dest 文件对。同步时(即执行repo sync命令时)src文件会被拷贝到dest。通常会被用于 README 或 Makefile 或其他构建脚本。 dest:是相对于当前目录(执行repo init和repo sync命令的目录)的路径 src:是相对于project path的相对路径
  • linkfile元素 与copyfile类似,只不过不是拷贝,而是建立软连接。

3.2 repo init

3.2.1 repo源设定

执行repo init时会下载repo的主体部分,并放在当前目录的.repo/repo目录下。

repo主体部分默认从https://gerrit.googlesource.com/git-repo获取,这个网站需要科学上网才可以访问。

可以使用其他镜像源来获取,如清华源。下面列举两种方式解决repo源问题:

方法一:

每次执行repo init时,增加选项:--repo-url=git-repo - Git at Google 指定repo源。

方法二:(推荐)

设置环境变量REPO_URL

export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'

可以将环境变量写在/etc/profile或~/.bashrc中

3.2.2 repo init命令格式

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

示例:

repo init -u "ssh://username@gerrit.company.com:29418/common/manifest" --no-repo-verify

选项:

-u: 指定Manifest库的Git访问路径。 -m: 指定要使用的Manifest文件,默认是defalut.xml -b: 指定要使用Manifest仓库中的某个特定分支 –repo-url: 指定repo主题代码源 –no-repo-verify: 指定不检查repo库是否需要更新。

执行repo init命令后,会在当前目录创建一个.repo隐藏文件夹。

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

3 directories, 1 file

文件夹 描述 manifests manifest仓库(清单库)内容,即repo init的-u选项对应的仓库 manifests.git manifest仓库(清单库)的.git目录 manifest.xml 指明当前生效的Manifest文件,即repo init的-m选项对应的参数(没有该选项时默认为default.xml) repo repo 命令的主体,包含了最新的 repo 命令

3.3 repo sync

repo sync命令格式:

repo sync [project_name]

初始化好一个repo工作目录后下一步就是把代码同步下来了,repo sync命令用于参照清单文件克隆并同步版本库。可以使用repo sync project_name的形式只克隆某个项目。如果repo sync不加任何参数,则该操作会同步所有项目(所有项目是指manifest文件中所有的project元素)。

<project_name>:为manifest文件中project元素的name属性或者path属性的值。如果只需要同步某一个或者个别几个项目的话,就可以采用这种方法。

  • 如果目标项目从未同步过,则 repo sync 相当于 git clone。远程代码库中的所有分支都会复制到本地项目目录中。

  • 如果目标项目已同步过,则 repo sync 相当于以下命令:

#对每个remote源进行fetch操作
git remote update
#针对当前分支的跟踪分支进行rebase操作
git rebase origin/<BRANCH>

选项:

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

问题:repo sync后git branch -a显示中”no branch“和”remotes/m/master“的含义

使用repo工具同步代码后,进入任意项目路径下,执行git branch -a输出如下:

[root@node02 linux]# git branch -a
* (no branch)
  remotes/m/master -> origin/master
  remotes/origin/master

输出的第一行 * (no branch) 中的 * 表示当前所在的分支,该行意思是,当前不再任何分支上。

为什么会显示no branch 呢? repo sync 只是根据清单文件中 revision 版本进行更新的,没有固定的branch,repo sync 成功之后,不能直接进行操作,需要先执行 repo start 建立新的分支进行开发。

其实,执行 repo branches 命令也会显示 no branches 的,这个就更好理解了,不同的子仓库的 revision 不尽相同,所有git仓库放在一起,更是没有一个确切的branch了。

3.4 repo start 创建主题分支

repo sync后可以使用repo list查看当前所有的项目:

repo list

需要进行repo start创建分支后才能在各项目上进行修改等操作,

命令格式:

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

创建并切换分支。刚clone下来的代码是没有分支的,repo start实际是对git checkout -b命令的封装。

repo start 与 git checkout -b 的区别:

  • repo start 是在清单文件设定的分支基础上创建新的分支

  • git checkout -b 是在当前所在分支的基础上创建新的分支

如果平时是在master上进行代码开发,则使用进行分支的切换:

repo start master project1  # 将project1切到master分支
repo start master --all # 将所有project切到master分支

3.5 repo 其他命令

repo命令都是对git命令的封装,相当于是对所有的project运行了同样的git命令:

查看项目代码所在分支:

repo branch

查看文件状态:

repo status [<project>...]

切换分支

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

查看工作区文件差异:

repo diff [<project>...]

在每个项目中运行指定的 shell 命令:

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

示例:

打印项目列表
repo forall -c 'echo $REPO_PROJECT'
打印项目路径
repo forall -c 'echo $REPO_PATH'
清理本地代码:
repo forall -c git reset --hard HEAD

显示当前使用的manifest文件内容

repo manifest

从gerrit代码审核中下载指定更改,并反正本地工作目录中:

例如,将更改http://gerrit.company.com/c/common/testrepo/+/5419 下载到本地目录,可运行一下命令:

repo download common/testrepo 5419

repo sync 可以有效移除通过 repo download 检索到的任何提交。

3.6 子仓代码提交

repo工具主要用于代码的下载管理,关于代码下载建议还是进入到各个下载好的子仓目录进行git操作。与之前的代码提交命令一样的。

git status
git add 
git commit
git push origin HEAD:refs/for/master

 类似资料: