aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-13 21:09:04 +0000
committertv <tv@krebsco.de>2026-11-13 22:14:38 +0100
commit0273a55087e2614323d6ebd145b08c56b370a483 (patch)
tree14c5e7ea01a862d2d359319236c54d9760ea1ddd /tests
parentc3ca6d4b991ea24192ac4ddec156d0530b462c3e (diff)
populate: check the hooks and submodules of Git work trees
git submodule update uses the .git of a submodule as it finds it in the work tree: a repository of its own, with configuration that runs commands, or a file naming a repository elsewhere. So git_problems also requires each .git below the work tree to be a file naming a repository in .git/modules. And it refuses hooks in .git/hooks, which populate's Git doesn't run, but Nix's does, writing the lock file of a flake in a git source. It's a shell function now, taking the work tree at run time, so drawing inputs can use it too. git-submodule plants a submodule's .git in the work tree: a repository of its own whose configuration names a filter, and a file naming a repository elsewhere. The fixture withsub has gitsrc as its submodule sub.
Diffstat (limited to 'tests')
-rwxr-xr-xtests/fixtures.sh17
-rw-r--r--tests/scenarios.nix60
2 files changed, 77 insertions, 0 deletions
diff --git a/tests/fixtures.sh b/tests/fixtures.sh
index ccd55a0..85701a1 100755
--- a/tests/fixtures.sh
+++ b/tests/fixtures.sh
@@ -307,6 +307,23 @@ mkdir /fixtures/git
git clone -q --bare /fixtures/gitsrc /fixtures/git/gitsrc.git
git -C /fixtures/git/gitsrc.git config uploadpack.allowReachableSHA1InWant true
+# withsub: a Git repository with gitsrc as its submodule sub, served by git
+# daemon like gitsrc, which the tests reach as git://deployer/gitsrc.git.
+mkdir /fixtures/withsub
+cat > /fixtures/withsub/.gitmodules <<'GIT'
+[submodule "sub"]
+ path = sub
+ url = git://deployer/gitsrc.git
+GIT
+(
+ cd /fixtures/withsub
+ git init -q -b master
+ git update-index --add --cacheinfo 160000,"$git_head",sub
+ git add .gitmodules
+ git commit -q -m withsub
+)
+git clone -q --bare /fixtures/withsub /fixtures/git/withsub.git
+
# pass: password stores with x/a, without and with Git.
if ! gpg --list-secret-keys spam@krebsco.de >/dev/null 2>&1; then
gpg --batch --passphrase '' --quick-gen-key spam@krebsco.de default default never
diff --git a/tests/scenarios.nix b/tests/scenarios.nix
index 8093e02..5d08e2e 100644
--- a/tests/scenarios.nix
+++ b/tests/scenarios.nix
@@ -2104,6 +2104,66 @@ assert !(krops.isLocalTarget (targets.remote "/"));
}
];
}))
+ # A Git work tree whose submodule's .git, which Git uses as it finds it,
+ # isn't the gitfile git clone made, naming the repository in
+ # .git/modules: a repository of its own, whose configuration names a
+ # command, and a gitfile naming a repository elsewhere.
+ (s "git-submodule" (let
+ elsewhere = "/var/krops-elsewhere";
+ url = dirOf gitUrl + "/withsub.git";
+ git = reclone: { x.git = { inherit url reclone; ref = "master"; }; };
+ untouched = ''
+ test ! -e ${elsewhere}/ran || fail "a command in a .git directory ran"
+ expect_eq "HEAD elsewhere" "$(git -C ${elsewhere}/repo rev-parse HEAD)" ${gitFirst}
+ '';
+ in {
+ isolate = true;
+ prepare = ''
+ rm -fR ${elsewhere}
+ git clone -q ${gitUrl} ${elsewhere}/repo
+ git -C ${elsewhere}/repo checkout -q ${gitFirst}
+ '';
+ phases = [
+ {
+ sources = git false;
+ check = untouched + ''
+ expect_eq "sub HEAD" "$(git -C "$T"/x/sub rev-parse HEAD)" ${gitHead}
+ '';
+ mutate = ''
+ rm "$T"/x/sub/.git
+ cp -R "$T"/x/.git/modules/sub "$T"/x/sub/.git
+ git config --file "$T"/x/sub/.git/config --unset core.worktree
+ git config --file "$T"/x/sub/.git/config \
+ filter.x.smudge "touch ${elsewhere}/ran; cat"
+ echo '* filter=x' > "$T"/x/sub/.git/info/attributes
+ git -C "$T"/x/sub update-ref --no-deref HEAD ${gitFirst}
+ git -C "$T"/x/sub read-tree ${gitFirst}
+ rm "$T"/x/sub/two
+ '';
+ }
+ {
+ sources = git false;
+ expect.fail = "error: populate doesn't use the Git work tree";
+ check = untouched;
+ mutate = ''
+ rm -fR "$T"/x/sub
+ mkdir "$T"/x/sub
+ echo gitdir: ${elsewhere}/repo/.git > "$T"/x/sub/.git
+ '';
+ }
+ {
+ sources = git false;
+ expect.fail = "error: populate doesn't use the Git work tree";
+ check = untouched;
+ }
+ {
+ sources = git true;
+ check = untouched + ''
+ expect_eq "sub HEAD" "$(git -C "$T"/x/sub rev-parse HEAD)" ${gitHead}
+ '';
+ }
+ ];
+ }))
# A ref that git fetch would take for an option: --upload-pack runs a
# command where the repository is local.
(s "git-ref-option" (let