diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 16350a5bf..1cc3c8507 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -377,10 +377,16 @@ struct EvalSettings : Config "Prefixes of URIs that builtin functions such as fetchurl and fetchGit are allowed to fetch."}; Setting traceFunctionCalls{this, false, "trace-function-calls", - "Emit log messages for each function entry and exit at the 'vomit' log level (-vvvv)"}; + "Emit log messages for each function entry and exit at the 'vomit' log level (-vvvv)."}; Setting flakeRegistry{this, "https://raw.githubusercontent.com/NixOS/flake-registry/master/flake-registry.json", "flake-registry", "Path or URI of the global flake registry."}; + + Setting allowDirty{this, true, "allow-dirty", + "Whether to allow dirty Git/Mercurial trees."}; + + Setting warnDirty{this, true, "warn-dirty", + "Whether to warn about dirty Git/Mercurial trees."}; }; extern EvalSettings evalSettings; diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index d9bbf85c2..f18159c05 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -480,9 +480,10 @@ ResolvedFlake resolveFlake(EvalState & state, const FlakeRef & topRef, HandleLoc if (!(lockFile == oldLockFile)) { if (allowedToWrite(handleLockFile)) { if (auto refData = std::get_if(&topRef.data)) { - if (lockFile.isDirty()) - warn("will not write lock file of flake '%s' because it has a dirty input", topRef); - else { + if (lockFile.isDirty()) { + if (evalSettings.warnDirty) + warn("will not write lock file of flake '%s' because it has a dirty input", topRef); + } else { lockFile.write(refData->path + (topRef.subdir == "" ? "" : "/" + topRef.subdir) + "/flake.lock"); // Hack: Make sure that flake.lock is visible to Git, so it ends up in the Nix store. diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc index 48d84c4a1..1b55b6f32 100644 --- a/src/libexpr/primops/fetchGit.cc +++ b/src/libexpr/primops/fetchGit.cc @@ -47,7 +47,11 @@ GitInfo exportGit(ref store, std::string uri, /* This is an unclean working tree. So copy all tracked files. */ - warn("Git tree '%s' is dirty", uri); + if (!evalSettings.allowDirty) + throw Error("Git tree '%s' is dirty", uri); + + if (evalSettings.warnDirty) + warn("Git tree '%s' is dirty", uri); GitInfo gitInfo; gitInfo.ref = "HEAD"; diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index c791443c3..40082894f 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -36,7 +36,11 @@ HgInfo exportMercurial(ref store, const std::string & uri, /* This is an unclean working tree. So copy all tracked files. */ - printTalkative("copying unclean Mercurial working tree '%s'", uri); + if (!evalSettings.allowDirty) + throw Error("Mercurial tree '%s' is unclean", uri); + + if (evalSettings.warnDirty) + warn("Mercurial tree '%s' is unclean", uri); HgInfo hgInfo; hgInfo.rev = "0000000000000000000000000000000000000000";