Git子模块警告“发现多个配置”

Pse*_*che 4 git git-submodules git-worktree

今天,我开始收到来自 git 的新警告,这是我以前从未见过的关于我的子模块的警告。例如:

warning: <hash_omitted>:.gitmodules, multiple configurations found for 'submodule.foo/bar'. Skipping second one!
Run Code Online (Sandbox Code Playgroud)

快速搜索似乎没有返回任何相关信息。我看到这里生成了警告,听起来可能与工作树有关?

这个警告究竟意味着什么,它的解决方案是什么?

tor*_*rek 5

Git 将每个子模块的配置数据存储在名为.gitmodules. 该文件具有相同布局.git/config,但不像.git/config,其实是犯。该警告告诉您该.gitmodules文件中的数据可疑(有关详细信息,请参见下文)。

每个提交存储每个文件的快照,因此每个具有子模块的提交(作为该提交的一部分)都有一个.gitmodules文件。1 检出该特定提交会导致检出.gitmodules您的工作树中的该文件,以便您可以在必要时对其进行检查和修改。注意,一旦提交制成,它的快照.gitmodules是永久性的,只读的,所以你不能修复现有的提交(S)有此文件的版本有错误,但错误只是一个警告。你可以(而且一般应)修复它在任何新的,你做的提交,通过固定的.gitmodules文件和使用git add .gitmodules


1从技术上讲,这仅适用于格式正确的提交,因为提交可以存储具有gitlink条目但缺少.gitmodules文件的树。不过,那将是一个不同的错误。


配置文件中的内容

Git 的配置文件格式大量借鉴了INI 文件。这是一个示例.git/config

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = git://git.kernel.org/pub/scm/git/git.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
Run Code Online (Sandbox Code Playgroud)

每个设置命名一个包含在节中的变量,用方括号描述。如果该部分只是像 一样[core]的一部分,则变量是core.filemode等等。如果该部分有像 的第二部分[remote "origin"],则变量是remote.origin.urlremote.origin.fetch

运行git config --local --list将上述配置转换为变量及其值的列表:

core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=git://git.kernel.org/pub/scm/git/git.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
Run Code Online (Sandbox Code Playgroud)

使用git config,您可以以编程方式操作变量。但请注意,至少通过文件格式,有可能重复一段:

$ cat foo.conf
[core]
    foo = bar
[dave]
     hal = ibm
[core]
     podbaydoors = closed
$ git config -f foo.conf -l
core.foo=bar
dave.hal=ibm
core.podbaydoors=closed
Run Code Online (Sandbox Code Playgroud)

许多 Git 以一种非常线性的方式读取这些配置文件,从系统范围的配置文件(/etc/git/config或其他一些系统特定的位置)开始,然后是您的每个用户$HOME/.gitconfig的配置文件(或类似的),然后是本地存储库的配置 ( .git/config)。如果您多次设置相同的变量,也许是通过在多个配置文件中重复一个部分,通常最后一个设置是被使用的:

[user]
     name = A
     name = B
     email = wrong@example.com
     email = wright@example.com
Run Code Online (Sandbox Code Playgroud)

您在此处的用户名和电子邮件地址将B <wright@example.com>作为后面的设置覆盖前面的设置。

然而,一些变量会累积。例如fetch,每个遥控器的设置都是这样工作的。如果你把:

[remote "origin"]
    fetch = +refs/notes/*:refs/notes/*
Run Code Online (Sandbox Code Playgroud)

在您的 中$HOME/.gitconfig,并且您的每个存储库.git/configremote.origin.fetch设置为通常的+refs/heads/*:refs/remotes/origin/*,您git fetch将强制更新您自己的所有笔记参考您通常的远程跟踪参考。(顺便说一句,这样做通常是不可取的 -如果您正在使用它们,这可能会破坏您的笔记。这只是您可以做的事情的一个示例。如果您打算这样做,请使用特殊的远程名称! )

警告,以及如何修复它

然而,当子模块代码在工作时,它会寻找第一个:

[submodule "path"]
Run Code Online (Sandbox Code Playgroud)

部分并读取这些变量。如果有第二个:

[submodule "path"]
Run Code Online (Sandbox Code Playgroud)

部分,它会忽略这些设置。2 确保第二个没有被用于任何事情;如果没有,请将其删除。如果它的某些设置应该适用,请将它们移到第一部分。

(哈希 ID 出来是因为git config可以被告知.gitmodules直接从提交或树中读取,并且子模块代码会这样做,因为在结帐完成之前需要模块设置。)


2这有点夸大其词,但解决方法仍然是一样的。

  • 我也看到相同的消息,但在 .gitmodules 中没有明显的重复。适合的版本是 git 2.25.1 但是,这个存储库有子模块,它们本身也有子模块。(不要问)。如果一个子模块出现在 master 的 .gitmodules 中,以及某些子模块的 .gitmodules 中,是否会出现该消息? (2认同)

phd*_*phd 1

编辑你的.gitmodules,验证你有 2 个带有该部分的子模块[submodule "foo/bar"]。删除第二个。