Commit 9c05c17b7ac7caf7691a9056994bda735ea31c81

Ben Straub 2012-10-19T20:05:18

Checkout progress now reports completed/total steps

diff --git a/examples/network/clone.c b/examples/network/clone.c
index 5ad9330..19bf0cc 100644
--- a/examples/network/clone.c
+++ b/examples/network/clone.c
@@ -9,7 +9,8 @@
 
 typedef struct progress_data {
 	git_indexer_stats fetch_progress;
-	float checkout_progress;
+	size_t completed_steps;
+	size_t total_steps;
 	const char *path;
 } progress_data;
 
@@ -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 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;
 	printf("net %3d%% (%6d kb)  /  idx %3d%%  /  chk %3d%%  %50s\n",
 			network_percent, kbytes, index_percent, checkout_percent, pd->path);
@@ -35,10 +38,11 @@ static void fetch_progress(const git_indexer_stats *stats, void *payload)
 	pd->fetch_progress = *stats;
 	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;
-	pd->checkout_progress = progress;
+	pd->completed_steps = cur;
+	pd->total_steps = tot;
 	pd->path = path;
 	print_progress(pd);
 }
diff --git a/include/git2/checkout.h b/include/git2/checkout.h
index 9032c6b..390d2f2 100644
--- a/include/git2/checkout.h
+++ b/include/git2/checkout.h
@@ -70,7 +70,8 @@ typedef struct git_checkout_opts {
 	/* Optional callback to notify the consumer of checkout progress. */
 	void (* progress_cb)(
 			const char *path,
-			float progress,
+			size_t completed_steps,
+			size_t total_steps,
 			void *payload);
 	void *progress_payload;
 
diff --git a/src/checkout.c b/src/checkout.c
index 35e3d29..8ab3da8 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -32,6 +32,8 @@ struct checkout_diff_data
 	bool found_submodules;
 	bool create_submodules;
 	int error;
+	size_t total_steps;
+	size_t completed_steps;
 };
 
 static int buffer_to_file(
@@ -158,26 +160,20 @@ static int checkout_submodule(
 }
 
 static void report_progress(
-		int stage,
-		float stage_progress,
 		struct checkout_diff_data *data,
 		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)
 		data->checkout_opts->progress_cb(
 				path,
-				overall_progress,
+				data->completed_steps,
+				data->total_steps,
 				data->checkout_opts->progress_payload);
 }
 
 static int checkout_blob(
 	struct checkout_diff_data *data,
-	const git_diff_file *file,
-	float progress)
+	const git_diff_file *file)
 {
 	git_blob *blob;
 	int error;
@@ -196,7 +192,7 @@ static int checkout_blob(
 		error = blob_content_to_file(
 			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);
 
 	return error;
@@ -220,7 +216,8 @@ static int checkout_remove_the_old(
 			git_repository_workdir(data->owner),
 			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;
@@ -266,11 +263,13 @@ static int checkout_create_the_new(
 		}
 
 		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) {
 			error = checkout_submodule(data, &delta->old_file);
+			data->completed_steps++;
 		}
 
 	}
@@ -365,6 +364,7 @@ int git_checkout_index(
 	data.workdir_len = git_buf_len(&workdir);
 	data.checkout_opts = &checkout_opts;
 	data.owner = repo;
+	data.total_steps = (size_t)git_diff_num_deltas(diff);
 
 	if ((error = retrieve_symlink_capabilities(repo, &data.can_symlink)) < 0)
 		goto cleanup;
@@ -379,7 +379,7 @@ int git_checkout_index(
 	 *    checked out during pass #2.
 	 */
 
-	report_progress(1, 0.f, &data, NULL);
+	report_progress(&data, NULL);
 
 	if (!(error = git_diff_foreach(
 			diff, &data, checkout_remove_the_old, NULL, NULL)) &&
@@ -392,7 +392,7 @@ int git_checkout_index(
 			diff, &data, checkout_create_the_new, NULL, NULL);
 	}
 
-	report_progress(2, 1.f, &data, NULL);
+	report_progress(&data, NULL);
 
 cleanup:
 	if (error == GIT_EUSER)
diff --git a/tests-clar/checkout/index.c b/tests-clar/checkout/index.c
index eac8515..58b3c7e 100644
--- a/tests-clar/checkout/index.c
+++ b/tests-clar/checkout/index.c
@@ -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));
 }
 
-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;
 	*was_called = true;
 }
diff --git a/tests-clar/checkout/tree.c b/tests-clar/checkout/tree.c
index 88d3b34..598ea9f 100644
--- a/tests-clar/checkout/tree.c
+++ b/tests-clar/checkout/tree.c
@@ -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"));
 }
 
-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;
 	*was_called = true;
 }
diff --git a/tests-clar/clone/network.c b/tests-clar/clone/network.c
index 62d4110..3d78d43 100644
--- a/tests-clar/clone/network.c
+++ b/tests-clar/clone/network.c
@@ -91,9 +91,9 @@ void test_clone_network__can_prevent_the_checkout_of_a_standard_repo(void)
 	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;
 	(*was_called) = true;
 }