forked from lix-project/lix
Unfetched submodules are included as empty directories in archives, so they end
up as such in the store when fetched in clean mode. Make sure the same happens
in dirty mode too. Fortunately, they are already correctly represented in the
ls-files output, so we just need to make sure to include the empty directory in
our filter.
Fixes: https://github.com/NixOS/nix/issues/6247
Change-Id: I60d06ff360cfa305d081b920838c893c06da801c
131 lines
5.7 KiB
Bash
131 lines
5.7 KiB
Bash
source common.sh
|
|
|
|
set -u
|
|
|
|
requireGit
|
|
|
|
clearStore
|
|
|
|
rootRepo=$TEST_ROOT/gitSubmodulesRoot
|
|
subRepo=$TEST_ROOT/gitSubmodulesSub
|
|
|
|
rm -rf ${rootRepo} ${subRepo} $TEST_HOME/.cache/nix
|
|
|
|
# Submodules can't be fetched locally by default, which can cause
|
|
# information leakage vulnerabilities, but for these tests our
|
|
# submodule is intentionally local and it's all trusted, so we
|
|
# disable this restriction. Setting it per repo is not sufficient, as
|
|
# the repo-local config does not apply to the commands run from
|
|
# outside the repos by Nix.
|
|
export XDG_CONFIG_HOME=$TEST_HOME/.config
|
|
git config --global protocol.file.allow always
|
|
|
|
initGitRepo() {
|
|
git init $1
|
|
git -C $1 config user.email "foobar@example.com"
|
|
git -C $1 config user.name "Foobar"
|
|
}
|
|
|
|
addGitContent() {
|
|
echo "lorem ipsum" > $1/content
|
|
git -C $1 add content
|
|
git -C $1 commit -m "Initial commit"
|
|
}
|
|
|
|
initGitRepo $subRepo
|
|
addGitContent $subRepo
|
|
|
|
initGitRepo $rootRepo
|
|
|
|
git -C $rootRepo submodule init
|
|
git -C $rootRepo submodule add $subRepo sub
|
|
git -C $rootRepo add sub
|
|
r0=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = file://$rootRepo; }).outPath")
|
|
git -C $rootRepo commit -m "Add submodule"
|
|
|
|
rev=$(git -C $rootRepo rev-parse HEAD)
|
|
|
|
r1=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; }).outPath")
|
|
r2=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = false; }).outPath")
|
|
r3=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }).outPath")
|
|
|
|
[[ $r0 == $r1 ]] # verify that unfetched submodules result in empty directories in dirty mode too
|
|
[[ $r1 == $r2 ]]
|
|
[[ $r2 != $r3 ]]
|
|
|
|
r4=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; }).outPath")
|
|
r5=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = false; }).outPath")
|
|
r6=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath")
|
|
r7=$(nix eval --raw --expr "(builtins.fetchGit { url = $rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath")
|
|
r8=$(nix eval --raw --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; submodules = true; }).outPath")
|
|
|
|
[[ $r1 == $r4 ]]
|
|
[[ $r4 == $r5 ]]
|
|
[[ $r3 == $r6 ]]
|
|
[[ $r6 == $r7 ]]
|
|
[[ $r7 == $r8 ]]
|
|
|
|
have_submodules=$(nix eval --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; }).submodules")
|
|
[[ $have_submodules == false ]]
|
|
|
|
have_submodules=$(nix eval --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; submodules = false; }).submodules")
|
|
[[ $have_submodules == false ]]
|
|
|
|
have_submodules=$(nix eval --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; submodules = true; }).submodules")
|
|
[[ $have_submodules == true ]]
|
|
|
|
pathWithoutSubmodules=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; }).outPath")
|
|
pathWithSubmodules=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }).outPath")
|
|
pathWithSubmodulesAgain=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }).outPath")
|
|
pathWithSubmodulesAgainWithRef=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath")
|
|
|
|
# The resulting store path cannot be the same.
|
|
[[ $pathWithoutSubmodules != $pathWithSubmodules ]]
|
|
|
|
# Checking out the same repo with submodules returns in the same store path.
|
|
[[ $pathWithSubmodules == $pathWithSubmodulesAgain ]]
|
|
|
|
# Checking out the same repo with submodules returns in the same store path.
|
|
[[ $pathWithSubmodulesAgain == $pathWithSubmodulesAgainWithRef ]]
|
|
|
|
# The submodules flag is actually honored.
|
|
[[ ! -e $pathWithoutSubmodules/sub/content ]]
|
|
[[ -e $pathWithSubmodules/sub/content ]]
|
|
|
|
[[ -e $pathWithSubmodulesAgainWithRef/sub/content ]]
|
|
|
|
# No .git directory or submodule reference files must be left
|
|
test "$(find "$pathWithSubmodules" -name .git)" = ""
|
|
|
|
# Git repos without submodules can be fetched with submodules = true.
|
|
subRev=$(git -C $subRepo rev-parse HEAD)
|
|
noSubmoduleRepoBaseline=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$subRepo; rev = \"$subRev\"; }).outPath")
|
|
noSubmoduleRepo=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$subRepo; rev = \"$subRev\"; submodules = true; }).outPath")
|
|
|
|
[[ $noSubmoduleRepoBaseline == $noSubmoduleRepo ]]
|
|
|
|
# Test relative submodule URLs.
|
|
rm $TEST_HOME/.cache/nix/fetcher-cache*
|
|
rm -rf $rootRepo/.git $rootRepo/.gitmodules $rootRepo/sub
|
|
initGitRepo $rootRepo
|
|
git -C $rootRepo submodule add ../gitSubmodulesSub sub
|
|
git -C $rootRepo commit -m "Add submodule"
|
|
rev2=$(git -C $rootRepo rev-parse HEAD)
|
|
pathWithRelative=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev2\"; submodules = true; }).outPath")
|
|
diff -r -x .gitmodules $pathWithSubmodules $pathWithRelative
|
|
|
|
# Test clones that have an upstream with relative submodule URLs.
|
|
rm $TEST_HOME/.cache/nix/fetcher-cache*
|
|
cloneRepo=$TEST_ROOT/a/b/gitSubmodulesClone # NB /a/b to make the relative path not work relative to $cloneRepo
|
|
git clone $rootRepo $cloneRepo
|
|
pathIndirect=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$cloneRepo; rev = \"$rev2\"; submodules = true; }).outPath")
|
|
[[ $pathIndirect = $pathWithRelative ]]
|
|
|
|
# Test that if the clone has the submodule already, we're not fetching
|
|
# it again.
|
|
git -C $cloneRepo submodule update --init
|
|
rm $TEST_HOME/.cache/nix/fetcher-cache*
|
|
rm -rf $subRepo
|
|
pathSubmoduleGone=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$cloneRepo; rev = \"$rev2\"; submodules = true; }).outPath")
|
|
[[ $pathSubmoduleGone = $pathWithRelative ]]
|