Correct progress reporting from checkout
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
diff --git a/examples/network/clone.c b/examples/network/clone.c
index 39b3241..fd30bca 100644
--- a/examples/network/clone.c
+++ b/examples/network/clone.c
@@ -15,17 +15,17 @@ typedef struct progress_data {
static void print_progress(const progress_data *pd)
{
- /*
int network_percent = (100*pd->fetch_progress.received) / pd->fetch_progress.total;
int index_percent = (100*pd->fetch_progress.processed) / pd->fetch_progress.total;
int checkout_percent = (int)(100.f * pd->checkout_progress);
- printf("net %3d%% / idx %3d%% / chk %3d%% %20s\r",
+ printf("net %3d%% / idx %3d%% / chk %3d%% %50s\r",
network_percent, index_percent, checkout_percent, pd->path);
- */
+ /*
printf("net %5d /%5d – idx %5d /%5d – chk %.04f %20s\r",
pd->fetch_progress.received, pd->fetch_progress.total,
pd->fetch_progress.processed, pd->fetch_progress.total,
pd->checkout_progress, pd->path);
+ */
}
static void fetch_progress(const git_indexer_stats *stats, void *payload)
diff --git a/src/checkout.c b/src/checkout.c
index d9b3246..a20a6f9 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -31,6 +31,7 @@ struct checkout_diff_data
bool can_symlink;
bool found_submodules;
bool create_submodules;
+ int num_stages;
int error;
};
@@ -157,6 +158,23 @@ static int checkout_submodule(
return 0;
}
+static void report_progress(
+ int stage,
+ float stage_progress,
+ struct checkout_diff_data *data,
+ const char *path)
+{
+ float per_stage_progress = 1.f/data->num_stages;
+ float overall_progress = (stage-1)*per_stage_progress +
+ stage_progress*per_stage_progress;
+
+ if (data->checkout_opts->progress_cb)
+ data->checkout_opts->progress_cb(
+ path,
+ overall_progress,
+ data->checkout_opts->progress_payload);
+}
+
static int checkout_blob(
struct checkout_diff_data *data,
const git_diff_file *file)
@@ -202,11 +220,7 @@ static int checkout_remove_the_old(
GIT_DIRREMOVAL_FILES_AND_DIRS);
}
- if (data->checkout_opts->progress_cb)
- data->checkout_opts->progress_cb(
- delta->new_file.path,
- progress,
- data->checkout_opts->progress_payload);
+ report_progress(1, progress, data, delta->new_file.path);
return data->error;
}
@@ -246,14 +260,22 @@ static int checkout_create_the_new(
if (do_checkout) {
bool is_submodule = S_ISGITLINK(delta->old_file.mode);
- if (is_submodule)
+ if (is_submodule) {
data->found_submodules = true;
+ data->num_stages = 3;
+ }
- if (!is_submodule && !data->create_submodules)
+ if (!is_submodule && !data->create_submodules) {
error = checkout_blob(data, &delta->old_file);
+ report_progress(2, progress, data, delta->old_file.path);
+
+ }
- else if (is_submodule && data->create_submodules)
+ else if (is_submodule && data->create_submodules) {
error = checkout_submodule(data, &delta->old_file);
+ report_progress(3, progress, data, delta->old_file.path);
+ }
+
}
if (error)
@@ -346,6 +368,7 @@ int git_checkout_index(
data.workdir_len = git_buf_len(&workdir);
data.checkout_opts = &checkout_opts;
data.owner = repo;
+ data.num_stages = 2;
if ((error = retrieve_symlink_capabilities(repo, &data.can_symlink)) < 0)
goto cleanup;
@@ -360,6 +383,8 @@ int git_checkout_index(
* checked out during pass #2.
*/
+ report_progress(1, 0.f, &data, NULL);
+
if (!(error = git_diff_foreach(
diff, &data, checkout_remove_the_old, NULL, NULL)) &&
!(error = git_diff_foreach(
@@ -371,6 +396,8 @@ int git_checkout_index(
diff, &data, checkout_create_the_new, NULL, NULL);
}
+ report_progress(data.num_stages, 1.f, &data, NULL);
+
cleanup:
if (error == GIT_EUSER)
error = (data.error != 0) ? data.error : -1;