0

谁能帮帮我。我想将一些 Git 存储库从一台服务器移动到另一台服务器,并同时重命名它们。我遇到的问题是当某些存储库是其他存储库的子模块时。我想在顶级模块中所有分支的历史记录中替换子模块的 URL,以便在删除原始文件后,我仍然可以返回并重建旧提交。我在 Windows PC 上,目前,我正在使用 .bat 文件来运行我的存储库迁移。

要将子模块从 server1 移动到 server2 并将名称从 sub_old 更改为 sub_new,我将原始(裸机)克隆到 C: 驱动器上的文件夹中,更改 URL,然后向上推送到新服务器:

git clone --bare https://server1/sub_old.git c:\temp_repo
cd c:\temp_repo
git remote set-url origin https://server2/sub_new.git
git push --mirror

然后从 server1 中删除 sub_old。

现在,当我想将使用 sub_old 存储库作为子模块的顶级存储库移动到新服务器时:

git clone --bare https://server1/top_old.git c:\temp_repo
cd c:\temp_repo
git remote set-url origin https://server2/top_new.git
REM At this point I want to change all of the references to the submodule from https://server1/sub_old.git to https://server2/sub_new.git
git push --mirror

然后从 server1 中删除 top_old。

在我想更改对子模块的所有 URL 引用时,我尝试使用:

git config --global url.https://server2/sub_new.git.insteadOf https://server1/sub_old.git

但没有成功。我显然不明白这应该如何工作,或者它是否适合使用。

4

1 回答 1

0

我想在所有分支的历史中替换子模块的 URL ...

这需要使用git filter-branchor git filter-repo。技术上不可能更改任何提交,因此这些命令不会这样做。相反,它们会将您现有存储库的提交复制到包含备用历史记录的全新提交集。1

如果您选择这样做,请非常确定您想要这样做,因为没有回头路。考虑使用 newfangled git filter-repo,它更擅长这种事情。2 请记住,一旦完成,任何人都不应再使用旧存储库或其任何克隆。把那些克隆扔出去。而是制作新存储库新克隆。

您使用的git config替代技巧有时是一种更好的方法。这不会在整个历史记录中替换子模块的 URL!相反,这会使所有原始提交保持不变。这只是意味着对而言——仅限您的帐户,因为您使用git config --global了 : 没有其他用户受此影响——只要您的 Git 将要访问原始 URL,它就会切换到替换 URL。

为使其适用于任何其他用户,这些其他用户必须采取相同的git config步骤。如果这是一个问题,您需要“用新的存储库(代表替代历史的全新提交)替换存储库(所有提交,它们是历史)”方法。


1如果重写的“替代历史”从未重写的提交开始,则替代历史几乎是全新的,而不是全新的。从某种意义上说,这更糟糕,因为它更容易意外地重新引入原始历史。然后你有两个历史,很难判断哪一个是“真实的”。

2它似乎没有针对性的“修复子模块 URL”选项,但这是一个合理的要求。在内部,这相当于过滤名为 的文件.gitmodules,所以它应该很容易实现。

于 2021-04-27T00:06:49.620 回答