Skip to content

Commit dbe6770

Browse files
committed
Use non-shallow cache repo if it contains the requested commit
This fixes the issue where updating a Git input does a non-shallow fetch, and then a subsequent eval does a shallow refetch because the revCount is already known. Now the subsequent eval will use the repo used in the first fetch.
1 parent 5fcf9f0 commit dbe6770

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

src/libfetchers/git.cc

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,11 +656,27 @@ struct GitInputScheme : InputScheme
656656
if (!input.getRev())
657657
input.attrs.insert_or_assign("rev", GitRepo::openRepo(repoDir)->resolveRef(ref).gitRev());
658658
} else {
659+
auto rev = input.getRev();
659660
auto repoUrl = std::get<ParsedURL>(repoInfo.location);
660661
std::filesystem::path cacheDir = getCachePath(repoUrl.to_string(), shallow);
661662
repoDir = cacheDir;
662663
repoInfo.gitDir = ".";
663664

665+
/* If shallow = false, but we have a non-shallow repo that already contains the desired rev, then use that
666+
* repo instead. */
667+
std::filesystem::path cacheDirNonShallow = getCachePath(repoUrl.to_string(), false);
668+
if (rev && shallow && pathExists(cacheDirNonShallow)) {
669+
auto nonShallowRepo = GitRepo::openRepo(cacheDirNonShallow, true, true);
670+
if (nonShallowRepo->hasObject(*rev)) {
671+
debug(
672+
"using non-shallow cached repo for '%s' since it contains rev '%s'",
673+
repoUrl.to_string(),
674+
rev->gitRev());
675+
repoDir = cacheDirNonShallow;
676+
goto have_rev;
677+
}
678+
}
679+
664680
std::filesystem::create_directories(cacheDir.parent_path());
665681
PathLocks cacheDirLock({cacheDir.string()});
666682

@@ -676,7 +692,7 @@ struct GitInputScheme : InputScheme
676692

677693
/* If a rev was specified, we need to fetch if it's not in the
678694
repo. */
679-
if (auto rev = input.getRev()) {
695+
if (rev) {
680696
doFetch = !repo->hasObject(*rev);
681697
} else {
682698
if (getAllRefsAttr(input)) {
@@ -717,7 +733,7 @@ struct GitInputScheme : InputScheme
717733
warn("could not update cached head '%s' for '%s'", ref, repoInfo.locationToArg());
718734
}
719735

720-
if (auto rev = input.getRev()) {
736+
if (rev) {
721737
if (!repo->hasObject(*rev))
722738
throw Error(
723739
"Cannot find Git revision '%s' in ref '%s' of repository '%s'! "
@@ -734,6 +750,7 @@ struct GitInputScheme : InputScheme
734750
// the remainder
735751
}
736752

753+
have_rev:
737754
auto repo = GitRepo::openRepo(repoDir);
738755

739756
// FIXME: check whether rev is an ancestor of ref?

0 commit comments

Comments
 (0)