Git submodule 的精准用法: Difference between revisions
Jump to navigation
Jump to search
| Line 39: | Line 39: | ||
这种设计有两个好处: | 这种设计有两个好处: | ||
* 不把别人写的几百个插件源码文件伪装成自己的文件 | |||
* 又能让配置仓库精确声明自己依赖哪个插件版本 | |||
submodule 最重要的价值: | submodule 最重要的价值: | ||
Revision as of 21:32, 22 July 2026
Git submodule 适合这种情况:主项目需要别的子项目,主项目需要管理子项目的版本。git clone 的子项目只是碰巧存在于这台电脑;而 Git submodule,子项目是主项目正式声明的一项依赖,正式记录插件的 URL、保存路径和准确版本。Git submodule 的本质是,放弃包管理器的一部分自动化,换取透明、固定、可控和可复现。对于大量、频繁更新的子项目,手工管理会比较繁琐;对于少量精选、长期固定、谨慎升级的子项目,非常合适。
概念
在 Emacs 配置中,可以把 ~/.emacs.d/ 视为主仓库。把 Vertico Consult Magit 等视为子仓库。
单凭 git clone 子仓库,Emacs 也可以用。但主仓库对子仓库的完整细节缺乏了解。
而 git submodule add 可以解决
- Vertico 从哪个 URL 下载
- 应该保存在哪个目录
- 应该使用哪个 commit
- 换电脑后应该怎样恢复
- 主配置回滚时,Vertico 应该回到哪个版本
.gitmodules 内容大致如下:
[submodule "travel/packages/vertico"]
path = travel/packages/vertico
url = https://github.com/minad/vertico.git
submodule 还会记录一条指向某个 commit 的 gitlink。
| 仓库 | 负责记录什么 |
|---|---|
~/.emacs.d 主仓库
|
自己的配置文件,以及每个插件应使用哪个 commit |
| Vertico 子仓库 | Vertico 源码和 Vertico 自己的完整开发历史 |
| Consult 子仓库 | Consult 源码和 Consult 自己的完整开发历史 |
| Magit 子仓库 | Magit 源码和 Magit 自己的完整开发历史 |
这种设计有两个好处:
- 不把别人写的几百个插件源码文件伪装成自己的文件
- 又能让配置仓库精确声明自己依赖哪个插件版本
submodule 最重要的价值:
- 固定插件版本
- 它记录的不是模糊的“使用最新版”,而是,这套配置经过测试时,各插件分别停留在哪个准确版本。这相当于给插件环境加了一把版本锁。
- 整体回滚
- 主仓库回滚到 abc1234,子仓库也会恢复到当时的状态。普通嵌套
git clone做不到这一点。即使主配置回到一个月前,插件仍可能停留在今天的新版本。 - 异地完整复现
git clone --recurse-submodules URL PATH,恢复出来的插件环境与原电脑一致。- 明确记录插件升级
- 使用 submodule 后,升级插件会被主仓库识别为一次正式变化,这让插件升级变成一种可查看、可测试、可提交、可撤销的操作。
工作流
## 配置
git config diff.submodule lo
git config status.submodulesummary 1
## 添加
cd ~/.emacs.d
git init -b main
git submodule add https://github.com/minad/vertico.git travel/packages/vertico
git status
git commit -m "Add Vertico submodule"
## 查看
git -C travel/packages/vertico log --oneline --decorate -10
git submodule status
## 升级
git submodule update --remote -- travel/packages/vertico
git diff --submodule=log
## 保留
git add travel/packages/vertico
git commit -m "Update Vertico" # commit 了才正式获得了主仓库的承认
## 放弃
git submodule update --checkout --force -- travel/packages/vertico # 未提交时,放弃,或
git revert 7ac39fe && git submodule update --init --recursive # 错提交后,放弃
## 删除
git rm travel/packages/vertico
git rm travel/40-test/init-vertico.el
git commit -m "Remove Vertico"
## 暂停
git submodule deinit -- travel/packages/vertico
## 不暂停
git submodule update --init -- travel/packages/vertico
## 移机
git clone --recurse-submodules 主仓库URL ~/.emacs.d # 一次搞定,或
git pull && git submodule update --init --recursive # 两次搞定
经验
- 不要修改插件原始仓库。不应把自己的配置写进子仓库。
- 一次升级一个插件,一个插件形成一个独立提交。
- submodule 经常处于 detached HEAD 是正常的。这是版本锁定的正常状态。
- git submodule 搞定源码仓库的版本关系,它不是包管理器,依赖项需要各软件自行安装