|
10 | 10 | #include "nix/util/sync.hh" |
11 | 11 | #include "nix/util/thread-pool.hh" |
12 | 12 | #include "nix/util/pool.hh" |
| 13 | +#include "nix/util/executable-path.hh" |
13 | 14 |
|
14 | 15 | #include <git2/attr.h> |
15 | 16 | #include <git2/blob.h> |
@@ -549,21 +550,44 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl> |
549 | 550 | // that) |
550 | 551 | // then use code that was removed in this commit (see blame) |
551 | 552 |
|
552 | | - auto dir = this->path; |
553 | | - Strings gitArgs{"-C", dir.string(), "--git-dir", ".", "fetch", "--quiet", "--force"}; |
554 | | - if (shallow) |
555 | | - append(gitArgs, {"--depth", "1"}); |
556 | | - append(gitArgs, {std::string("--"), url, refspec}); |
557 | | - |
558 | | - runProgram( |
559 | | - RunOptions{ |
560 | | - .program = "git", |
561 | | - .lookupPath = true, |
562 | | - // FIXME: git stderr messes up our progress indicator, so |
563 | | - // we're using --quiet for now. Should process its stderr. |
564 | | - .args = gitArgs, |
565 | | - .input = {}, |
566 | | - .isInteractive = true}); |
| 553 | + if (ExecutablePath::load().findName("git")) { |
| 554 | + auto dir = this->path; |
| 555 | + Strings gitArgs{"-C", dir.string(), "--git-dir", ".", "fetch", "--quiet", "--force"}; |
| 556 | + if (shallow) |
| 557 | + append(gitArgs, {"--depth", "1"}); |
| 558 | + append(gitArgs, {std::string("--"), url, refspec}); |
| 559 | + |
| 560 | + runProgram( |
| 561 | + RunOptions{ |
| 562 | + .program = "git", |
| 563 | + .lookupPath = true, |
| 564 | + // FIXME: git stderr messes up our progress indicator, so |
| 565 | + // we're using --quiet for now. Should process its stderr. |
| 566 | + .args = gitArgs, |
| 567 | + .input = {}, |
| 568 | + .isInteractive = true}); |
| 569 | + } else { |
| 570 | + // Fall back to using libgit2 for fetching. This does not |
| 571 | + // support SSH very well. |
| 572 | + Remote remote; |
| 573 | + |
| 574 | + if (git_remote_create_anonymous(Setter(remote), *this, url.c_str())) |
| 575 | + throw Error("cannot create Git remote '%s': %s", url, git_error_last()->message); |
| 576 | + |
| 577 | + char * refspecs[] = {(char *) refspec.c_str()}; |
| 578 | + git_strarray refspecs2{.strings = refspecs, .count = 1}; |
| 579 | + |
| 580 | + git_fetch_options opts = GIT_FETCH_OPTIONS_INIT; |
| 581 | + // FIXME: for some reason, shallow fetching over ssh barfs |
| 582 | + // with "could not read from remote repository". |
| 583 | + opts.depth = shallow && parseURL(url).scheme != "ssh" ? 1 : GIT_FETCH_DEPTH_FULL; |
| 584 | + opts.callbacks.payload = &act; |
| 585 | + opts.callbacks.sideband_progress = sidebandProgressCallback; |
| 586 | + opts.callbacks.transfer_progress = transferProgressCallback; |
| 587 | + |
| 588 | + if (git_remote_fetch(remote.get(), &refspecs2, &opts, nullptr)) |
| 589 | + throw Error("fetching '%s' from '%s': %s", refspec, url, git_error_last()->message); |
| 590 | + } |
567 | 591 | } |
568 | 592 |
|
569 | 593 | void verifyCommit(const Hash & rev, const std::vector<fetchers::PublicKey> & publicKeys) override |
@@ -1312,13 +1336,18 @@ std::vector<std::tuple<GitRepoImpl::Submodule, Hash>> GitRepoImpl::getSubmodules |
1312 | 1336 | return result; |
1313 | 1337 | } |
1314 | 1338 |
|
1315 | | -ref<GitRepo> getTarballCache() |
1316 | | -{ |
1317 | | - static auto repoDir = std::filesystem::path(getCacheDir()) / "tarball-cache"; |
| 1339 | +namespace fetchers { |
1318 | 1340 |
|
1319 | | - return GitRepo::openRepo(repoDir, true, true); |
| 1341 | +ref<GitRepo> Settings::getTarballCache() const |
| 1342 | +{ |
| 1343 | + auto tarballCache(_tarballCache.lock()); |
| 1344 | + if (!*tarballCache) |
| 1345 | + *tarballCache = GitRepo::openRepo(std::filesystem::path(getCacheDir()) / "tarball-cache", true, true); |
| 1346 | + return ref<GitRepo>(*tarballCache); |
1320 | 1347 | } |
1321 | 1348 |
|
| 1349 | +} // namespace fetchers |
| 1350 | + |
1322 | 1351 | GitRepo::WorkdirInfo GitRepo::getCachedWorkdirInfo(const std::filesystem::path & path) |
1323 | 1352 | { |
1324 | 1353 | static Sync<std::map<std::filesystem::path, WorkdirInfo>> _cache; |
|
0 commit comments