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

发布于 2024-07-22 23:23:31 字数 138 浏览 11 评论 0 原文

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

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

I've created a git repository with a submodule in it. I'm able to tell the submodule itself to change its remote repository path, but I'm not sure how to tell the parent repository how to change the remote repository path for the submodule.

I wouldn't be surprised if I'm somewhat out of luck and have to do things manually, as even deleting submodules isn't easy.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

罪歌 2024-07-29 23:23:31

您应该能够编辑 .gitmodules 文件来更新 URL,然后运行 ​​git submodulesync --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

You should just be able to edit the .gitmodules file to update the URL and then run git submodule sync --recursive to reflect that change to the superproject and your working copy.

Then you need to go to the .git/modules/path_to_submodule dir and change its config file to update git path.

If repo history is different then you need to checkout new branch manually:

git submodule sync --recursive
cd <submodule_dir> 

git fetch
git checkout origin/master
git branch master -f
git checkout master
血之狂魔 2024-07-29 23:23:31

使用 Git 2.25(2020 年第 1 季度),您可以修改它。
请参阅“Git 子模块 url 已更改”和新命令

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

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

警告Hi-Angel 提到在评论中(甚至使用 Git 2.31.1 进行了测试):

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

如果在您的 .gitmodules 文件中,路径看起来像这样 some-path,然后执行:

# 通常会导致意外行为 
  git 子模块 set-url some-path/ new-url 
  

