|
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
|
|
0 commit comments