@@ -647,6 +647,30 @@ struct GitInputScheme : InputScheme
647647 return options.makeFingerprint (rev) + (getSubmodulesAttr (input) ? " ;s" : " " );
648648 }
649649
650+ /* *
651+ * Get a `SourceAccessor` for the given Git revision by creating a git archive and unpacking it to the Nix store.
652+ * This is used for Nix < 2.20 compatibility.
653+ */
654+ ref<SourceAccessor> getGitArchiveAccessor (
655+ Store & store, RepoInfo & repoInfo, const std::filesystem::path & repoDir, const Hash & rev) const
656+ {
657+ auto tmpDir = createTempDir ();
658+ AutoDelete delTmpDir (tmpDir, true );
659+
660+ auto source = sinkToSource ([&](Sink & sink) {
661+ runProgram2 (
662+ {.program = " git" ,
663+ .args = {" -C" , repoDir, " --git-dir" , repoInfo.gitDir , " archive" , rev.gitRev ()},
664+ .standardOut = &sink});
665+ });
666+
667+ unpackTarfile (*source, tmpDir);
668+
669+ auto storePath = store.addToStore (" source" , {getFSSourceAccessor (), CanonPath (tmpDir)});
670+
671+ return ref{store.getFSAccessor (storePath)};
672+ }
673+
650674 std::pair<ref<SourceAccessor>, Input>
651675 getAccessorFromCommit (const Settings & settings, ref<Store> store, RepoInfo & repoInfo, Input && input) const
652676 {
@@ -804,7 +828,8 @@ struct GitInputScheme : InputScheme
804828 fetchToStore2 (settings, *store, {accessor}, FetchMode::DryRun, input.getName ()).second ;
805829 if (expectedNarHash != narHashNew) {
806830 GitAccessorOptions options2{.exportIgnore = true , .applyFilters = true };
807- auto accessor2 = repo->getAccessor (rev, options2, " «" + input.to_string (true ) + " »" );
831+ auto accessor2 = getGitArchiveAccessor (*store, repoInfo, repoDir, rev);
832+ accessor2->fingerprint = options2.makeFingerprint (rev);
808833 auto narHashOld =
809834 fetchToStore2 (settings, *store, {accessor2}, FetchMode::DryRun, input.getName ()).second ;
810835 if (expectedNarHash == narHashOld) {
0 commit comments