repo 本质是谷歌开发的一款多仓库管理命令行工具,它的核心作用就是把多个独立的 Git 仓库统一编排管理,解决大型项目里 Git 只能单独管理单个仓库的短板,很多安卓源码这类超大型项目,会拆成几十上百个 Git 子仓库,单独逐个拉取更新非常繁琐,repo 就是用来批量同步批量提交批量切换分支的上层封装工具,底层依然依赖 Git 本身,并不是替代 Git,它本身还会自带一个清单仓库,也就是 manifest 仓库,这个清单文件记录所有子仓库的地址分支路径等配置信息,repo 所有操作都是读取这份清单,再自动对各个子仓库执行对应的 Git 操作。
为什么需要 repo
普通 Git 设计定位就是单仓库管理,一个 Git 仓库对应一套项目代码,但是大型嵌入式安卓系统类项目,会把内核驱动应用编译脚本拆分成大量独立 Git 仓库,每个仓库有自己的提交历史分支标签,如果只用原生 Git,开发者需要手动进入每一个仓库执行 clone pull checkout,跨仓库同步版本非常容易出错,还很难保证所有子仓库版本匹配一致。repo 就是为这个场景诞生,它把所有子仓库的版本绑定在 manifest 清单里,一次命令就可以完成全部子仓库的初始化同步,保证整套源码版本统一,减少人工操作失误,提升大型多仓项目的开发效率。
repo 基础工作流程
第一步安装 repo,一般是通过官方引导脚本下载 repo 启动器,给脚本添加可执行权限,这个启动器本身很小,运行之后会自动下载 repo 主体程序。
第二步初始化仓库,执行 repo init 命令,指定 manifest 清单仓库的地址,还可以指定分支,这一步会在当前目录创建.repo 隐藏目录,里面存放 manifest 配置和 repo 自身程序,此时还没有拉取业务子仓库代码。
第三步同步代码,执行 repo sync,程序读取 manifest 里面登记的全部子仓库地址,自动批量 clone 或者更新所有子仓库,把代码拉到本地对应目录。
第四步日常开发操作,常用命令包含 repo start 创建新分支,repo status 查看全部子仓库改动状态,repo diff 对比所有仓库改动,repo upload 提交改动到评审平台,repo forall 可以对所有子仓库循环执行自定义 Git 命令。
第五步版本维护,维护人员可以修改 manifest 清单,更新各个子仓库对应的 commit 版本号,这样其他开发者 init 和 sync 之后,就能拿到整套统一匹配的代码版本。
repo 和 Git 的核心区别表格
| 对比项 | repo | Git |
|---|---|---|
| 定位 | 多仓库上层管理工具 | 单仓库版本控制系统 |
| 底层依赖 | 必须依赖 Git | 独立版本控制软件 |
| 管理对象 | 多个 Git 子仓库加 manifest 清单 | 单个 Git 仓库 |
| 典型场景 | 安卓源码大型多仓项目 | 普通单项目代码管理 |
| 核心能力 | 批量同步批量操作跨仓版本绑定 | 版本提交分支合并标签管理 |
补充关键知识点
manifest 是 repo 最核心的配置文件,一般是 xml 格式,里面定义每一个 project 也就是子仓库,包含仓库远程地址本地存放路径分支,还可以配置默认分支远程服务器,还有删除仓库局部覆盖配置等高级选项。repo forall 是非常高频的命令,可以遍历所有子仓库执行指定 shell 命令,比如批量查找批量打标签批量清理未提交改动。repo 本身是 Python 脚本实现,跨平台支持 Linux 和 macOS,Windows 原生支持较差,一般会搭配 WSL 使用。repo 还有权限与代码评审集成能力,原生设计就是对接 Gerrit 代码评审系统,repo upload 就是把各个子仓库的 commit 推送到 Gerrit 评审队列。
总结来说,repo 不是新的版本控制系统,它是 Git 的配套调度工具,专门解决多 Git 仓库协同开发的痛点,核心依靠 manifest 清单绑定全部子仓库版本,适合超大型分布式多仓源码工程,小型项目一般不需要引入 repo,直接使用原生 Git 就足够。
【常见问题】
问题 1 repo 是不是可以完全替代 Git
回答 1 repo 不能替代 Git,repo 底层所有版本操作仍然调用 Git 命令,repo 只是上层封装,负责多仓库调度,所有提交历史分支管理的核心能力依旧由 Git 提供,日常开发还是会经常直接在子仓库里面执行 Git 命令。
问题 2 repo init 的作用是什么
回答 1 repo init 是初始化 repo 工程,主要是拉取 manifest 清单仓库,建立.repo 隐藏目录,选定清单对应的分支,完成 repo 环境准备,这个阶段还不会同步所有业务子仓库代码,必须再执行 repo sync 才会拉取源码。
问题 3 repo sync 和普通 git pull 有什么不同
回答 1 git pull 只针对当前这一个 Git 仓库做拉取更新,repo sync 会读取 manifest 清单,一次性对清单登记的全部子仓库批量执行类似 fetch 和 checkout 的更新操作,保证整套多仓项目所有子仓库版本同步对齐。
问题 4 repo 里面 manifest 文件有什么作用
回答 1 manifest 是 repo 的核心清单文件,记录全部子仓库的远程地址本地路径默认分支以及对应的提交版本,repo 所有批量操作都依靠这份清单识别需要管理的 Git 仓库,修改 manifest 就可以切换整套项目的版本组合。
【免责申明】
本文内容仅作为技术知识科普讲解,repo 工具的命令参数行为会随版本迭代发生变化,实际生产开发请以官方原版文档为准,操作多仓库源码时请提前备份代码,错误执行批量命令可能造成本地代码改动丢失,本文不承担因操作失误产生的相关损失。
