如何用另一个仓库替换Git的子模块?

110

如何使用不同的git仓库替换git子模块?

具体来说,我有一个子模块:

  • 位于 ./ExternalFrameworks/TestFramework,指向git仓库git@github.com:userA/TestFramework.git
  • 我现在想将其指向git@github.com:userB/TestFramework.git

问题是,当我按照这里描述的方法删除子模块,然后使用以下命令重新添加时,问题就出现了:

git submodule add git@github.com:userB/TestFramework.git

我遇到了这个错误:

A git directory for 'ExternalFrameworks/TestFramework' is found locally with remote(s):
  origin    git@github.com:userA/TestFramework.git
If you want to reuse this local git directory instead of cloning again from
  git@github.com:userB/TestFramework.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

1
可能是更改git子模块的远程存储库的重复问题。 - jiyinyiyong
6个回答

145
如果子模块的位置(URL)已经改变,那么你可以简单地按照以下步骤进行操作:
  1. 修改存储库根目录中的 .gitmodules 文件来使用新的 URL。
  2. 删除存储库中的子模块文件夹 rm -rf .git/modules/<submodule>
  3. 删除工作目录中的子模块文件夹 rm -rf <submodule>
  4. 运行 git submodule sync 命令。
  5. 运行 git submodule update 命令。

更完整的信息可以在其他地方找到:


5
值得注意的是:当另一个已经初始化子模块的用户得到您的更新时,他们也必须在新的子模块能够正常工作之前执行一次“git submodule sync”。 - joseph.hainline
3
这对我没有起作用。执行后,我的子模块仍然指向旧的URL。你有什么想法为什么会这样吗? - Arne
34
也许你的子模块从未被正确初始化。在它对我起作用之前,我不得不运行rm -rf .git/modules/<submodule>命令。 - David Braun
2
之后我必须进入模块的目录,git checkout我想要的分支,然后git pull。 - Nicolas Raoul
1
我收到了错误提示:服务器不允许请求未公开的对象6ed9043bcb3bf7269bba3e60f2bb59b403a7cb13,并且在子模块路径“app/code/Magenerds/PageDesigner”中获取了,但它不包含6ed9043bcb3bf7269bba3e60f2bb59b403a7cb13。直接获取该提交失败。 - Black
显示剩余5条评论

37

首先,按照已经提到的方法删除当前的子模块,该方法可以在此处找到,以方便您参考:

  • .gitmodules文件中删除相关部分
  • .git/config文件中删除相关部分
  • 运行git rm --cached path_to_submodule(不带尾随斜杠)
  • 提交并删除现在未被跟踪的子模块文件

现在,使用--name标志添加新的子模块。这将为 git 提供一个替代名称,以便在.git/config中引用子模块,并与历史上存在的子模块进行区分,您仍然需要在之前的历史记录中使用它。

因此,请键入:

git submodule add --name UpdatedTestFramework git@github.com:userB/TestFramework.git

然后你将会得到子模块在你期望的路径下加载的结果。


2
虽然这种方式确实可以运作,但并不像Tim的方法那样简洁。 - joseph.hainline
4
这对我有用,但我还必须删除.git/modules/<path_to_submodule> - Nate
1
感谢提到 --name。我之前不知道与此相关的问题,直到使用了这个选项才能替换子模块(感谢你的回答)。 - aknuds1
这最终是我唯一行得通的方法,但是我想保持相同的目录名称。它确实检出了正确的路径并使模块名称成为所需名称,但工作目录名称是新存储库名称。因此,如果您想要相同的名称,您还需要在URL结尾处指定该名称,如下所示:git submodule add --name old-name-to-keep git@github.com:userB/new-repository.git old-name-to-keep - rgb

11

这些命令将在命令提示符上执行,而不会更改本地存储库中的任何文件。

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

这些命令会更改.gitmodules文件。 - rustyx

5
我可以帮您进行翻译。这段内容的意思是:在您的 git 仓库根目录下(而不是子模块),运行以下命令即可解决此问题。
rm -rf .git/modules/yourmodule

然后您应该能够像平常一样添加。

3
我发现最简单的方法是这样的:
git rm -rf [submodule_dir]
git submodule add --name new_[submodule_name] [new_submodule_url] [submodule_dir]

我不喜欢手动修改我的.gitmodules文件的想法。我还写了一篇小博客介绍了这个方法。


3

如果你只想更改此克隆的远程URL:

git config submodule."$submodule_name".url "$new_url"

这不会影响父项目中的.gitmodules文件,因此不会传播给其他开发人员。

这被描述为“用户特定记录更改” 在这里

不要运行git submodule sync,因为那会再次重置为默认URL。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接