git submodule 和git repo介绍
这是一个 Git 子模块(submodule)管理问题。当一个 Git 仓库(主仓库)中包含多个其他 Git 仓库(子仓库)时,最推荐的做法是使用 Git 子模块 或 Git 子树(subtree) 进行管理。
✅ 方案一:使用 Git 子模块(推荐)
适合需要保持每个子仓库独立开发、独立版本控制的情况。
🔧 使用方法
1. 添加子模块
git submodule add <子仓库地址> <子目录路径>
例:
git submodule add https://github.com/user/libfoo.git third_party/libfoo
2. 初始化和更新子模块(拉代码后)
git submodule init
git submodule update
或直接使用:
git submodule update --init --recursive
3. 拉取主仓库时带上子模块
git clone --recurse-submodules <主仓库地址>
4. 更新子模块内容(从远程)
cd 子模块路径
git pull origin main
5. 如果你修改了子模块,记得在主仓库也 git add
记录子模块新引用。
✅ 方案二:使用 Git 子树(subtree)
适合你想把子仓库代码直接融合到主仓库,统一提交,但偶尔同步子仓库更新。
git subtree add --prefix=third_party/libfoo https://github.com/user/libfoo.git main --squash
然后你可以更新它:
git subtree pull --prefix=third_party/libfoo https://github.com/user/libfoo.git main --squash
⚠️ 如果你直接把多个 .git
仓库嵌套
如果你在一个 Git 仓库目录中直接 git clone
了多个其他仓库的子目录,就会出现多个 .git/
,这并不会被主仓库追踪,容易混乱。建议换成上面两种正规方式来管理。
📝 总结
方式 | 特点 | 推荐场景 |
---|---|---|
子模块 | 轻量,子仓库独立存在,适合组件化开发 | 独立开发、引用外部库 |
子树 | 代码直接嵌入主仓库,适合一次性集成或者不频繁更新的依赖 | 想让仓库独立,无需太多外部依赖 |
多 .git 嵌套 | 非标准管理,容易出错 | ❌ 不推荐 |
好的!你既然想系统了解 Repo 工具,那我就以教科书式的方式,全面、详细、通俗易懂地给你介绍这个工具的来龙去脉、核心概念、原理、使用方法、示例项目等。
📦 Repo 工具详解(Google 开发的 Git 多仓库管理工具)
一、📖 什么是 Repo 工具?
Repo 是 Google 开发的一个命令行工具,用来统一管理多个 Git 仓库。
它最早用于 Android 系统源码的管理,因为 Android 系统是由几百甚至上千个 Git 仓库组成的一个工程,传统的 Git 无法高效管理。
✅ Repo 是一个「Git 的封装器(wrapper)」,不替代 Git,而是在 Git 的基础上工作。
二、📌 Repo 解决了什么问题?
假设场景:
你要参与一个系统项目,代码由如下 5 个仓库组成:
仓库名 | 路径 |
---|---|
bootloader.git | bootloader/ |
kernel.git | kernel/ |
system.git | system/ |
apps.git | apps/ |
drivers.git | drivers/ |
如果你用 Git:
- 你需要一个一个 clone,搞清楚每个仓库放哪、用哪个分支、哪个版本。
- 改完一个仓库要手动记录更新,容易忘、容易错。
如果你用 Repo:
- 一份 manifest 文件(XML)就能定义所有仓库和它们的位置。
- 一条命令
repo sync
就能把所有仓库都拉下来。 - 统一提交/管理,团队协作也方便。
三、🔧 Repo 的核心结构和原理
1️⃣ .repo/
目录
这是 repo 项目的核心管理目录。
your_project/
├── .repo/
│ ├── manifest.xml ← 定义了所有 Git 仓库信息
│ ├── manifests/ ← 多个 manifest 文件
│ ├── manifests.git/ ← 存放 manifest 的 Git 仓库
│ └── repo/ ← repo 脚本本身
2️⃣ manifest.xml(配置清单文件)
这是一个 XML 文件,告诉 repo:
- 要 clone 哪些 Git 仓库?
- 每个仓库放在哪个子目录?
- 默认使用哪个分支?
- 哪些仓库是必须的?
示例(简化):
<manifest><remote name="origin"fetch="https://example.com/git/" /><default remote="origin" revision="main" /><project name="kernel.git" path="kernel" /><project name="bootloader.git" path="bootloader" />
</manifest>
四、🧪 实战:使用 Repo 工具的完整流程
✅ 环境准备
安装 repo 工具:
# 推荐方法:从 Google 官方下载
mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH # 添加到环境变量
✅ 初始化仓库(第一次)
mkdir myproject && cd myproject
repo init -u https://android.googlesource.com/platform/manifest
参数说明:
-u
是 manifest 仓库的地址- 你也可以加
-b 分支名
指定默认分支
✅ 同步所有代码
repo sync
它会自动 clone 所有仓库,并 checkout 到指定分支。
✅ 查看当前有哪些仓库
repo list
✅ 提交代码
repo start mybranch --all # 所有仓库都建一个分支
# 或只对当前目录建分支
repo start mybranch .# 修改、commit 后
repo status
repo diff
repo upload # 提交改动(上传到 Gerrit 或类似平台)
五、🧰 常用 repo 命令总结
命令 | 作用 |
---|---|
repo init | 初始化一个 repo 项目(从 manifest) |
repo sync | 同步所有仓库的代码 |
repo start | 给所有仓库创建分支 |
repo status | 查看所有仓库的状态 |
repo diff | 查看当前改动 |
repo upload | 提交更改(上传到代码审查平台) |
repo forall -c "命令" | 对所有仓库执行某个命令 |
示例:
repo forall -c "git pull"
六、🎯 使用场景
场景 | 是否适合用 Repo |
---|---|
Android 系统源码 | ✅ 完美适配 |
鸿蒙 OS / OpenEuler 等大系统 | ✅ 很多都用 Repo |
多个模块组件协作项目 | ✅ 如果用 Git 管理多个模块 |
小项目 / 单仓库 | ❌ 没必要,用 Git 就够了 |
七、🚨 注意事项
- repo 工具依赖 manifest 仓库,不能随意删除
.repo/
- 所有子仓库其实都是 Git 仓库,你可以进到子目录用 git 命令操作
repo sync
有时比较慢,可以加-j8
并行加速- 如果你公司内部也用了 Repo,通常 manifest 是私有的,你需要公司内部地址
🧠 总结一句话记住:
Repo 工具就是用来统一管理多个 Git 仓库的工具,它让复杂的大工程变得有序可控。
如果你愿意,我可以:
- 手把手带你搭建一个 mini repo 项目做实战
- 或者帮你分析你现在遇到的项目是不是在用 repo 工具
你现在是在哪个项目里遇到了 repo?是 Android、RK SDK、还是鸿蒙、公司内系统?我可以给你提供对应的 manifest 示例和命令指南。