868

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

如果我有点不走运并且必须手动执行操作,我不会感到惊讶,因为即使删除子模块也不容易。

4

9 回答 9

1177

您应该能够编辑.gitmodules文件以更新 URL,然后运行git submodule 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
于 2009-05-27T05:25:39.867 回答
192

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

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/分支

于 2015-06-05T20:17:48.367 回答
186

使用 Git 2.25(2020 年第一季度),您可以对其进行修改
请参阅“ Git submodule url changed ”和新命令

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

(在--分隔符上,请参阅“双连字符作为停止选项解释并按字面处理所有后续参数的信号”)

警告:Hi-Angel在评论中提到(即使使用 Git 2.31.1 测试):

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

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


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

实际上,已经在 2009 年 4 月提交了一个补丁来澄清gitmodule角色。

所以现在gitmodule 文档还没有包括:

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

这几乎证实了吉姆的回答


如果您遵循这个git 子模块教程,您会看到需要一个“ git submodule 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 config remote."$remote".url "$url"

于 2009-05-27T05:40:27.497 回答
152

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

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

git config --file=.gitmodules -e

要不就:

vim .gitmodules

然后重新同步并更新:

git submodule sync
git submodule update --init --recursive --remote
于 2017-05-12T11:48:59.843 回答
80

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

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

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

于 2013-10-01T21:46:14.190 回答
13

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

git config submodule.common.url /data/my_local_common
于 2009-05-29T23:27:19.103 回答
3

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

于 2017-04-01T16:39:26.233 回答
-1

蛮力方法:

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

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

于 2020-12-09T08:15:38.077 回答
-2

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

即使在 Git 2.25(以及git submodule set-url <path> <newurl>.

根据 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 部分及其工作树。进一步的调用 [..] 将跳过任何未注册的子模块,直到它们再次被初始化

于 2021-10-05T11:48:31.390 回答