Git Submodule: Data & Code Repository Separate
导言
原本是不期望使用submodule的,但是PTA要用,还是需要学习一下。
Git 子模块入门教程¶
Git Submodule在下载zip包时是无法运行的
由于子模块信息会保留在.git
信息,和.gitmodules
文件里。zip下载没有。
需要删除.gitmodules
文件,并且重复git add来重新添加。
在 Git 中,子模块(submodule)允许将一个 Git 仓库作为另一个 Git 仓库的子目录,从而管理不同的 Git 项目作为一个整体。这在需要将外部项目作为依赖或嵌入到你的项目中时非常有用。子模块的管理有时比较复杂,特别是当项目中有大量子模块时。
如果你觉得子模块不好用,也可以选择使用 .gitignore
或者 ln -s
来替代。
1. 添加子模块¶
要将子模块添加到你的 Git 仓库中,首先进入你的主仓库根目录,然后执行以下命令:
<repository_url>
是你想要添加的子模块仓库的 URL。-
<submodule_path>
是你希望将子模块放置在主项目中的相对路径。 -
这个命令会在主仓库中创建对子模块的引用,允许你将子模块与主项目一起管理。
- 相关信息会保留在
.git
信息,和.gitmodules
文件里。
2. 更新和初始化子模块¶
添加子模块后,你需要初始化并更新子模块的内容。运行以下命令:
--init
用于初始化子模块。--recursive
确保子模块中的其他子模块也被初始化。
这将会下载并初始化子模块的内容,使其成为主仓库的一部分。
3. 配置 .gitignore
文件¶
如果你不希望将子模块的内容提交到主仓库中,你可以在主仓库的 .gitignore
文件中忽略子模块的路径。例如,如果你的子模块位于 submodule_folder
目录下,可以在 .gitignore
文件中添加如下内容:
这样,Git 就不会把子模块的内容包含在版本控制中,但子模块的引用信息(即它指向的 commit)仍然会被记录在主仓库中。
4. 使用子模块¶
当你在其他机器上克隆这个主仓库时,或者将仓库分享给其他开发者时,他们需要运行以下命令来初始化并获取子模块的内容:
对子模块进行修改¶
如果你需要对子模块做修改,可以进入子模块目录并像普通 Git 仓库一样进行工作。修改并提交后,不要忘记将子模块的更新推送到子模块的远程仓库。然后,再回到主仓库,提交更新后的子模块引用。
# 在子模块目录中进行修改和提交
cd third_party/op-plugin
git commit -m "Update submodule"
git push origin master
# 回到主仓库并提交子模块引用的更新
cd ..
git add third_party/op-plugin
git commit -m "Update submodule reference"
git push
更新子模块¶
如果你需要将子模块更新到最新的版本,可以进入子模块目录并运行以下命令:
然后,回到主仓库提交更新后的子模块引用:
子模块的独立版本控制¶
记住,子模块有自己独立的版本控制系统,因此你需要单独管理子模块的版本。子模块提供了一种将外部项目整合到你的主项目中的方式,同时保持它们独立的开发和版本控制。
替代方案¶
虽然 Git 子模块提供了强大的功能,但在一些场景下,它可能会显得比较复杂或不适用。如果你觉得子模块难以管理,可以考虑以下替代方案:
- 使用
.gitignore
:如果你不想管理子模块的内容,直接将其添加到.gitignore
文件中。 - 使用符号链接 (
ln -s
):通过在主仓库中使用符号链接,将外部项目作为文件夹包含进来,而不直接嵌套它们为 Git 子模块。
这两种方法可以简化一些场景,但会失去 Git 对子模块的自动管理和版本控制支持。
总结¶
Git 子模块是将外部仓库引入到你的主仓库中的强大工具,适用于有外部依赖的项目。尽管它们有独立的版本控制,需要管理多个仓库,但它们提供了更灵活和独立的版本控制方式。子模块的使用需要一些配置和理解,但一旦掌握,就能有效地组织和管理多个 Git 仓库。
必要性存疑
- parent repository ignore the sub directory in
.gitignore
- Normal git usage in child repository, eg.
init commit push
- submodule for what?
- for auto upload and init multi-subgit to target git commit
常见问题¶
合并冲突¶
父项目为空
PS C:\Users\94364\github\pytorch_without_subgit> git submodule status
66b781b70b1d095d107786d6b6a1bdfef7aa3e18 third_party/Tensorpipe (66b781b)
58d77fa8070e8cec2dc1ed015d66b454c8d78850 third_party/googletest (release-1.8.0-2986-g58d77fa8)
U0000000000000000000000000000000000000000 third_party/op-plugin
114e06a0b131d4055da3688d915bac4bbd29eb4f third_party/torchair/torchair (114e06a0)
使用git add third_party/op-plugin
即可更新
submodule 有git, 但是没文件
说明是git clone时中断了,可以直接git reset --hard origin/master
合并submodule commit冲突
这个错误是因为 Git 在处理子模块的冲突时发现 third_party/op-plugin
子模块未被正确初始化或未检出其对应的 commit。以下是解决该问题的步骤:
- 初始化和更新子模块 确保子模块已被初始化并更新到正确的版本:
如果子模块没有被初始化,这将下载并检出子模块内容。如果子模块已经存在但未被更新,这个命令会同步它到当前父项目的正确版本。
- 手动解决子模块冲突 子模块冲突需要手动解决,按照以下步骤操作:
(1) 进入子模块目录
进入冲突的子模块目录 third_party/op-plugin
:
(2) 检查冲突状态 在子模块中运行以下命令查看冲突情况:
(3) 解决冲突 解决子模块内的冲突问题,可以选择:
- 回退到指定版本:如果你知道父项目期望的子模块版本,直接检出该版本:
- 合并冲突:如果子模块的冲突是由于不同分支的内容合并导致的,运行:
(4) 提交子模块的修改 子模块冲突解决后,提交子模块的变更:
然后返回到父项目目录。
- 更新父项目状态 在父项目中,标记子模块冲突已解决:
然后继续变基过程:
参考文献¶
上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。
无