Commit 9c05c17b by Ben Straub

Checkout progress now reports completed/total steps

parent cd001bbb
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
typedef struct progress_data { typedef struct progress_data {
git_indexer_stats fetch_progress; git_indexer_stats fetch_progress;
float checkout_progress; size_t completed_steps;
size_t total_steps;
const char *path; const char *path;
} progress_data; } progress_data;
...@@ -17,7 +18,9 @@ static void print_progress(const progress_data *pd) ...@@ -17,7 +18,9 @@ static void print_progress(const progress_data *pd)
{ {
int network_percent = (100*pd->fetch_progress.received) / pd->fetch_progress.total; 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 index_percent = (100*pd->fetch_progress.processed) / pd->fetch_progress.total;
int checkout_percent = (int)(100.f * pd->checkout_progress); int checkout_percent = pd->total_steps > 0
? (100.f * pd->completed_steps) / pd->total_steps
: 0.f;
int kbytes = pd->fetch_progress.bytes / 1024; int kbytes = pd->fetch_progress.bytes / 1024;
printf("net %3d%% (%6d kb) / idx %3d%% / chk %3d%% %50s\n", printf("net %3d%% (%6d kb) / idx %3d%% / chk %3d%% %50s\n",
network_percent, kbytes, index_percent, checkout_percent, pd->path); network_percent, kbytes, index_percent, checkout_percent, pd->path);
...@@ -35,10 +38,11 @@ static void fetch_progress(const git_indexer_stats *stats, void *payload) ...@@ -35,10 +38,11 @@ static void fetch_progress(const git_indexer_stats *stats, void *payload)
pd->fetch_progress = *stats; pd->fetch_progress = *stats;
print_progress(pd); print_progress(pd);
} }
static void checkout_progress(const char *path, float progress, void *payload) static void checkout_progress(const char *path, size_t cur, size_t tot, void *payload)
{ {
progress_data *pd = (progress_data*)payload; progress_data *pd = (progress_data*)payload;
pd->checkout_progress = progress; pd->completed_steps = cur;
pd->total_steps = tot;
pd->path = path; pd->path = path;
print_progress(pd); print_progress(pd);
} }
......
...@@ -70,7 +70,8 @@ typedef struct git_checkout_opts { ...@@ -70,7 +70,8 @@ typedef struct git_checkout_opts {
/* Optional callback to notify the consumer of checkout progress. */ /* Optional callback to notify the consumer of checkout progress. */
void (* progress_cb)( void (* progress_cb)(
const char *path, const char *path,
float progress, size_t completed_steps,
size_t total_steps,
void *payload); void *payload);
void *progress_payload; void *progress_payload;
......
...@@ -32,6 +32,8 @@ struct checkout_diff_data ...@@ -32,6 +32,8 @@ struct checkout_diff_data
bool found_submodules; bool found_submodules;
bool create_submodules; bool create_submodules;
int error; int error;
size_t total_steps;
size_t completed_steps;
}; };
static int buffer_to_file( static int buffer_to_file(
...@@ -158,26 +160,20 @@ static int checkout_submodule( ...@@ -158,26 +160,20 @@ static int checkout_submodule(
} }
static void report_progress( static void report_progress(
int stage,
float stage_progress,
struct checkout_diff_data *data, struct checkout_diff_data *data,
const char *path) const char *path)
{ {
float per_stage_progress = 0.5;
float overall_progress = (stage-1)*per_stage_progress +
stage_progress*per_stage_progress;
if (data->checkout_opts->progress_cb) if (data->checkout_opts->progress_cb)
data->checkout_opts->progress_cb( data->checkout_opts->progress_cb(
path, path,
overall_progress, data->completed_steps,
data->total_steps,
data->checkout_opts->progress_payload); data->checkout_opts->progress_payload);
} }
static int checkout_blob( static int checkout_blob(
struct checkout_diff_data *data, struct checkout_diff_data *data,
const git_diff_file *file, const git_diff_file *file)
float progress)
{ {
git_blob *blob; git_blob *blob;
int error; int error;
...@@ -196,7 +192,7 @@ static int checkout_blob( ...@@ -196,7 +192,7 @@ static int checkout_blob(
error = blob_content_to_file( error = blob_content_to_file(
blob, git_buf_cstr(data->path), file->mode, data->checkout_opts); blob, git_buf_cstr(data->path), file->mode, data->checkout_opts);
report_progress(2, progress, data, file->path); report_progress(data, file->path);
git_blob_free(blob); git_blob_free(blob);
return error; return error;
...@@ -220,7 +216,8 @@ static int checkout_remove_the_old( ...@@ -220,7 +216,8 @@ static int checkout_remove_the_old(
git_repository_workdir(data->owner), git_repository_workdir(data->owner),
GIT_DIRREMOVAL_FILES_AND_DIRS); GIT_DIRREMOVAL_FILES_AND_DIRS);
report_progress(1, progress, data, delta->new_file.path); data->completed_steps++;
report_progress(data, delta->new_file.path);
} }
return data->error; return data->error;
...@@ -266,11 +263,13 @@ static int checkout_create_the_new( ...@@ -266,11 +263,13 @@ static int checkout_create_the_new(
} }
if (!is_submodule && !data->create_submodules) { if (!is_submodule && !data->create_submodules) {
error = checkout_blob(data, &delta->old_file, progress); error = checkout_blob(data, &delta->old_file);
data->completed_steps++;
} }
else if (is_submodule && data->create_submodules) { else if (is_submodule && data->create_submodules) {
error = checkout_submodule(data, &delta->old_file); error = checkout_submodule(data, &delta->old_file);
data->completed_steps++;
} }
} }
...@@ -365,6 +364,7 @@ int git_checkout_index( ...@@ -365,6 +364,7 @@ int git_checkout_index(
data.workdir_len = git_buf_len(&workdir); data.workdir_len = git_buf_len(&workdir);
data.checkout_opts = &checkout_opts; data.checkout_opts = &checkout_opts;
data.owner = repo; data.owner = repo;
data.total_steps = (size_t)git_diff_num_deltas(diff);
if ((error = retrieve_symlink_capabilities(repo, &data.can_symlink)) < 0) if ((error = retrieve_symlink_capabilities(repo, &data.can_symlink)) < 0)
goto cleanup; goto cleanup;
...@@ -379,7 +379,7 @@ int git_checkout_index( ...@@ -379,7 +379,7 @@ int git_checkout_index(
* checked out during pass #2. * checked out during pass #2.
*/ */
report_progress(1, 0.f, &data, NULL); report_progress(&data, NULL);
if (!(error = git_diff_foreach( if (!(error = git_diff_foreach(
diff, &data, checkout_remove_the_old, NULL, NULL)) && diff, &data, checkout_remove_the_old, NULL, NULL)) &&
...@@ -392,7 +392,7 @@ int git_checkout_index( ...@@ -392,7 +392,7 @@ int git_checkout_index(
diff, &data, checkout_create_the_new, NULL, NULL); diff, &data, checkout_create_the_new, NULL, NULL);
} }
report_progress(2, 1.f, &data, NULL); report_progress(&data, NULL);
cleanup: cleanup:
if (error == GIT_EUSER) if (error == GIT_EUSER)
......
...@@ -361,9 +361,9 @@ void test_checkout_index__wont_notify_of_expected_line_ending_changes(void) ...@@ -361,9 +361,9 @@ void test_checkout_index__wont_notify_of_expected_line_ending_changes(void)
cl_git_pass(git_checkout_index(g_repo, &g_opts)); cl_git_pass(git_checkout_index(g_repo, &g_opts));
} }
static void progress(const char *path, float progress, void *payload) static void progress(const char *path, size_t cur, size_t tot, void *payload)
{ {
GIT_UNUSED(path); GIT_UNUSED(progress); GIT_UNUSED(path); GIT_UNUSED(cur); GIT_UNUSED(tot);
bool *was_called = (bool*)payload; bool *was_called = (bool*)payload;
*was_called = true; *was_called = true;
} }
......
...@@ -64,9 +64,9 @@ void test_checkout_tree__can_checkout_a_subdirectory_from_a_subtree(void) ...@@ -64,9 +64,9 @@ void test_checkout_tree__can_checkout_a_subdirectory_from_a_subtree(void)
cl_assert_equal_i(true, git_path_isfile("./testrepo/de/fgh/1.txt")); cl_assert_equal_i(true, git_path_isfile("./testrepo/de/fgh/1.txt"));
} }
static void progress(const char *path, float progress, void *payload) static void progress(const char *path, size_t cur, size_t tot, void *payload)
{ {
GIT_UNUSED(path); GIT_UNUSED(progress); GIT_UNUSED(path); GIT_UNUSED(cur); GIT_UNUSED(tot);
bool *was_called = (bool*)payload; bool *was_called = (bool*)payload;
*was_called = true; *was_called = true;
} }
......
...@@ -91,9 +91,9 @@ void test_clone_network__can_prevent_the_checkout_of_a_standard_repo(void) ...@@ -91,9 +91,9 @@ void test_clone_network__can_prevent_the_checkout_of_a_standard_repo(void)
git_buf_free(&path); git_buf_free(&path);
} }
static void checkout_progress(const char *path, float progress, void *payload) static void checkout_progress(const char *path, size_t cur, size_t tot, void *payload)
{ {
GIT_UNUSED(path); GIT_UNUSED(progress); GIT_UNUSED(path); GIT_UNUSED(cur); GIT_UNUSED(tot);
bool *was_called = (bool*)payload; bool *was_called = (bool*)payload;
(*was_called) = true; (*was_called) = true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment