概述
Repo的使用离不开Git, Git 和 Repo 都是版本控制工具,但它们在使用场景和功能上有明显区别…
Git
- 定义:Git 是一个分布式的版本控制系统,由 Linus Torvalds 为 Linux 内核开发而设计,现已成为世界上最流行的版本控制软件之一。
- 功能:Git 能够高效地追踪文件和目录的历史变更,支持分支和合并、提交历史记录、回滚更改、解决冲突等功能。它允许开发者在本地创建仓库并进行完整的版本控制操作,包括克隆、添加、提交、推送、拉取、合并等。
Repo
- 定义:Repo 是 Google 开发的一个高级工具,它是基于 Python 编写的一个脚本集合,主要用来管理和协调多个 Git 仓库的工作。
- 功能:Repo 主要针对大型项目,特别是那些包含了大量相互依赖的子模块或者子项目的工程,如 Android 开源项目 (AOSP)。Repo 可以简化对这些子仓库的初始化、同步、分支管理、提交以及推送等操作。它通过 manifest 文件来描述所有子项目的配置和依赖关系,从而提供了一种在顶层统一管理多个 Git 仓库的方法。
总的来说,
- Git 是单个项目的版本控制系统。
- Repo 是在 Git 之上构建的工具,用于大规模分布式开发环境中的多仓库协同管理。
使用 Repo 的好处在于能够方便地同时处理和同步多个相关联的 Git 仓库,简化复杂项目中跨仓库的日常版本控制任务。
使用REPO
国内的环境建议用mirrors.tuna.tsinghua.edu.cn 镜像
-
下载
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o ~/bin/repo chmod +x repo
为了方便可以将其拷贝到你的
PATH
里。更新
repo的运行过程中会尝试访问官方的git源更新自己,如果想使用tuna的镜像源进行更新,可以将如下内容复制到你的
~/.bashrc
里export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
并重启终端模拟器。
-
同步/更新
repo sync [project0 project1 ... projectn] repo sync [/path/to/project0 ... /path/to/projectn]
-
初始化/init
repo init -u url [options]
在当前目录中安装 Repo。此命令会创建一个
.repo/
目录,其中包含存放 Repo 源代码和标准 Android 清单文件的 Git 代码库。选项:
u
:指定从中检索清单代码库的网址。常见清单位于https://android.googlesource.com/platform/manifest
。m
:选择代码库中的清单文件。如果未选择清单名称,则默认为default.xml
。b
:指定修订版本,即特定的 manifest-branch。
注意对于所有剩余的 Repo 命令,当前的工作目录必须是
.repo/
的父目录或该父目录的子目录。当输入空的URL初始化, 报错. python 改为 python3 即可
ubuntu@SERVER4:/disk4/repoTest$ repo init Downloading Repo source from https://mirrors.tuna.tsinghua.edu.cn/git/git-repo remote: Enumerating objects: 8731, done. remote: Counting objects: 100% (4959/4959), done. remote: Compressing objects: 100% (2487/2487), done. remote: Total 8731 (delta 4744), reused 2472 (delta 2472), pack-reused 3772 Receiving objects: 100% (8731/8731), 3.01 MiB | 4.60 MiB/s, done. Resolving deltas: 100% (6011/6011), done. Traceback (most recent call last):File "/home/user/bin/repo", line 1490, in <module>main(sys.argv[1:])File "/home/user/bin/repo", line 1440, in main_Init(args, gitc_init=(cmd == "gitc-init"))File "/home/user/bin/repo", line 691, in _Initos.rename(dst, dst_final) OSError: [Errno 39] Directory not empty: '/disk4/repoTest/.repo/repo.tmp' -> '/disk4/repoTest/.repo/repo'
搭建Repo仓库(服务端)
- 搭建基于gitolite的GIT服务器 192.168.7.3
- 默认创建的几个git仓库
-
2.1. gitolite-admin : 用于管理git仓库和用户秘钥 [自动创建]
-
2.2. manifest: 特殊Git仓库, repo通过此项目来获取仓库, 它包含了项目的清单(manifest)文件。仓库任意名称[手动创建]
default.xml 或者 manifest.xml 这是最重要的文件之一,定义了项目树状结构、各个子项目的URL、分支、标签以及其他同步策略等信息。每个项目对应一个
<project>
标签,并且包含项目路径、git仓库URL等属性groups.xml:可能存在的文件,用于定义不同的项目组,以便于根据开发团队的不同需求或者权限来下载不同的子项目集合。
other-manifests/ 目录: 该目录下可能有多个针对不同构建目标或版本的manifest文件,如
android-9.0.0.xml
等。 -
2.3. test: 测试项目 [自动创建]
-
- 配置repo的manifest: 只需要一个文件- default.xml
-
default.xml
<?xml version="1.0" encoding="UTF-8"?> <manifest><remote name="codes" fetch="."/><default remote="codes" sync-j="4"/><project name="project_1" revision="master"/><project name="project_2" revision="master"/> </manifest>
-
manifest文件定义了这些仓库的基本布局和同步规则。配置含义如下:
<remote name="codes" fetch="."/>
:定义了一个远程仓库,名字叫做codes
,其fetch地址为.
。这里的.
代表当前目录,意味着所有的项目都位于本地同一个父目录下,不需要从远程服务器拉取代码。<default remote="codes" sync-j="4"/>
:设置默认的远程仓库为刚刚定义的codes
,并且设置了sync-j
属性为4,这意味着在执行repo sync命令时,将会并发运行4个jobs(任务)来并行拉取和更新各个项目。<project name="project_1" revision="master"/>
:定义了一个名为project_1
的项目,其对应的Git仓库的分支或者提交哈希为master
,repo会在同步时检查并确保该项目处于master
分支的最新状态。<project name="project_2" revision="master"/>
:类似地,定义了另一个名为project_2
的项目,同样指向master
分支。
文件描述了一个由两个Git项目(project_1和project_2)组成的代码仓库集合,它们都将从本地的codes
远程仓库同步,并且在同步时默认使用master
分支,并且同步过程可以并发执行四个任务以提高效率。
- 客户端下载同步
刚开始使用的文件名称: manifest, 导致报错: 'default.xml’ not available
Downloading Repo source from https://mirrors.tuna.tsinghua.edu.cn/git/git-reporemote: Enumerating objects: 8731, done.remote: Counting objects: 100% (4959/4959), done.remote: Compressing objects: 100% (2487/2487), done.remote: Total 8731 (delta 4745), reused 2472 (delta 2472), pack-reused 3772Receiving objects: 100% (8731/8731), 3.01 MiB | 10.66 MiB/s, done.Resolving deltas: 100% (6012/6012), done.fatal: manifest 'default.xml' not availablefatal: manifest default.xml not found================================================================================Repo command failed: UpdateManifestErrorUnable to sync manifest default.xml
指定清单: repo init git@192.168.7.3:RepoTest -m other_manifest.xml
#download manifestsubuntu@SERVER4:/disk4/repoTest$ repo init -u git@192.168.7.3:manifestrepo: reusing existing repo client checkout in /disk4/repoTestrepo has been initialized in /disk4/repoTest#repo sync download all sourceubuntu@SERVER4:/disk4/repoTest$ repo syncFetching: 100% (2/2), done in 14.816sUpdating files: 100% (1050/1050), done.Checking out: 100% (2/2), done in 5.283srepo sync has finished successfully.
附录(仅供参考)
服务端文件结构:
$ sudo ls -l /home/git/repositories/
total 172
drwx------ 7 git git 4096 2月 19 15:14 project_1.git
drwx------ 7 git git 4096 2月 19 15:14 project_2.git
drwx------ 7 git git 4096 2月 19 15:14 RepoTest.git
drwx------ 7 git git 4096 2月 19 15:14 manifest.git
drwx------ 7 git git 4096 2月 19 15:14 test.git
$ tree RepoTest/RepoTest/├── other_manifest.xml└── default.xml
客户端文件
$ tree -L 1 -a RepoTest/RepoTest/├── project_1├── project_2└── .repo├── copy-link-files.json├── manifests│ ├── other_manifest.xml│ ├── default.xml│ └── .git -> ../manifests.git├── manifests.git├── manifest.xml├── project.list├── project-objects├── projects├── repo├── .repo_fetchtimes.json├── .repo_localsyncstate.json└── TRACE_FILE
常见错误
-
‘NoneType’ object has no attribute 'rstrip’ : 检查manifest配置, 非python错误
repo sync ================================================================================ Repo command failed: RepoUnhandledExceptionError'NoneType' object has no attribute 'rstrip'
参考
repo使用总结—从入门到入门
Repo实践指南
repo:从零开始搭建repo环境
搭建支持 Repo 的 Android 源码镜像(Repo 服务器)