我已经创建了一个带有子模块的git存储库。我可以告诉子模块本身更改其远程存储库路径,但我不确定如何告诉父存储库如何更改子模块的远程存储库路径。
如果我运气不好,不得不手动操作,我也不会感到惊讶,因为即使删除子模块也不容易。
我已经创建了一个带有子模块的git存储库。我可以告诉子模块本身更改其远程存储库路径,但我不确定如何告诉父存储库如何更改子模块的远程存储库路径。
如果我运气不好,不得不手动操作,我也不会感到惊讶,因为即使删除子模块也不容易。
当前回答
简单来说,你只需要编辑.gitmodules文件,然后重新同步和更新:
通过git命令或直接编辑文件:
git config --file=.gitmodules -e
或者是:
vim .gitmodules
然后重新同步和更新:
git submodule sync
git submodule update --init --recursive --remote
其他回答
很多人(在这里和在互联网上)建议需要手动编辑或删除多个文件的解决方案。但这真的不需要!
即使在Git 2.25(因此Git子模块set-url <path> <newurl>)不可用的环境中,最简单的解决方案是简单地“取消注册”子模块并使用新的URL重新添加它。
根据Git版本和子模块设置,您可能需要在再次添加<path>之前手动删除它。不需要其他手动操作!
git submodule deinit <path>
rm -rf <path>
git submodule add <repository> [<path>]
之后.gitmodules文件将有一个不同的URL,应该被提交。所有其他位置(配置,工作树)已经被git处理了。
为了解释deinit的作用,我想引用Git手册中的一段话:
Deinit [-f|——force](——all|[——]<path>…) 取消注册给定的子模块,即删除整个子模块。$name部分从.git/config连同他们的工作树。进一步的呼叫[..]将跳过任何未注册的子模块,直到它们再次初始化
一种蛮力方法:
更新超模块中的.gitmodules文件以指向新的子模块url, 添加并提交更改到supermodule/.gitmodules, 在您的计算机上的其他地方创建一个新的超级模块克隆(确保.gitmodules文件的最新更改反映在克隆中), 将工作目录更改为超模块的新克隆, 在子模块上运行git子模块update——init——远程路径到子模块,
果不其然!超级模块的新克隆中的子模块配置正确!
你应该可以编辑.gitmodules文件来更新URL,然后运行git子模块sync——recursive来将更改反映到超项目和你的工作副本中。
然后你需要转到.git/modules/path_to_submodule目录,修改它的配置文件来更新git路径。
如果回购历史记录不同,那么你需要手动签出新的分支:
git submodule sync --recursive
cd <submodule_dir>
git fetch
git checkout origin/master
git branch master -f
git checkout master
使用Git 2.25 (Q1 2020),您可以修改它。 参见“Git子模块url已更改”和新命令
git submodule set-url [--] <path> <newurl>
(在分隔符上,请参阅“双连字符作为停止选项解释并按字面意思处理所有以下参数的信号”)
警告:Hi-Angel在评论中提到(甚至用Git 2.31.1测试过):
你应该小心git子模块set-url,因为它有一个bug: 如果,在你的.gitmodules文件中,路径看起来像这个some-path,然后你执行了一个git子模块set-url some-path/ new-url(注意后面的斜杠/),那么,该命令不会修改现有的子模块,而是会添加另一个。
原答案(2009年5月,14年前)
实际上,一个补丁已经在2009年4月提交,以澄清gitmodule的角色。
所以现在gitmodule文档还不包括:
The .gitmodules file, located in the top-level directory of a git working tree, is a text file with a syntax matching the requirements -of linkgit:git-config4. [NEW]: As this file is managed by Git, it tracks the +records of a project's submodules. Information stored in this file is used as a hint to prime the authoritative version of the record stored in the project configuration file. User specific record changes (e.g. to account for differences in submodule URLs due to networking situations) should be made to the configuration file, while record changes to be propagated (e.g. +due to a relocation of the submodule source) should be made to this file.
这在很大程度上证实了吉姆的答案。
如果你遵循这个git子模块教程,你会发现你需要一个“git子模块init”来将子模块存储库url添加到.git/config中。
“git submodule sync”已在2008年8月添加,目的是为了在URL更改时(特别是当子模块的数量很重要时)使任务更容易完成。 该命令的关联脚本非常简单:
module_list "$@" |
while read mode sha1 stage path
do
name=$(module_name "$path")
url=$(git config -f .gitmodules --get submodule."$name".url)
if test -e "$path"/.git
then
(
unset GIT_DIR
cd "$path"
remote=$(get_default_remote)
say "Synchronizing submodule url for '$name'"
git config remote."$remote".url "$url"
)
fi
done
目标仍然是:git配置remote."$remote"。url " $ url "
只需编辑你的.git/config文件。例如;如果你有一个“common”子模块,你可以在超级模块中这样做:
git config submodule.common.url /data/my_local_common