如何更改git子模块的远程存储库?

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

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

396981 次浏览

您应该能够编辑.gitmodules文件以更新URL,然后运行git submodule sync --recursive以将该更改反映到超级项目和您的工作副本。

然后您需要转到.git/modules/path_to_submodule目录并更改其配置文件以更新git路径。

如果repo历史记录不同,则需要手动签出新分支:

git submodule sync --recursivecd <submodule_dir>
git fetchgit checkout origin/mastergit branch master -fgit checkout master

使用Git 2.25(Q1 2020),您可以修改它。
请参阅“git子模块url修改”和新命令

git submodule set-url [--] <path> <newurl>

(在--分隔符上,见“双连字符作为停止选项解释的信号,并从字面上处理所有以下参数”)

警告:嗨,天使提到在评论(即使使用Git 2.31.1进行了测试):

应该小心git submodule set-url,因为它有一个bug:

如果,在你的.gitmodules文件中,路径看起来像这样some-path,然后你执行一个git submodule set-url some-path/ new-url(注意后面的斜杠/),然后,而不是修改现有的子模块,命令将添加另一个。


原答案(2009年5月,十年前)

实际上,补丁已于2009年4月提交澄清了gitmodule的作用。

所以现在gitModul留档还不包括:

.gitmodules文件位于git工作树的顶层目录中,是一个文本文件,其语法符合-link git: git-config4的要求。
[新]:
由于该文件由Git管理,它跟踪项目子模块的+记录。
存储在此文件中的信息用作提示,以确定存储在项目配置文件中的记录的权威版本。
用户特定的记录更改(例如,由于网络情况导致子模块URL的差异)应该对配置文件进行更改,而要传播的记录更改(例如+由于子模块源的重定位)应该对此文件进行。

这几乎证实了吉姆的回答


如果您遵循此git子模块教程,您会发现您需要“git submodule init”才能将子模块存储库URL添加到. git/config。

git submodule sync”有已于2008年8月添加,正是为了在URL更改时使任务更容易(特别是如果子模块的数量很重要)。
与该命令的关联脚本非常简单:

module_list "$@" |while read mode sha1 stage pathdoname=$(module_name "$path")url=$(git config -f .gitmodules --get submodule."$name".url)if test -e "$path"/.gitthen(unset GIT_DIRcd "$path"remote=$(get_default_remote)say "Synchronizing submodule url for '$name'"git config remote."$remote".url "$url")fidone

目标仍然是:git config remote."$remote".url "$url"

只需编辑您的. git/config服务配置文件。例如;如果您有一个“共同”子模块,您可以在超级模块中执行此操作:

git config submodule.common.url /data/my_local_common

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

  • 使用新存储库的URL更新. git模块
  • 从“. git/config”文件中删除相应的行
  • 删除“. git/模块/外部”目录中的相应目录(最近的git版本为“. git/模块”)
  • 删除签出的子模块目录本身(不确定是否有必要)
  • 运行git submodule initgit submodule update
  • 确保签出的子模块处于正确的提交位置,并提交,因为哈希可能会有所不同

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

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

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

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

git config --file=.gitmodules -e打开默认编辑器,您可以在其中更新路径

简单来说,您只需要编辑. git模块文件,然后重新同步和更新:

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

git config --file=.gitmodules -e

或者只是:

vim .gitmodules

然后重新同步和更新:

git submodule syncgit submodule update --init --recursive --remote

蛮力方法:

  • 更新超级模块中的.gitmodules文件以指向新的子模块url,
  • 添加并提交更改到supermodule/.gitmodules
  • 在您的计算机上的其他地方制作超级模块的新克隆(确保对.gitmodules文件的最新更改反映在克隆中),
  • 将您的工作目录更改为超级模块的新克隆,
  • 在子模块上运行git submodule update --init --remote path-to-submodule

等等!超级模块的新克隆中的子模块已正确配置!

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

即使在Git2.25(以及git submodule 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>…​)

注销给定的子模块,即从. git/config中删除整个submodule.$name 部分及其工作树。进一步的调用[…]将跳过任何未注册的子模块,直到它们再次初始化