(注意 some-path/ 中的尾部斜杠 /,然后,该命令将 添加另一个。 而是运行:

<前><代码># 好
git 子模块 set-url some-path new-url


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

实际上,补丁有于 2009 年 4 月提交,以阐明 gitmodule 角色。

所以现在 gitmodule 文档 尚不包括:

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

这几乎证实了吉姆的回答


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

git submodulesync”已 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"


注意:

Git 2.40 (Q1 2023)澄清 git config remote..url

请参阅 commit d390e08< /a>(2023 年 2 月 7 日)作者:Calvin Wan (CalvinWan0101)
(由 Junio C Hamano -- gitster -- 合并于 提交 59397e9,2023 年 2 月 15 日)

文档:澄清多个pushurls< /code> 与 url

签字人:Calvin Wan

在具有多个已配置 URL 的远程中,git Remote -v(man) 显示 fetch 使用的正确 url。

但是,git config remote。(man) 返回最后定义的 url

这种差异可能会导致使用如此定义的远程的用户感到困惑,因为在第一个之后定义的任何 url 本质上都充当 pushurl

添加文档以阐明 fetch 如何与多个 URL 交互以及 Push 如何与多个 PushURL 和 URL 交互。

urls-remotes 现在包含在其 手册页

仅用于推送。

可选且默认

推送到远程会影响所有已定义的推送网址或所有
如果没有定义 Pushurl,则定义 url。
然而,Fetch 只会
如果定义了多个 url,则从第一个定义的 url 获取。


Git 2.44(2024 年第 1 季度),第 10 批,加强了 fsck 在记录的 URL 中进行的 URL 检查对于子模块。

因此,当您更改 URL 时,URL 有效性检查现在更加可靠。

请参阅 提交 8430b43提交 7e2fc39, 提交 6af2c4a提交 13320ff(2024 年 1 月 18 日),作者:维多利亚染料 (vdye)
(由 Junio C Hamano -- gitster -- 合并于 提交 76bd129,2024 年 1 月 26 日)

submodule-config.c:加强URL fsck检查

签字人:Victoria Dye

更新“curl URL”子模块 URL 的验证(即
在“check_submodule_url()”中指定“http[s]”或“ftp[s]”协议的协议)以捕获更多无效 URL。
使用“credential_from_url_gently()”的现有验证错误地解析了某些 URL,导致传递“git fsck'(man) 检查。
相反,“url_normalize()” - 用于验证“remote_get()”中的远程 URL - 正确识别“credential_from_url_gently()'.

要捕获更多无效情况,请将“credential_from_url_gently()”替换为“url_normalize()”,后跟“url_decode()”以及换行符检查(在“credential_from_url_gently()”验证中镜像“check_url_component()”)。

With Git 2.25 (Q1 2020), you can modify it.
See "Git submodule url changed" and the new command

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

(On the -- separator, see "double hyphen as a signal to stop option interpretation and treat all following arguments literally")

WARNING: Hi-Angel mentions in the comments (tested even with Git 2.31.1):

One should be careful with git submodule set-url because it has a bug:

If, inside your .gitmodules file, the path looks like this some-path, and then you execute a:

# Usually causes unexpected behavior
git submodule set-url some-path/ new-url

(note the trailing slash / in some-path/), then, instead of modifying existing submodule, the command will add another one. Instead run:

# Good
git submodule set-url some-path new-url

Original answer (May 2009, fourteen years ago)

Actually, a patch has been submitted in April 2009 to clarify gitmodule role.

So now the gitmodule documentation does not yet include:

The .gitmodules file, located in the top-level directory of a git working tree, is a text file with a syntax matching the requirements -of linkgit:git-config4.
[NEW]:
As this file is managed by Git, it tracks the +records of a project's submodules.
Information stored in this file is used as a hint to prime the authoritative version of the record stored in the project configuration file.
User specific record changes (e.g. to account for differences in submodule URLs due to networking situations) should be made to the configuration file, while record changes to be propagated (e.g. +due to a relocation of the submodule source) should be made to this file.

That pretty much confirm Jim's answer.


If you follow this git submodule tutorial, you see you need a "git submodule init" to add the submodule repository URLs to .git/config.

"git submodule sync" has been added in August 2008 precisely to make that task easier when URL changes (especially if the number of submodules is important).
The associate script with that command is straightforward enough:

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

The goal remains: git config remote."$remote".url "$url"


Note:

Git 2.40 (Q1 2023) clarifies git config remote.<remote>.url:

See commit d390e08 (07 Feb 2023) by Calvin Wan (CalvinWan0101).
(Merged by Junio C Hamano -- gitster -- in commit 59397e9, 15 Feb 2023)

Documentation: clarify multiple pushurls vs urls

Signed-off-by: Calvin Wan

In a remote with multiple configured URLs, git remote -v(man) shows the correct url that fetch uses.

However, git config remote.<remote>.url(man) returns the last defined url instead.

This discrepancy can cause confusion for users with a remote defined as such, since any url defined after the first essentially acts as a pushurl.

Add documentation to clarify how fetch interacts with multiple urls and how push interacts with multiple pushurls and urls.

urls-remotes now includes in its man page:

The <pushurl> is used for pushes only.

It is optional and defaults
to <URL>.

Pushing to a remote affects all defined pushurls or to all
defined urls if no pushurls are defined.
Fetch, however, will only
fetch from the first defined url if muliple urls are defined.


Git 2.44 (Q1 2024), batch 10, tightens URL checks fsck makes in a URL recorded for submodules.

So when you change the URL, the URL validity check is now more robust.

See commit 8430b43, commit 7e2fc39, commit 6af2c4a, commit 13320ff (18 Jan 2024) by Victoria Dye (vdye).
(Merged by Junio C Hamano -- gitster -- in commit 76bd129, 26 Jan 2024)

submodule-config.c: strengthen URL fsck check

Signed-off-by: Victoria Dye

Update the validation of "curl URL" submodule URLs (i.e.
those that specify an "http[s]" or "ftp[s]" protocol) in 'check_submodule_url()' to catch more invalid URLs.
The existing validation using 'credential_from_url_gently()' parses certain URLs incorrectly, leading to invalid submodule URLs passing 'git fsck'(man) checks.
Conversely, 'url_normalize()' - used to validate remote URLs in 'remote_get()' - correctly identifies the invalid URLs missed by 'credential_from_url_gently()'.

To catch more invalid cases, replace 'credential_from_url_gently()' with 'url_normalize()' followed by a 'url_decode()' and a check for newlines (mirroring 'check_url_component()' in the 'credential_from_url_gently()' validation).

烟酉 2024-07-29 23:23:31

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

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

These commands will do the work on command prompt without altering any files on local repository

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

Please look at the blog for screenshots: Changing GIT submodules URL/Branch to other URL/branch of same repository

小瓶盖 2024-07-29 23:23:31

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

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

git config --file=.gitmodules -e

或者只是:

vim .gitmodules

然后重新同步并更新:

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

In simple terms, you just need to edit the .gitmodules file, then resync and update:

Edit the file, either via a git command or directly:

git config --file=.gitmodules -e

or just:

vim .gitmodules

then resync and update:

git submodule sync
git submodule update --init --recursive --remote
挽袖吟 2024-07-29 23:23:31

对我有用的方法(在 Windows 上,使用 git 版本 1.8.3.msysgit.0):

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

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

What worked for me (on Windows, using git version 1.8.3.msysgit.0):

  • Update .gitmodules with the URL to the new repository
  • Remove the corresponding line from the ".git/config" file
  • Delete the corresponding directory in the ".git/modules/external" directory (".git/modules" for recent git versions)
  • Delete the checked out submodule directory itself (unsure if this is necessary)
  • Run git submodule init and git submodule update
  • Make sure the checked out submodule is at the correct commit, and commit that, since it's likely that the hash will be different

After doing all that, everything is in the state I would expect. I imagine other users of the repository will have similar pain when they come to update though - it would be wise to explain these steps in your commit message!

山人契 2024-07-29 23:23:31

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

git config submodule.common.url /data/my_local_common

Just edit your .git/config file. For example; if you have a "common" submodule you can do this in the super-module:

git config submodule.common.url /data/my_local_common
荒芜了季节 2024-07-29 23:23:31

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

git config --file=.gitmodules -e opens the default editor in which you can update the path

忘年祭陌 2024-07-29 23:23:31

强力方法:

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

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

A brute force approach:

  • update the .gitmodules file in the supermodule to point to the new submodule url,
  • add and commit the changes to supermodule/.gitmodules,
  • make a new clone of the supermodule somewhere else on your computer (making sure that the latest changes to the .gitmodules file are reflected in the clone),
  • change your working directory to the new clone of the supermodule,
  • run git submodule update --init --remote path-to-submodule on the submodule,

et voilà! The submodule in the new clone of the supermodule is properly configured!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文