在没有 .gitmodules 的情况下使用 Git 子模块
我对手动将一个 Git 存储库放入另一个 Git 存储库的具体情况感兴趣(通过使用 git clone 或通过在文件系统中复制粘贴)。我注意到当你这样做时会发生以下事情:
- Git 将保存指向特定提交的指针,就像子模块一样。
- Git 不允许您从内部修改子项目的内容 超级项目,就像子模块一样。
- 超级项目上的 git clone 不会复制子项目内容, 就像子模块一样。
git submodule
将不起作用。它抱怨 .gitmodules 不存在 那里。
我想知道:
- .gitmodules 有什么作用?它的缺席是两者之间唯一明显的区别 像这样的手动复制和一个真正的子模块。
- 还有什么我不知道的区别吗?
- 这个手动复制的状态有特殊的名字吗?
- 有什么方法可以覆盖和/或解决效果 3 和 4 吗? (即:我想要 使生成的存储库完全可用)
I'm interested in the specific case where you manually place one Git repository inside another Git repository (either by using git clone
or by copy-pasting in the filesystem). I've noticed the following things happen when you do this:
- Git will save a pointer to a specific commit, like with a submodule.
- Git will not allow you to modify the contents of the subproject from within the
superproject, like with a submodule. git clone
on the superproject will not copy the subproject contents,
like with a submodule.git submodule
will not work. It complains about .gitmodules not being
there.
I would like to know:
- What does .gitmodules do? It's absence is the only obvious difference between a
manual copy like this and a true submodule. - Is there any other difference I don't know about?
- Does this manually-copied state have a special name?
- Is there any way to override and/or work around effects 3 and 4? (IE: I want to
render the resulting repository fully usable)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为唯一的区别是子模块与其父模块有关系。例如,您可以在克隆时使用
--recursive
选项来一次获取所有子模块。否则,您必须将它们一一取出。I think the only difference is a submodule has a relation with its parent. For instance, you can use
--recursive
option when cloning to fetch all the submodules at a time. Otherwise, you'd have to fetch them all one by one.我认为(我不确定)这是子模块的实现细节。如果添加存储库中的存储库(使用 git add),则不会存储目录的内容,而是存储 HEAD 提交的哈希值(作为提交类型,而不是作为树或 blob 类型)。如果您有子存储库,则此提交哈希包含您需要的所有信息。但如果你只有超级仓库和子仓库HEAD的提交哈希,你仍然需要获取子仓库。此信息存储在 .gitmodules 文件中。如果你根本不使用遥控器,如果你从不克隆、推送或拉取你的超级存储库,你实际上可以使用没有 .gitmodules 的子模块。只需将子存储库(例如第 3 方库)复制到存储库中即可。这允许跟踪超级存储库中的每次提交使用了哪些版本的第三方库。但它不允许立即克隆所有内容。子存储库的遥控器仅存储在工作树中的克隆中。如果将超级存储库推送到裸存储库,则从何处获取子模块的信息就会丢失。
要了解其工作原理,
cat-file
是一个非常有用的工具,可以查看单个 git 对象。提交包含消息、作者、提交者,通常还包含指向树对象的链接:树对象包含其他 git 对象的列表:
文件夹存储为树对象(再次包含一些 git 对象),文件存储为 blob。子模块作为类型提交存储在树对象中。内容可以在子存储库的给定哈希中找到。
来自 man git-submodule :
I think (I am not sure) this is an implementation detail of submodules. If a repository in a repository is added (using git add), not the content of the directory is stored, but instead the hash of the commit of the HEAD is stored (as type commit and not as type tree or blob). This commit hash contains all information you need if you have the sub repository. But if you have only the super repository and the commit hash of the HEAD of the sub repository, you still need to get the sub repository. This information is stored in the .gitmodules file. If you don't use remotes at all, if you never clone, push or pull your super repository, you can actually use submodules without .gitmodules. Simply glone the sub repositories (e.g. 3rd party libraries) in your repository. This allows to keep track which versions of the 3rd party libraries where used for each commit in the super repository. But it does not allow to clone everything at once. The remotes of the sub repositories are stored only in the clones in the working tree. If you push the super repository (to a bare repository), the information where to get the sub modules from is lost.
To understand how this works
cat-file
is a very helpful tool to take a look at the single git objects. A commit contains a message, author, comitter and usually a link to tree object:The tree object contains a list of other git objects:
Folders are stored as tree objects (containing again a lits of git objects) and files as blob. A submodule is stored as type commit in a tree object. The contents can be found in the given hash in the sub repository.
From
man git-submodule
: