能否复用同一Git克隆版本库作为submodule?需注意哪些风险?
答案是可以。你不需要重新完整克隆Lib A,直接用本地已有的克隆路径添加子模块即可,命令如下:
cd path/to/projectB git submodule add /本地/libA的绝对路径 src/lib/libA # 若两个仓库是相对位置,也可使用相对路径 git submodule add ../../libA src/lib/libA
添加后,Project B的.gitmodules文件会记录这个本地路径,子模块会直接关联你已有的Lib A克隆,本地修改可以直接在原Lib A目录或Project B的子模块目录中操作,无需推拉就能测试联动效果。
但这种做法存在不少陷阱和弊端,需要注意:
协作时的路径不一致问题:你本地的Lib A路径会被记录在
.gitmodules里,其他开发者克隆Project B时,他们的机器上大概率没有相同路径,子模块会自动尝试拉取Lib A的远程仓库版本,和你的本地状态脱节。如果你的本地Lib A路径移动,还需要手动修改.gitmodules并执行git submodule sync修复关联。分支状态混淆风险:你本地Lib A在分支A,但Project B的子模块需要跟踪分支Z,来回切换分支或修改时很容易搞混状态。比如你在子模块目录切到A分支改了代码,但Project B的子模块配置是跟踪Z,提交子模块哈希时可能误提交A分支的哈希,导致团队其他成员拉取后子模块分支不符合预期。
未推送提交的隐患:虽然本地修改不用推拉就能测试,但如果在Project B里提交了子模块的新哈希(对应你本地未推送的修改),其他开发者拉取Project B后会找不到这个提交,触发"missing commit"错误。你必须先把Lib A的本地修改推到远程,再提交Project B里的子模块哈希,否则会给团队协作添乱。
Git子模块命令的误操作:比如执行
git submodule update --remote会强制拉取Lib A远程分支的最新代码,覆盖你本地未提交的修改;在Project B里执行提交时,容易忘记先提交子模块的修改,导致子模块哈希和实际代码状态不匹配。相对路径的局限性:如果用相对路径添加子模块,要求所有开发者的Lib A和Project B的相对目录结构完全一致,否则子模块关联会失效,灵活性很低。
内容的提问来源于stack exchange,提问作者Daniel

