forked from lix-project/lix
Add explicit allRefs = true;
argument to fetchGit
Sometimes it's necessary to fetch a git repository at a revision and it's unknown which ref contains the revision in question. An example would be a Cargo.lock which only provides the URL and the revision when using a git repository as build input. However it's considered a bad practice to perform a full checkout of a repository since this may take a lot of time and can eat up a lot of disk space. This patch makes a full checkout explicit by adding an `allRefs` argument to `builtins.fetchGit` which fetches all refs if explicitly set to true. Closes #2409
This commit is contained in:
parent
629af83b2d
commit
2857b1baaf
|
@ -59,12 +59,13 @@ struct GitInputScheme : InputScheme
|
||||||
if (maybeGetStrAttr(attrs, "type") != "git") return {};
|
if (maybeGetStrAttr(attrs, "type") != "git") return {};
|
||||||
|
|
||||||
for (auto & [name, value] : attrs)
|
for (auto & [name, value] : attrs)
|
||||||
if (name != "type" && name != "url" && name != "ref" && name != "rev" && name != "shallow" && name != "submodules" && name != "lastModified" && name != "revCount" && name != "narHash")
|
if (name != "type" && name != "url" && name != "ref" && name != "rev" && name != "shallow" && name != "submodules" && name != "lastModified" && name != "revCount" && name != "narHash" && name != "allRefs")
|
||||||
throw Error("unsupported Git input attribute '%s'", name);
|
throw Error("unsupported Git input attribute '%s'", name);
|
||||||
|
|
||||||
parseURL(getStrAttr(attrs, "url"));
|
parseURL(getStrAttr(attrs, "url"));
|
||||||
maybeGetBoolAttr(attrs, "shallow");
|
maybeGetBoolAttr(attrs, "shallow");
|
||||||
maybeGetBoolAttr(attrs, "submodules");
|
maybeGetBoolAttr(attrs, "submodules");
|
||||||
|
maybeGetBoolAttr(attrs, "allRefs");
|
||||||
|
|
||||||
if (auto ref = maybeGetStrAttr(attrs, "ref")) {
|
if (auto ref = maybeGetStrAttr(attrs, "ref")) {
|
||||||
if (std::regex_search(*ref, badGitRefRegex))
|
if (std::regex_search(*ref, badGitRefRegex))
|
||||||
|
@ -169,10 +170,12 @@ struct GitInputScheme : InputScheme
|
||||||
|
|
||||||
bool shallow = maybeGetBoolAttr(input.attrs, "shallow").value_or(false);
|
bool shallow = maybeGetBoolAttr(input.attrs, "shallow").value_or(false);
|
||||||
bool submodules = maybeGetBoolAttr(input.attrs, "submodules").value_or(false);
|
bool submodules = maybeGetBoolAttr(input.attrs, "submodules").value_or(false);
|
||||||
|
bool allRefs = maybeGetBoolAttr(input.attrs, "allRefs").value_or(false);
|
||||||
|
|
||||||
std::string cacheType = "git";
|
std::string cacheType = "git";
|
||||||
if (shallow) cacheType += "-shallow";
|
if (shallow) cacheType += "-shallow";
|
||||||
if (submodules) cacheType += "-submodules";
|
if (submodules) cacheType += "-submodules";
|
||||||
|
if (allRefs) cacheType += "-all-refs";
|
||||||
|
|
||||||
auto getImmutableAttrs = [&]()
|
auto getImmutableAttrs = [&]()
|
||||||
{
|
{
|
||||||
|
@ -338,11 +341,15 @@ struct GitInputScheme : InputScheme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* If the local ref is older than ‘tarball-ttl’ seconds, do a
|
if (allRefs) {
|
||||||
git fetch to update the local ref to the remote ref. */
|
doFetch = true;
|
||||||
struct stat st;
|
} else {
|
||||||
doFetch = stat(localRefFile.c_str(), &st) != 0 ||
|
/* If the local ref is older than ‘tarball-ttl’ seconds, do a
|
||||||
(uint64_t) st.st_mtime + settings.tarballTtl <= (uint64_t) now;
|
git fetch to update the local ref to the remote ref. */
|
||||||
|
struct stat st;
|
||||||
|
doFetch = stat(localRefFile.c_str(), &st) != 0 ||
|
||||||
|
(uint64_t) st.st_mtime + settings.tarballTtl <= (uint64_t) now;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doFetch) {
|
if (doFetch) {
|
||||||
|
@ -352,9 +359,11 @@ struct GitInputScheme : InputScheme
|
||||||
// we're using --quiet for now. Should process its stderr.
|
// we're using --quiet for now. Should process its stderr.
|
||||||
try {
|
try {
|
||||||
auto ref = input.getRef();
|
auto ref = input.getRef();
|
||||||
auto fetchRef = ref->compare(0, 5, "refs/") == 0
|
auto fetchRef = allRefs
|
||||||
? *ref
|
? "refs/*"
|
||||||
: "refs/heads/" + *ref;
|
: ref->compare(0, 5, "refs/") == 0
|
||||||
|
? *ref
|
||||||
|
: "refs/heads/" + *ref;
|
||||||
runProgram("git", true, { "-C", repoDir, "fetch", "--quiet", "--force", "--", actualUrl, fmt("%s:%s", fetchRef, fetchRef) });
|
runProgram("git", true, { "-C", repoDir, "fetch", "--quiet", "--force", "--", actualUrl, fmt("%s:%s", fetchRef, fetchRef) });
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
if (!pathExists(localRefFile)) throw;
|
if (!pathExists(localRefFile)) throw;
|
||||||
|
|
Loading…
Reference in a new issue