Show Git fetch progress

This commit is contained in:
Eelco Dolstra 2023-11-15 13:57:20 +01:00
parent 2964a9f562
commit 2890999911
4 changed files with 39 additions and 3 deletions

View file

@ -3,6 +3,7 @@
#include "cache.hh" #include "cache.hh"
#include "finally.hh" #include "finally.hh"
#include "processes.hh" #include "processes.hh"
#include "signals.hh"
#include <boost/core/span.hpp> #include <boost/core/span.hpp>
@ -341,10 +342,32 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
ref<InputAccessor> getAccessor(const Hash & rev) override; ref<InputAccessor> 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( void fetch(
const std::string & url, const std::string & url,
const std::string & refspec) override const std::string & refspec) override
{ {
Activity act(*logger, lvlTalkative, actFetchTree, fmt("fetching Git repository '%s'", url));
Remote remote; Remote remote;
if (git_remote_create_anonymous(Setter(remote), *this, url.c_str())) if (git_remote_create_anonymous(Setter(remote), *this, url.c_str()))
@ -356,7 +379,12 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
.count = 1 .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); throw Error("fetching '%s' from '%s': %s", refspec, url, git_error_last()->message);
} }

View file

@ -520,8 +520,6 @@ struct GitInputScheme : InputScheme
} }
if (doFetch) { if (doFetch) {
Activity act(*logger, lvlTalkative, actUnknown, fmt("fetching Git repository '%s'", repoInfo.url));
try { try {
auto fetchRef = repoInfo.allRefs auto fetchRef = repoInfo.allRefs
? "refs/*" ? "refs/*"

View file

@ -340,6 +340,14 @@ public:
state->activitiesByType[type].expected += j; state->activitiesByType[type].expected += j;
update(*state); 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) void update(State & state)

View file

@ -23,6 +23,7 @@ typedef enum {
actQueryPathInfo = 109, actQueryPathInfo = 109,
actPostBuildHook = 110, actPostBuildHook = 110,
actBuildWaiting = 111, actBuildWaiting = 111,
actFetchTree = 112,
} ActivityType; } ActivityType;
typedef enum { typedef enum {
@ -34,6 +35,7 @@ typedef enum {
resProgress = 105, resProgress = 105,
resSetExpected = 106, resSetExpected = 106,
resPostBuildLogLine = 107, resPostBuildLogLine = 107,
resFetchStatus = 108,
} ResultType; } ResultType;
typedef uint64_t ActivityId; typedef uint64_t ActivityId;