4

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

warning: <hash_omitted>:.gitmodules, multiple configurations found for 'submodule.foo/bar'. Skipping second one!

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

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

4

2 回答 2

5

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

每个提交都存储每个文件的快照,因此每个具有子模块的提交都具有(作为该提交的一部分)一个.gitmodules文件。1 签出该特定提交会导致.gitmodules在您的工作树中签出该文件,以便您可以检查它并在必要时对其进行修改。请注意,一旦提交,其快照.gitmodules是永久且只读的,因此您无法修复现有提交中存在错误版本的错误,但该错误只是一个警告。您可以(并且通常应该)通过修复.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

每个设置命名一个包含在section中的变量,在方括号中描述。如果该部分只是像 的一部分[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

使用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

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

[user]
     name = A
     name = B
     email = wrong@example.com
     email = wright@example.com

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

但是,有些变量会累积。fetch例如,每个遥控器的设置都以这种方式工作。如果你放:

[remote "origin"]
    fetch = +refs/notes/*:refs/notes/*

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

警告,以及如何解决它

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

[submodule "path"]

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

[submodule "path"]

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

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


2这有点夸大其词,但修复方法仍然相同。

于 2018-08-16T20:30:07.470 回答
1

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

于 2018-08-16T20:28:00.010 回答