我已经创建了一个带有子模块的git存储库。我可以告诉子模块本身更改其远程存储库路径,但我不确定如何告诉父存储库如何更改子模块的远程存储库路径。

如果我运气不好,不得不手动操作,我也不会感到惊讶,因为即使删除子模块也不容易。


你应该可以编辑.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

对我有用的(在Windows上,使用git版本1.8.3.msysgit.0):

用URL更新.gitmodules到新的存储库 从”中删除相应的行。git /配置文件 删除文件中对应的目录。Git /modules/external“目录(”。Git /modules”,适用于最新的Git版本) 删除签出的子模块目录本身(不确定这是否有必要) 运行git子模块init和git子模块update 确保检出的子模块处于正确的提交位置,并提交该子模块,因为哈希值可能会不同

在做了所有这些之后,一切都处于我所期望的状态。我想其他用户在更新时也会有类似的痛苦——在提交消息中解释这些步骤是明智的!


这些命令将在命令提示符上完成工作,而不会更改本地存储库上的任何文件

git config --file=.gitmodules submodule.Submod.url https://github.com/username/ABC.git
git config --file=.gitmodules submodule.Submod.branch Development
git submodule sync
git submodule update --init --recursive --remote

请查看博客截图:将GIT子模块URL/分支更改为同一存储库的其他URL/分支


Git配置——file=。Gitmodules -e打开默认编辑器,您可以在其中更新路径


简单来说,你只需要编辑.gitmodules文件,然后重新同步和更新:

通过git命令或直接编辑文件:

git config --file=.gitmodules -e

或者是:

vim .gitmodules

然后重新同步和更新:

git submodule sync
git submodule update --init --recursive --remote

一种蛮力方法:

更新超模块中的.gitmodules文件以指向新的子模块url, 添加并提交更改到supermodule/.gitmodules, 在您的计算机上的其他地方创建一个新的超级模块克隆(确保.gitmodules文件的最新更改反映在克隆中), 将工作目录更改为超模块的新克隆, 在子模块上运行git子模块update——init——远程路径到子模块,

果不其然!超级模块的新克隆中的子模块配置正确!


很多人(在这里和在互联网上)建议需要手动编辑或删除多个文件的解决方案。但这真的不需要!

即使在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连同他们的工作树。进一步的呼叫[..]将跳过任何未注册的子模块,直到它们再次初始化