diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index f750d907d36..71dcfd29da2 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -251,10 +251,6 @@ struct GitInputScheme : InputScheme url.query.insert_or_assign("ref", *ref); if (getShallowAttr(input)) url.query.insert_or_assign("shallow", "1"); - if (getLfsAttr(input)) - url.query.insert_or_assign("lfs", "1"); - if (getSubmodulesAttr(input)) - url.query.insert_or_assign("submodules", "1"); if (maybeGetBoolAttr(input.attrs, "exportIgnore").value_or(false)) url.query.insert_or_assign("exportIgnore", "1"); if (maybeGetBoolAttr(input.attrs, "verifyCommit").value_or(false)) @@ -265,6 +261,11 @@ struct GitInputScheme : InputScheme url.query.insert_or_assign("publicKey", publicKeys.at(0).key); } else if (publicKeys.size() > 1) url.query.insert_or_assign("publicKeys", publicKeys_to_string(publicKeys)); + // These are allowed as self attrs, the explicit false is important + if (auto lfs = maybeGetBoolAttr(input.attrs, "lfs")) + url.query.insert_or_assign("lfs", *lfs ? "1" : "0"); + if (auto submodules = maybeGetBoolAttr(input.attrs, "submodules")) + url.query.insert_or_assign("submodules", *submodules ? "1" : "0"); return url; } @@ -884,8 +885,14 @@ struct GitInputScheme : InputScheme std::optional getFingerprint(ref store, const Input & input) const override { auto makeFingerprint = [&](const Hash & rev) { - return rev.gitRev() + (getSubmodulesAttr(input) ? ";s" : "") + (getExportIgnoreAttr(input) ? ";e" : "") - + (getLfsAttr(input) ? ";l" : ""); + std::string modifiers = ""; + if (getExportIgnoreAttr(input)) + modifiers += ";e"; + if (auto lfs = maybeGetBoolAttr(input.attrs, "lfs")) + modifiers += *lfs ? ";l1" : ";l0"; + if (auto submodules = maybeGetBoolAttr(input.attrs, "submodules")) + modifiers += *submodules ? ";s1" : ";s0"; + return rev.gitRev() + modifiers; }; if (auto rev = input.getRev()) diff --git a/src/libflake/flake.cc b/src/libflake/flake.cc index 3acf589a582..e74eff9e7cd 100644 --- a/src/libflake/flake.cc +++ b/src/libflake/flake.cc @@ -326,7 +326,7 @@ static FlakeRef applySelfAttrs(const FlakeRef & ref, const Flake & flake) for (auto & attr : flake.selfAttrs) { if (!allowedAttrs.contains(attr.first)) throw Error("flake 'self' attribute '%s' is not supported", attr.first); - newRef.input.attrs.insert_or_assign(attr.first, attr.second); + newRef.input.attrs.try_emplace(attr.first, attr.second); } return newRef; diff --git a/tests/nixos/fetch-git/test-cases/lfs/default.nix b/tests/nixos/fetch-git/test-cases/lfs/default.nix index 289c3770911..7fbc13146e8 100644 --- a/tests/nixos/fetch-git/test-cases/lfs/default.nix +++ b/tests/nixos/fetch-git/test-cases/lfs/default.nix @@ -209,6 +209,7 @@ # memorize the revision self_lfs_rev = client.succeed(f"{repo.git} rev-parse HEAD").strip() + # Check that LFS is now enabled by default with TemporaryDirectory() as tempdir: client.succeed(f"mkdir -p {tempdir}") client.succeed(f""" @@ -223,7 +224,24 @@ nix eval --debug --raw {tempdir}#.outPath """) - client.succeed(f"cmp {repo.path}/beeg {fetched_self_lfs}/beeg >&2") + client.succeed(f"cmp {repo.path}/beeg {fetched_self_lfs}/beeg >&2") + + # Check that we can disable LFS enabled by default + with TemporaryDirectory() as tempdir: + client.succeed(f"mkdir -p {tempdir}") + client.succeed(f""" + printf '{{ + inputs.foo = {{ + url = "git+{repo.remote}?ref=main&rev={self_lfs_rev}&lfs=0"; + }}; + outputs = {{ foo, self }}: {{ inherit (foo) outPath; }}; + }}' >{tempdir}/flake.nix + """) + fetched_self_nolfs = client.succeed(f""" + nix eval --debug --raw {tempdir}#.outPath + """) + + client.succeed(f"! cmp {fetched_self_lfs}/beeg {fetched_self_nolfs}/beeg >&2") with subtest("Ensure fetching with SSH generates the same output"):