From 2c8bbb27d91ec35162522079d632608fcaac2a57 Mon Sep 17 00:00:00 2001 From: Ben Straub Date: Tue, 16 Oct 2012 20:16:21 -0700 Subject: [PATCH] Convert checkout_index to use progress callback --- include/git2/checkout.h | 11 +++++--- src/checkout.c | 24 +++++++---------- src/clone.c | 9 ++----- src/reset.c | 2 +- tests-clar/checkout/index.c | 51 ++++++++++++++++++++++++------------- 5 files changed, 54 insertions(+), 43 deletions(-) diff --git a/include/git2/checkout.h b/include/git2/checkout.h index b4f9ad081..d0190c260 100644 --- a/include/git2/checkout.h +++ b/include/git2/checkout.h @@ -65,9 +65,15 @@ typedef struct git_checkout_opts { const git_oid *blob_oid, int file_mode, void *payload); - void *notify_payload; + /* Optional callback to notify the consumer of checkout progress. */ + void (* progress_cb)( + const char *path, + float progress, + void *payload); + void *progress_payload; + /** When not NULL, array of fnmatch patterns specifying * which paths should be taken into account */ @@ -101,8 +107,7 @@ GIT_EXTERN(int) git_checkout_head( */ GIT_EXTERN(int) git_checkout_index( git_repository *repo, - git_checkout_opts *opts, - git_indexer_stats *stats); + git_checkout_opts *opts); /** * Updates files in the index and working tree to match the content of the diff --git a/src/checkout.c b/src/checkout.c index b56b459d2..222eb26df 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -27,7 +27,7 @@ struct checkout_diff_data git_buf *path; size_t workdir_len; git_checkout_opts *checkout_opts; - git_indexer_stats *stats; + /*git_indexer_stats *stats;*/ git_repository *owner; bool can_symlink; bool found_submodules; @@ -204,6 +204,12 @@ 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); + return data->error; } @@ -304,11 +310,9 @@ static void normalize_options(git_checkout_opts *normalized, git_checkout_opts * int git_checkout_index( git_repository *repo, - git_checkout_opts *opts, - git_indexer_stats *stats) + git_checkout_opts *opts) { git_diff_list *diff = NULL; - git_indexer_stats dummy_stats; git_diff_options diff_opts = {0}; git_checkout_opts checkout_opts; @@ -339,19 +343,11 @@ int git_checkout_index( normalize_options(&checkout_opts, opts); - if (!stats) - stats = &dummy_stats; - - stats->processed = 0; - /* total based on 3 passes, but it might be 2 if no submodules */ - stats->total = (unsigned int)git_diff_num_deltas(diff) * 3; - memset(&data, 0, sizeof(data)); data.path = &workdir; data.workdir_len = git_buf_len(&workdir); data.checkout_opts = &checkout_opts; - data.stats = stats; data.owner = repo; if ((error = retrieve_symlink_capabilities(repo, &data.can_symlink)) < 0) @@ -378,8 +374,6 @@ int git_checkout_index( diff, &data, checkout_create_the_new, NULL, NULL); } - stats->processed = stats->total; - cleanup: if (error == GIT_EUSER) error = (data.error != 0) ? data.error : -1; @@ -417,7 +411,7 @@ int git_checkout_tree( if ((error = git_index_write(index)) < 0) goto cleanup; - error = git_checkout_index(repo, opts, stats); + error = git_checkout_index(repo, opts); cleanup: git_index_free(index); diff --git a/src/clone.c b/src/clone.c index 215185610..0039b146d 100644 --- a/src/clone.c +++ b/src/clone.c @@ -248,16 +248,11 @@ cleanup: -static int setup_remotes_and_fetch(git_repository *repo, - const char *origin_url, - git_indexer_stats *fetch_stats) +static int setup_remotes_and_fetch(git_repository *repo, const char *origin_url) { int retcode = GIT_ERROR; git_remote *origin = NULL; git_off_t bytes = 0; - git_indexer_stats dummy_stats; - - if (!fetch_stats) fetch_stats = &dummy_stats; /* Create the "origin" remote */ if (!git_remote_add(&origin, repo, GIT_REMOTE_ORIGIN, origin_url)) { @@ -327,7 +322,7 @@ static int clone_internal( } if (!(retcode = git_repository_init(&repo, path, is_bare))) { - if ((retcode = setup_remotes_and_fetch(repo, origin_url, fetch_stats)) < 0) { + if ((retcode = setup_remotes_and_fetch(repo, origin_url)) < 0) { /* Failed to fetch; clean up */ git_repository_free(repo); git_futils_rmdir_r(path, NULL, GIT_DIRREMOVAL_FILES_AND_DIRS); diff --git a/src/reset.c b/src/reset.c index dfa095be4..3fcad7f46 100644 --- a/src/reset.c +++ b/src/reset.c @@ -94,7 +94,7 @@ int git_reset( | GIT_CHECKOUT_OVERWRITE_MODIFIED | GIT_CHECKOUT_REMOVE_UNTRACKED; - if (git_checkout_index(repo, &opts, NULL) < 0) { + if (git_checkout_index(repo, &opts) < 0) { giterr_set(GITERR_INDEX, "%s - Failed to checkout the index.", ERROR_MSG); goto cleanup; } diff --git a/tests-clar/checkout/index.c b/tests-clar/checkout/index.c index f017a0fe2..944d679f8 100644 --- a/tests-clar/checkout/index.c +++ b/tests-clar/checkout/index.c @@ -69,7 +69,7 @@ void test_checkout_index__cannot_checkout_a_bare_repository(void) memset(&g_opts, 0, sizeof(g_opts)); g_repo = cl_git_sandbox_init("testrepo.git"); - cl_git_fail(git_checkout_index(g_repo, NULL, NULL)); + cl_git_fail(git_checkout_index(g_repo, NULL)); } void test_checkout_index__can_create_missing_files(void) @@ -79,7 +79,7 @@ void test_checkout_index__can_create_missing_files(void) cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt")); g_opts.checkout_strategy = GIT_CHECKOUT_CREATE_MISSING; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); test_file_contents("./testrepo/README", "hey there\n"); test_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n"); @@ -95,7 +95,7 @@ void test_checkout_index__can_remove_untracked_files(void) cl_assert_equal_i(true, git_path_isdir("./testrepo/dir/subdir/subsubdir")); g_opts.checkout_strategy = GIT_CHECKOUT_REMOVE_UNTRACKED; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); cl_assert_equal_i(false, git_path_isdir("./testrepo/dir")); } @@ -111,7 +111,7 @@ void test_checkout_index__honor_the_specified_pathspecs(void) cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt")); cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt")); - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); test_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n"); @@ -142,7 +142,7 @@ void test_checkout_index__honor_the_gitattributes_directives(void) cl_git_mkfile("./testrepo/.gitattributes", attributes); set_core_autocrlf_to(false); - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); test_file_contents("./testrepo/README", "hey there\n"); test_file_contents("./testrepo/new.txt", "my new file\n"); @@ -157,7 +157,7 @@ void test_checkout_index__honor_coreautocrlf_setting_set_to_true(void) cl_git_pass(p_unlink("./testrepo/.gitattributes")); set_core_autocrlf_to(true); - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); test_file_contents("./testrepo/README", expected_readme_text); #endif @@ -172,7 +172,7 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_true(void) { set_repo_symlink_handling_cap_to(true); - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); #ifdef GIT_WIN32 test_file_contents("./testrepo/link_to_new.txt", "new.txt"); @@ -194,7 +194,7 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_false(void) { set_repo_symlink_handling_cap_to(false); - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); test_file_contents("./testrepo/link_to_new.txt", "new.txt"); } @@ -204,7 +204,7 @@ void test_checkout_index__donot_overwrite_modified_file_by_default(void) cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!"); g_opts.checkout_strategy = 0; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); test_file_contents("./testrepo/new.txt", "This isn't what's stored!"); } @@ -214,7 +214,7 @@ void test_checkout_index__can_overwrite_modified_file(void) cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!"); g_opts.checkout_strategy = GIT_CHECKOUT_OVERWRITE_MODIFIED; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); test_file_contents("./testrepo/new.txt", "my new file\n"); } @@ -224,14 +224,14 @@ void test_checkout_index__options_disable_filters(void) cl_git_mkfile("./testrepo/.gitattributes", "*.txt text eol=crlf\n"); g_opts.disable_filters = false; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); test_file_contents("./testrepo/new.txt", "my new file\r\n"); p_unlink("./testrepo/new.txt"); g_opts.disable_filters = true; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); test_file_contents("./testrepo/new.txt", "my new file\n"); } @@ -249,7 +249,7 @@ void test_checkout_index__options_dir_modes(void) reset_index_to_treeish((git_object *)commit); g_opts.dir_mode = 0701; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); cl_git_pass(p_stat("./testrepo/a", &st)); cl_assert_equal_i(st.st_mode & 0777, 0701); @@ -269,7 +269,7 @@ void test_checkout_index__options_override_file_modes(void) g_opts.file_mode = 0700; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); cl_git_pass(p_stat("./testrepo/new.txt", &st)); cl_assert_equal_i(st.st_mode & 0777, 0700); @@ -283,7 +283,7 @@ void test_checkout_index__options_open_flags(void) g_opts.file_open_flags = O_CREAT | O_RDWR | O_APPEND; g_opts.checkout_strategy |= GIT_CHECKOUT_OVERWRITE_MODIFIED; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); test_file_contents("./testrepo/new.txt", "hi\nmy new file\n"); } @@ -328,7 +328,7 @@ void test_checkout_index__can_notify_of_skipped_files(void) g_opts.skipped_notify_cb = notify_cb; g_opts.notify_payload = &data; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); } static int dont_notify_cb( @@ -358,5 +358,22 @@ void test_checkout_index__wont_notify_of_expected_line_ending_changes(void) g_opts.skipped_notify_cb = dont_notify_cb; g_opts.notify_payload = NULL; - cl_git_pass(git_checkout_index(g_repo, &g_opts, NULL)); + cl_git_pass(git_checkout_index(g_repo, &g_opts)); +} + +static void progress(const char *path, float progress, void *payload) +{ + GIT_UNUSED(path); GIT_UNUSED(progress); + int *count = (int*)payload; + (*count)++; +} + +void test_checkout_index__calls_progress_callback(void) +{ + int count = 0; + g_opts.progress_cb = progress; + g_opts.progress_payload = &count; + + cl_git_pass(git_checkout_index(g_repo, &g_opts)); + cl_assert_equal_i(count, 5); }