From 28909999116781e194e2eb1646f3ccec005e774f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 15 Nov 2023 13:57:20 +0100 Subject: [PATCH] Show Git fetch progress --- src/libfetchers/git-utils.cc | 30 +++++++++++++++++++++++++++++- src/libfetchers/git.cc | 2 -- src/libmain/progress-bar.cc | 8 ++++++++ src/libutil/logging.hh | 2 ++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/libfetchers/git-utils.cc b/src/libfetchers/git-utils.cc index 1edafbf33..b7ef05c10 100644 --- a/src/libfetchers/git-utils.cc +++ b/src/libfetchers/git-utils.cc @@ -3,6 +3,7 @@ #include "cache.hh" #include "finally.hh" #include "processes.hh" +#include "signals.hh" #include @@ -341,10 +342,32 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this ref getAccessor(const Hash & rev) override; + static int sidebandProgressCallback(const char * str, int len, void * payload) + { + auto act = (Activity *) payload; + act->result(resFetchStatus, trim(std::string_view(str, len))); + return _isInterrupted ? -1 : 0; + } + + static int transferProgressCallback(const git_indexer_progress * stats, void * payload) + { + auto act = (Activity *) payload; + act->result(resFetchStatus, + fmt("%d/%d objects received, %d/%d deltas indexed, %.1f MiB", + stats->received_objects, + stats->total_objects, + stats->indexed_deltas, + stats->total_deltas, + stats->received_bytes / (1024.0 * 1024.0))); + return _isInterrupted ? -1 : 0; + } + void fetch( const std::string & url, const std::string & refspec) override { + Activity act(*logger, lvlTalkative, actFetchTree, fmt("fetching Git repository '%s'", url)); + Remote remote; if (git_remote_create_anonymous(Setter(remote), *this, url.c_str())) @@ -356,7 +379,12 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this .count = 1 }; - if (git_remote_fetch(remote.get(), &refspecs2, nullptr, nullptr)) + git_fetch_options opts = GIT_FETCH_OPTIONS_INIT; + opts.callbacks.payload = &act; + opts.callbacks.sideband_progress = sidebandProgressCallback; + opts.callbacks.transfer_progress = transferProgressCallback; + + if (git_remote_fetch(remote.get(), &refspecs2, &opts, nullptr)) throw Error("fetching '%s' from '%s': %s", refspec, url, git_error_last()->message); } diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index 177c8b66e..3e7dcd8de 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -520,8 +520,6 @@ struct GitInputScheme : InputScheme } if (doFetch) { - Activity act(*logger, lvlTalkative, actUnknown, fmt("fetching Git repository '%s'", repoInfo.url)); - try { auto fetchRef = repoInfo.allRefs ? "refs/*" diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc index a7aee47c3..3aa012ee1 100644 --- a/src/libmain/progress-bar.cc +++ b/src/libmain/progress-bar.cc @@ -340,6 +340,14 @@ public: state->activitiesByType[type].expected += j; update(*state); } + + else if (type == resFetchStatus) { + auto i = state->its.find(act); + assert(i != state->its.end()); + ActInfo & actInfo = *i->second; + actInfo.lastLine = getS(fields, 0); + update(*state); + } } void update(State & state) diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index 5aa6bee95..183f2d8e1 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -23,6 +23,7 @@ typedef enum { actQueryPathInfo = 109, actPostBuildHook = 110, actBuildWaiting = 111, + actFetchTree = 112, } ActivityType; typedef enum { @@ -34,6 +35,7 @@ typedef enum { resProgress = 105, resSetExpected = 106, resPostBuildLogLine = 107, + resFetchStatus = 108, } ResultType; typedef uint64_t ActivityId;