经过一番研究和自己回答问题,我认为以下内容对他人可能有所帮助:
理解git子模块非常困难,但一旦掌握,一切就都变得清晰易懂了!
以下文章展示:
- 如何添加子模块,并让其他人同步更新您的子模块。
- 如何更新子模块,并让其他人同步更新您的子模块。
- 如何移除子模块,并让其他人同步更新您的子模块。
- 如何更新已移除的子模块。
添加子模块
git submodule add -b
.gitmodules中的条目(名称、路径、URL、分支)通过下载相应的子模块进行操作。
git submodule update --init
这个操作有三个重要的作用,其中前两个对用户隐藏:
更新.git/config文件,增加一个额外的条目(submodules)
以裸形式在.git/modules下下载存储库。这意味着,在.git内部还有一个.git。
将git子模块从.git/modules检出到父目录中。
现在,在第二天,提交者意识到应该将子模块更改为其他提交而不是HEAD。因此,他会进入本地存储库,然后进入子模块路径,并通过简单调用来检出所需的提交:
git checkout <hash>
cd <parent dir>
git submodule status
此时,git子模块状态仍未显示新的哈希值。只有在更改被暂存时,新的哈希值才会显示出来。现在,提交者只需要暂存(添加)、提交和推送更改,以便所有其他开发人员都能看到。
更新已添加的子模块
第三天,其他开发人员只需调用命令来更新他们的存储库:
git pull
git submodule update --force
基本上,这里的要点很简单:子模块在没有被告知之前不会做出反应。仅仅执行git pull并不能更新git子模块。开发人员可以继续在本地子模块上工作,并且不必将其与服务器上的子模块同步“永远”不变。只有在显式调用git submodule update命令时,子模块才会更新。
删除子模块
现在,在第四天,提交者决定完全删除git子模块。这里的步骤也不简单,因为没有称为git submodule rm的东西应该等价于git submodule add。只有按照以下顺序进行操作才能完成:
git submodule deinit submodulename
这将删除 .git/config 条目。
这将清空子模块目录!!执行此命令后,您将在子模块目录中看不到任何内容。
但是子模块的内容仍然可以在 .git/modules 下找到。
因此,在此处执行 git status -u 命令仍会显示所有内容都是最新的!
因此要显示移除的内容,
git rm submodulepath
现在,执行git status命令会返回.gitmodules文件已更改(子模块已删除),并且子模块路径已被删除。提交并推送更改。
删除子模块后的更新
第五天,开发人员想要像使用git submodule update一样“自动”删除子模块。因此,他们首先执行git pull命令,成功地删除了所有与git子模块相关的索引。
git submodule status # shows nothing
但是,.git/config仍然包含有效的子模块条目,子模块文件夹以及.git/submodules下的裸仓库也都在那里!没有命令可以删除它们。所有这些必须通过手动显式移除。(如果我说错了,请纠正我)
git pull
时,子模块将显示为“已修改”。要将子模块更新到新引用,请在主存储库上运行git submodule update
。 - Thibault D.