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


722

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

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


8
注意:Git 2.25(2020年第一季度)带有一个新命令 “:git submodule set-url [--] <path> <newurl>
VonC

Answers:


1009

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


22
至少在1.7.1或1.7.3中,这似乎没有更新.git / config。
davidtbernal,2010年

6
这还会更新先前提交的子模块url配置吗?例如,如果我签出较旧的提交,它将指向新的子模块URL吗?
maxmelbin 2012年

62
git submodule foreach -q git config remote.origin.url看“实际”子模块的网址
乔尔Purra

9
它没有.git/config使用git 2.1.0 更新。在运行之前,我必须同时.gitmodules进行.git/config手动更新和更新,才能更新git submodule sync --recursive我的子模块。
desseim 2014年

7
这似乎遗漏了git submodule update --init --recursive --remote实际上将存储库更改为新远程服务器的关键步骤
Jason Axelson,

154

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

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


8
这行得通,但我必须记得将更改推送到遥控器。git add .gitmodules git commit -m "modified submodule URL" git push origin master
skulz00

5
好吧,这给我造成了可怕的混乱。命令悄无声息地关闭了,但是实际的子模块存储库仍然认为它的远程目录是旧的(旧的URL)。也许这些命令应该与子模块存储库中的其他命令一起使用?
Motti Shneor '16

5
最后一个命令有点极端...如果您的子模块内部有子模块,那么这也会远程更新子子模块,这不太可能需要。
巴蒂斯特·威希特

7
请注意,您需要用子模块的名称替换Submod!
Shital Shah

133

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

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

git config --file=.gitmodules -e

要不就:

vim .gitmodules

然后重新同步并更新:

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

6
git submodule update --init为我工作,--remote似乎将其绑定到远程仓库的头。
Chaim Eliyah

95

使用Git 2.25(Q1 2020),您可以对其进行修改
请参阅“ Git子模块的URL已更改 ”和新命令

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

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

实际上,2009年4月已经提交了补丁程序以阐明gitmodule角色。

因此,现在gitmodule文档尚不包括:

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

这几乎证实了吉姆的答案


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

正是在2008年8月添加了git submodule sync”,目的简化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"


我只想在这台机器上更改子模块的URL。在父项目中,我可以.git/config通过执行以下操作修改记录:此处也git config submodule."$submodule_name".url "$new_url" 对此进行了描述
joeytwiddle

可选的双破折号在git submodule set-url [--] <path> <newurl>做什么?
开玩笑

1
@jeverling他们帮助将选项与参数分开:请参见stackoverflow.com/a/1192194/6309
VonC

1
请注意,对于具有较旧版本git的Ubuntu用户,您可以使用此PPA进行更新:launchpad.net/~git-core/+archive/ubuntu/ppa
starbeamrainbowlabs

69

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

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

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


2
非常感谢你做的这些。这是在我已经进行了一项竞赛后为我工作的唯一一项git submodule update。遵循其他答案将不会更改./git/modules/external目录中的内容,因此尝试更新将导致其仍提取不正确的网址。
NtscCobalt 2014年

这似乎有点危险,而且我不确定它是否保留了先前子模块的历史记录。例如,如果您想检出主存储库的旧提交或分支(包含子模块的分支),我不确定它是否会知道拉出与主存储库的旧提交相关并与之相关的OLD子模块。 。
Motti Shneor '16

不,几乎可以肯定不知道-您必须在第一个步骤之后再次执行所有步骤。这就是我发现可以使子模块的当前状态生效的方法。自从我写这篇文章以来,我不知道事情的状态是否已经改变,请注意:)
Ben Hymers

@MottiShneor如果您需要保留以前的子模块历史记录,的确确实很危险,尽管我不确定。就我而言,这是唯一有效的解决方案,我想要的基本上是用我自己的叉子替换原始的子模块
arainone

1
按照这些步骤操作,发现“删除已检出的子模块目录本身(不确定是否有必要)”是必需的,否则在运行git子模块更新时,您将遇到“致命:不是git存储库:...”
PiersyP

10

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

git config submodule.common.url /data/my_local_common

这是最好的方法,如果您尝试一次更改URL,而不是在超级项目中永久更改。例如,您要从磁盘上的本地副本克隆子模块。
安迪

4

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.