Merge pull request #3102 from libgit2/cmn/pack-objects-report Show progress during packing for the local transport
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
diff --git a/examples/network/clone.c b/examples/network/clone.c
index 37e373d..b2d80ed 100644
--- a/examples/network/clone.c
+++ b/examples/network/clone.c
@@ -46,6 +46,13 @@ static void print_progress(const progress_data *pd)
}
}
+static int sideband_progress(const char *str, int len, void *payload)
+{
+ printf("remote: %*s", len, str);
+ fflush(stdout);
+ return 0;
+}
+
static int fetch_progress(const git_transfer_progress *stats, void *payload)
{
progress_data *pd = (progress_data*)payload;
@@ -86,6 +93,7 @@ int do_clone(git_repository *repo, int argc, char **argv)
checkout_opts.progress_cb = checkout_progress;
checkout_opts.progress_payload = &pd;
clone_opts.checkout_opts = checkout_opts;
+ clone_opts.fetch_opts.callbacks.sideband_progress = sideband_progress;
clone_opts.fetch_opts.callbacks.transfer_progress = &fetch_progress;
clone_opts.fetch_opts.callbacks.credentials = cred_acquire_cb;
clone_opts.fetch_opts.callbacks.payload = &pd;
diff --git a/src/pack-objects.c b/src/pack-objects.c
index 9327646..e287e33 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -893,6 +893,29 @@ static unsigned long free_unpacked(struct unpacked *n)
return freed_mem;
}
+static int report_delta_progress(git_packbuilder *pb, uint32_t count, bool force)
+{
+ int ret;
+
+ if (pb->progress_cb) {
+ double current_time = git__timer();
+ double elapsed = current_time - pb->last_progress_report_time;
+
+ if (force || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
+ pb->last_progress_report_time = current_time;
+
+ ret = pb->progress_cb(
+ GIT_PACKBUILDER_DELTAFICATION,
+ count, pb->nr_objects, pb->progress_cb_payload);
+
+ if (ret)
+ return giterr_set_after_callback(ret);
+ }
+ }
+
+ return 0;
+}
+
static int find_deltas(git_packbuilder *pb, git_pobject **list,
unsigned int *list_size, unsigned int window,
int depth)
@@ -918,6 +941,9 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
break;
}
+ pb->nr_deltified += 1;
+ report_delta_progress(pb, pb->nr_deltified, false);
+
po = *list++;
(*list_size)--;
git_packbuilder__progress_unlock(pb);
@@ -1290,6 +1316,8 @@ static int prepare_pack(git_packbuilder *pb)
}
}
+ report_delta_progress(pb, pb->nr_objects, true);
+
pb->done = true;
git__free(delta_list);
return 0;
diff --git a/src/pack-objects.h b/src/pack-objects.h
index 9af5c0b..82dea81 100644
--- a/src/pack-objects.h
+++ b/src/pack-objects.h
@@ -65,6 +65,7 @@ struct git_packbuilder {
git_zstream zstream;
uint32_t nr_objects,
+ nr_deltified,
nr_alloc,
nr_written,
nr_remaining;
diff --git a/src/transports/local.c b/src/transports/local.c
index 305c71b..9dd4486 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -502,6 +502,33 @@ static int foreach_cb(void *buf, size_t len, void *payload)
}
static const char *counting_objects_fmt = "Counting objects %d\r";
+static const char *compressing_objects_fmt = "Compressing objects: %.0f%% (%d/%d)";
+
+static int local_counting(int stage, unsigned int current, unsigned int total, void *payload)
+{
+ git_buf progress_info = GIT_BUF_INIT;
+ transport_local *t = payload;
+
+ if (!t->progress_cb)
+ return 0;
+
+ if (stage == GIT_PACKBUILDER_ADDING_OBJECTS) {
+ git_buf_printf(&progress_info, counting_objects_fmt, current);
+ } else if (stage == GIT_PACKBUILDER_DELTAFICATION) {
+ float perc = (((float) current) / total) * 100;
+ git_buf_printf(&progress_info, compressing_objects_fmt, perc, current, total);
+ if (current == total)
+ git_buf_printf(&progress_info, ", done\n");
+ else
+ git_buf_putc(&progress_info, '\r');
+
+ }
+
+ if (git_buf_oom(&progress_info))
+ return -1;
+
+ return t->progress_cb(git_buf_cstr(&progress_info), git_buf_len(&progress_info), t->message_cb_payload);
+}
static int local_download_pack(
git_transport *transport,
@@ -527,6 +554,8 @@ static int local_download_pack(
if ((error = git_packbuilder_new(&pack, t->repo)) < 0)
goto cleanup;
+ git_packbuilder_set_callbacks(pack, local_counting, t);
+
stats->total_objects = 0;
stats->indexed_objects = 0;
stats->received_objects = 0;