子模块管理
EnderRealm 项目使用 Git 子模块来管理依赖的库和运行时环境。这个章节将教你如何管理子模块。
什么是子模块?
子模块(Submodule)是 Git 的一个功能,允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。它常用于:
- 管理依赖:将第三方库作为子模块引入
- 共享代码:多个项目共享同一个库
- 独立版本控制:子模块有自己独立的版本历史
为什么 EnderRealm 需要子模块?
EnderRealm 项目使用子模块来管理以下组件:
| 子模块 | 路径 | 用途 |
|---|---|---|
| Easy4Form | libs/Easy4Form | Bedrock 玩家表单库 |
| EnderRealmFastGUI | libs/EnderRealmFastGUI | 容器 UI 构建库 |
| Floodgate | libs/Floodgate | Bedrock-Java 桥接(Fork) |
| EnderRealmRuntime | EnderRealmRuntime | 开发服务器运行时 |
子模块的工作原理
子模块本质上是一个指向特定提交的指针:
主仓库
├── .gitmodules # 子模块配置
├── .git/modules/ # 子模块的实际 Git 仓库
├── libs/Easy4Form/ # 子模块的工作目录(指向特定提交)
└── ....gitmodules 文件
.gitmodules 文件定义了子模块的信息:
ini
[submodule "libs/Easy4Form"]
path = libs/Easy4Form
url = https://github.com/EnderRealmMC/Easy4Form.git
[submodule "libs/EnderRealmFastGUI"]
path = libs/EnderRealmFastGUI
url = https://github.com/EnderRealmMC/EnderRealmFastGUI
[submodule "libs/Floodgate"]
path = libs/Floodgate
url = https://github.com/EnderRealmMC/Floodgate.git
[submodule "EnderRealmRuntime"]
path = EnderRealmRuntime
url = https://github.com/EnderRealmMC/EnderRealmRuntime.git子模块的日常操作
初始化子模块
如果克隆时没有使用 --recurse-submodules 参数,需要手动初始化:
bash
# 初始化并更新所有子模块
git submodule update --init --recursive
# 分步执行
git submodule init
git submodule update更新子模块
bash
# 更新所有子模块到主仓库记录的版本
git submodule update
# 更新所有子模块到最新版本
git submodule update --remote
# 更新特定子模块到最新版本
git submodule update --remote libs/Easy4Form查看子模块状态
bash
# 查看子模块状态
git submodule status
# 输出示例:
# 1a2b3c4d5e6f7g8h9i0j libs/Easy4Form (heads/main)
# 0j9i8h7g6f5e4d3c2b1a libs/EnderRealmFastGUI (heads/main)
# 9i8h7g6f5e4d3c2b1a0j libs/Floodgate (heads/main)
# 8h7g6f5e4d3c2b1a0j9i EnderRealmRuntime (heads/main)前面的 - 号表示子模块未初始化,空格表示已初始化且与记录的版本一致,+ 表示子模块有新的提交。
进入子模块目录
bash
# 进入子模块目录
cd libs/Easy4Form
# 现在可以在子模块中执行 Git 命令
git log --oneline -5
git status提交子模块更改
如果在子模块中做了修改:
bash
# 1. 进入子模块目录
cd libs/Easy4Form
# 2. 提交更改
git add .
git commit -m "修改了子模块"
# 3. 推送子模块更改
git push origin main
# 4. 返回主仓库
cd ../..
# 5. 更新主仓库中的子模块指针
git add libs/Easy4Form
git commit -m "更新 Easy4Form 子模块"
# 6. 推送主仓库更改
git push origin main子模块的常见问题
Q: 子模块目录是空的?
A: 子模块未初始化,执行:
bash
git submodule update --init --recursiveQ: 子模块更新失败?
A: 尝试以下方法:
bash
# 方法 1:强制更新
git submodule update --force
# 方法 2:重新初始化
git submodule deinit -f libs/Easy4Form
git submodule update --init libs/Easy4Form
# 方法 3:删除并重新克隆
rm -rf libs/Easy4Form
git submodule update --init libs/Easy4FormQ: 如何查看子模块的远程更新?
A: 使用以下命令:
bash
# 进入子模块目录
cd libs/Easy4Form
# 获取远程更新
git fetch
# 查看本地与远程的差异
git log HEAD..origin/main --oneline
# 返回主仓库
cd ../..Q: 如何切换子模块的分支?
A: 使用以下命令:
bash
# 进入子模块目录
cd libs/Easy4Form
# 切换分支
git checkout feature-branch
# 返回主仓库
cd ../..
# 更新主仓库中的子模块指针
git add libs/Easy4Form
git commit -m "切换 Easy4Form 到 feature-branch"Q: 子模块冲突怎么解决?
A: 当多人修改了子模块的指针时可能会产生冲突:
bash
# 1. 进入子模块目录
cd libs/Easy4Form
# 2. 切换到正确的版本
git checkout <正确的提交哈希>
# 3. 返回主仓库
cd ../..
# 4. 解决冲突
git add libs/Easy4Form
git commit -m "解决子模块冲突"子模块的最佳实践
1. 保持子模块同步
定期更新子模块,保持与上游同步:
bash
# 查看子模块是否有更新
git submodule foreach git fetch
git submodule foreach git log HEAD..origin/main --oneline
# 更新子模块
git submodule update --remote2. 提交前检查子模块
在提交主仓库前,确保子模块处于正确状态:
bash
# 检查子模块状态
git submodule status
# 确保子模块没有未提交的更改
git submodule foreach git status3. 使用 .gitmodules 管理配置
.gitmodules 文件应该被提交到仓库:
bash
git add .gitmodules
git commit -m "更新子模块配置"4. 文档化子模块的使用
在 README 中说明子模块的用途和初始化方法。
子模块 vs 包管理器
Git 子模块和其他依赖管理方式的对比:
| 方式 | 优点 | 缺点 |
|---|---|---|
| Git 子模块 | 精确控制版本,可以修改源码 | 操作复杂,容易出错 |
| Maven/Gradle 依赖 | 简单,自动管理 | 无法修改源码 |
| 包管理器(npm/pip) | 简单,社区丰富 | 可能与项目不兼容 |
EnderRealm 选择子模块的原因:
- 需要修改 Floodgate 源码(Fork)
- 需要精确控制库的版本
- 库与项目紧密集成
常见问题
Q: 如何添加新的子模块?
A: 使用以下命令:
bash
# 添加子模块
git submodule add https://github.com/user/repo.git libs/repo
# 提交更改
git add .gitmodules libs/repo
git commit -m "添加新的子模块"Q: 如何删除子模块?
A: 使用以下命令:
bash
# 1. 从 .gitmodules 中删除
git config -f .gitmodules --remove-section submodule.libs/repo
# 2. 从 .git/config 中删除
git config --remove-section submodule.libs/repo
# 3. 从暂存区删除
git rm --cached libs/repo
# 4. 删除本地文件
rm -rf libs/repo
rm -rf .git/modules/libs/repo
# 5. 提交更改
git add .
git commit -m "删除子模块"Q: 如何克隆包含子模块的仓库?
A: 使用以下命令:
bash
# 方法 1:克隆时自动初始化子模块
git clone --recurse-submodules <url>
# 方法 2:克隆后手动初始化
git clone <url>
cd repo
git submodule update --init --recursive推荐学习资源
下一步
子模块管理学习完成后,让我们进入阶段三:理解项目。