Git fetcher: Ignore .gitmodules entries that are not submodules

Fixes #10739.
This commit is contained in:
Eelco Dolstra 2024-09-04 14:43:43 +02:00
parent 357cec93b6
commit 9d24080090
2 changed files with 33 additions and 6 deletions

View file

@ -601,12 +601,16 @@ struct GitSourceAccessor : SourceAccessor
return readBlob(path, true); return readBlob(path, true);
} }
Hash getSubmoduleRev(const CanonPath & path) /**
* If `path` exists and is a submodule, return its
* revision. Otherwise return nothing.
*/
std::optional<Hash> getSubmoduleRev(const CanonPath & path)
{ {
auto entry = need(path); auto entry = lookup(path);
if (git_tree_entry_type(entry) != GIT_OBJECT_COMMIT) if (!entry || git_tree_entry_type(entry) != GIT_OBJECT_COMMIT)
throw Error("'%s' is not a submodule", showPath(path)); return std::nullopt;
return toHash(*git_tree_entry_id(entry)); return toHash(*git_tree_entry_id(entry));
} }
@ -1074,8 +1078,10 @@ std::vector<std::tuple<GitRepoImpl::Submodule, Hash>> GitRepoImpl::getSubmodules
auto rawAccessor = getRawAccessor(rev); auto rawAccessor = getRawAccessor(rev);
for (auto & submodule : parseSubmodules(pathTemp)) { for (auto & submodule : parseSubmodules(pathTemp)) {
auto rev = rawAccessor->getSubmoduleRev(submodule.path); /* Filter out .gitmodules entries that don't exist or are not
result.push_back({std::move(submodule), rev}); submodules. */
if (auto rev = rawAccessor->getSubmoduleRev(submodule.path))
result.push_back({std::move(submodule), *rev});
} }
return result; return result;

View file

@ -104,6 +104,27 @@ noSubmoduleRepo=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$subR
[[ $noSubmoduleRepoBaseline == $noSubmoduleRepo ]] [[ $noSubmoduleRepoBaseline == $noSubmoduleRepo ]]
# Test .gitmodules with entries that refer to non-existent objects or objects that are not submodules.
cat >> $rootRepo/.gitmodules <<EOF
[submodule "missing"]
path = missing
url = https://example.org/missing.git
[submodule "file"]
path = file
url = https://example.org/file.git
EOF
echo foo > $rootRepo/file
git -C $rootRepo add file
git -C $rootRepo commit -a -m "Add bad submodules"
rev=$(git -C $rootRepo rev-parse HEAD)
r=$(nix eval --raw --expr "builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }")
[[ -f $r/file ]]
[[ ! -e $r/missing ]]
# Test relative submodule URLs. # Test relative submodule URLs.
rm $TEST_HOME/.cache/nix/fetcher-cache* rm $TEST_HOME/.cache/nix/fetcher-cache*
rm -rf $rootRepo/.git $rootRepo/.gitmodules $rootRepo/sub rm -rf $rootRepo/.git $rootRepo/.gitmodules $rootRepo/sub