Commit 2c8bbb27 by Ben Straub

Convert checkout_index to use progress callback

parent d57c47dc
...@@ -65,9 +65,15 @@ typedef struct git_checkout_opts { ...@@ -65,9 +65,15 @@ typedef struct git_checkout_opts {
const git_oid *blob_oid, const git_oid *blob_oid,
int file_mode, int file_mode,
void *payload); void *payload);
void *notify_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 /** When not NULL, array of fnmatch patterns specifying
* which paths should be taken into account * which paths should be taken into account
*/ */
...@@ -101,8 +107,7 @@ GIT_EXTERN(int) git_checkout_head( ...@@ -101,8 +107,7 @@ GIT_EXTERN(int) git_checkout_head(
*/ */
GIT_EXTERN(int) git_checkout_index( GIT_EXTERN(int) git_checkout_index(
git_repository *repo, git_repository *repo,
git_checkout_opts *opts, git_checkout_opts *opts);
git_indexer_stats *stats);
/** /**
* Updates files in the index and working tree to match the content of the * Updates files in the index and working tree to match the content of the
......
...@@ -27,7 +27,7 @@ struct checkout_diff_data ...@@ -27,7 +27,7 @@ struct checkout_diff_data
git_buf *path; git_buf *path;
size_t workdir_len; size_t workdir_len;
git_checkout_opts *checkout_opts; git_checkout_opts *checkout_opts;
git_indexer_stats *stats; /*git_indexer_stats *stats;*/
git_repository *owner; git_repository *owner;
bool can_symlink; bool can_symlink;
bool found_submodules; bool found_submodules;
...@@ -204,6 +204,12 @@ static int checkout_remove_the_old( ...@@ -204,6 +204,12 @@ static int checkout_remove_the_old(
GIT_DIRREMOVAL_FILES_AND_DIRS); 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; return data->error;
} }
...@@ -304,11 +310,9 @@ static void normalize_options(git_checkout_opts *normalized, git_checkout_opts * ...@@ -304,11 +310,9 @@ static void normalize_options(git_checkout_opts *normalized, git_checkout_opts *
int git_checkout_index( int git_checkout_index(
git_repository *repo, git_repository *repo,
git_checkout_opts *opts, git_checkout_opts *opts)
git_indexer_stats *stats)
{ {
git_diff_list *diff = NULL; git_diff_list *diff = NULL;
git_indexer_stats dummy_stats;
git_diff_options diff_opts = {0}; git_diff_options diff_opts = {0};
git_checkout_opts checkout_opts; git_checkout_opts checkout_opts;
...@@ -339,19 +343,11 @@ int git_checkout_index( ...@@ -339,19 +343,11 @@ int git_checkout_index(
normalize_options(&checkout_opts, opts); 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)); memset(&data, 0, sizeof(data));
data.path = &workdir; data.path = &workdir;
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.stats = stats;
data.owner = repo; data.owner = repo;
if ((error = retrieve_symlink_capabilities(repo, &data.can_symlink)) < 0) if ((error = retrieve_symlink_capabilities(repo, &data.can_symlink)) < 0)
...@@ -378,8 +374,6 @@ int git_checkout_index( ...@@ -378,8 +374,6 @@ int git_checkout_index(
diff, &data, checkout_create_the_new, NULL, NULL); diff, &data, checkout_create_the_new, NULL, NULL);
} }
stats->processed = stats->total;
cleanup: cleanup:
if (error == GIT_EUSER) if (error == GIT_EUSER)
error = (data.error != 0) ? data.error : -1; error = (data.error != 0) ? data.error : -1;
...@@ -417,7 +411,7 @@ int git_checkout_tree( ...@@ -417,7 +411,7 @@ int git_checkout_tree(
if ((error = git_index_write(index)) < 0) if ((error = git_index_write(index)) < 0)
goto cleanup; goto cleanup;
error = git_checkout_index(repo, opts, stats); error = git_checkout_index(repo, opts);
cleanup: cleanup:
git_index_free(index); git_index_free(index);
......
...@@ -248,16 +248,11 @@ cleanup: ...@@ -248,16 +248,11 @@ cleanup:
static int setup_remotes_and_fetch(git_repository *repo, static int setup_remotes_and_fetch(git_repository *repo, const char *origin_url)
const char *origin_url,
git_indexer_stats *fetch_stats)
{ {
int retcode = GIT_ERROR; int retcode = GIT_ERROR;
git_remote *origin = NULL; git_remote *origin = NULL;
git_off_t bytes = 0; git_off_t bytes = 0;
git_indexer_stats dummy_stats;
if (!fetch_stats) fetch_stats = &dummy_stats;
/* Create the "origin" remote */ /* Create the "origin" remote */
if (!git_remote_add(&origin, repo, GIT_REMOTE_ORIGIN, origin_url)) { if (!git_remote_add(&origin, repo, GIT_REMOTE_ORIGIN, origin_url)) {
...@@ -327,7 +322,7 @@ static int clone_internal( ...@@ -327,7 +322,7 @@ static int clone_internal(
} }
if (!(retcode = git_repository_init(&repo, path, is_bare))) { 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 */ /* Failed to fetch; clean up */
git_repository_free(repo); git_repository_free(repo);
git_futils_rmdir_r(path, NULL, GIT_DIRREMOVAL_FILES_AND_DIRS); git_futils_rmdir_r(path, NULL, GIT_DIRREMOVAL_FILES_AND_DIRS);
......
...@@ -94,7 +94,7 @@ int git_reset( ...@@ -94,7 +94,7 @@ int git_reset(
| GIT_CHECKOUT_OVERWRITE_MODIFIED | GIT_CHECKOUT_OVERWRITE_MODIFIED
| GIT_CHECKOUT_REMOVE_UNTRACKED; | 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); giterr_set(GITERR_INDEX, "%s - Failed to checkout the index.", ERROR_MSG);
goto cleanup; goto cleanup;
} }
......
...@@ -69,7 +69,7 @@ void test_checkout_index__cannot_checkout_a_bare_repository(void) ...@@ -69,7 +69,7 @@ void test_checkout_index__cannot_checkout_a_bare_repository(void)
memset(&g_opts, 0, sizeof(g_opts)); memset(&g_opts, 0, sizeof(g_opts));
g_repo = cl_git_sandbox_init("testrepo.git"); 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) void test_checkout_index__can_create_missing_files(void)
...@@ -79,7 +79,7 @@ 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")); cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
g_opts.checkout_strategy = GIT_CHECKOUT_CREATE_MISSING; 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/README", "hey there\n");
test_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n"); test_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n");
...@@ -95,7 +95,7 @@ void test_checkout_index__can_remove_untracked_files(void) ...@@ -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")); cl_assert_equal_i(true, git_path_isdir("./testrepo/dir/subdir/subsubdir"));
g_opts.checkout_strategy = GIT_CHECKOUT_REMOVE_UNTRACKED; 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")); cl_assert_equal_i(false, git_path_isdir("./testrepo/dir"));
} }
...@@ -111,7 +111,7 @@ void test_checkout_index__honor_the_specified_pathspecs(void) ...@@ -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/branch_file.txt"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/new.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")); cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
test_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n"); test_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n");
...@@ -142,7 +142,7 @@ void test_checkout_index__honor_the_gitattributes_directives(void) ...@@ -142,7 +142,7 @@ void test_checkout_index__honor_the_gitattributes_directives(void)
cl_git_mkfile("./testrepo/.gitattributes", attributes); cl_git_mkfile("./testrepo/.gitattributes", attributes);
set_core_autocrlf_to(false); 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/README", "hey there\n");
test_file_contents("./testrepo/new.txt", "my new file\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) ...@@ -157,7 +157,7 @@ void test_checkout_index__honor_coreautocrlf_setting_set_to_true(void)
cl_git_pass(p_unlink("./testrepo/.gitattributes")); cl_git_pass(p_unlink("./testrepo/.gitattributes"));
set_core_autocrlf_to(true); 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); test_file_contents("./testrepo/README", expected_readme_text);
#endif #endif
...@@ -172,7 +172,7 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_true(void) ...@@ -172,7 +172,7 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_true(void)
{ {
set_repo_symlink_handling_cap_to(true); 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 #ifdef GIT_WIN32
test_file_contents("./testrepo/link_to_new.txt", "new.txt"); 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) ...@@ -194,7 +194,7 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_false(void)
{ {
set_repo_symlink_handling_cap_to(false); 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"); 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) ...@@ -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!"); cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!");
g_opts.checkout_strategy = 0; 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!"); 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) ...@@ -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!"); cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!");
g_opts.checkout_strategy = GIT_CHECKOUT_OVERWRITE_MODIFIED; 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"); test_file_contents("./testrepo/new.txt", "my new file\n");
} }
...@@ -224,14 +224,14 @@ void test_checkout_index__options_disable_filters(void) ...@@ -224,14 +224,14 @@ void test_checkout_index__options_disable_filters(void)
cl_git_mkfile("./testrepo/.gitattributes", "*.txt text eol=crlf\n"); cl_git_mkfile("./testrepo/.gitattributes", "*.txt text eol=crlf\n");
g_opts.disable_filters = false; 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"); test_file_contents("./testrepo/new.txt", "my new file\r\n");
p_unlink("./testrepo/new.txt"); p_unlink("./testrepo/new.txt");
g_opts.disable_filters = true; 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"); test_file_contents("./testrepo/new.txt", "my new file\n");
} }
...@@ -249,7 +249,7 @@ void test_checkout_index__options_dir_modes(void) ...@@ -249,7 +249,7 @@ void test_checkout_index__options_dir_modes(void)
reset_index_to_treeish((git_object *)commit); reset_index_to_treeish((git_object *)commit);
g_opts.dir_mode = 0701; 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_git_pass(p_stat("./testrepo/a", &st));
cl_assert_equal_i(st.st_mode & 0777, 0701); cl_assert_equal_i(st.st_mode & 0777, 0701);
...@@ -269,7 +269,7 @@ void test_checkout_index__options_override_file_modes(void) ...@@ -269,7 +269,7 @@ void test_checkout_index__options_override_file_modes(void)
g_opts.file_mode = 0700; 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_git_pass(p_stat("./testrepo/new.txt", &st));
cl_assert_equal_i(st.st_mode & 0777, 0700); cl_assert_equal_i(st.st_mode & 0777, 0700);
...@@ -283,7 +283,7 @@ void test_checkout_index__options_open_flags(void) ...@@ -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.file_open_flags = O_CREAT | O_RDWR | O_APPEND;
g_opts.checkout_strategy |= GIT_CHECKOUT_OVERWRITE_MODIFIED; 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"); 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) ...@@ -328,7 +328,7 @@ void test_checkout_index__can_notify_of_skipped_files(void)
g_opts.skipped_notify_cb = notify_cb; g_opts.skipped_notify_cb = notify_cb;
g_opts.notify_payload = &data; 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( static int dont_notify_cb(
...@@ -358,5 +358,22 @@ void test_checkout_index__wont_notify_of_expected_line_ending_changes(void) ...@@ -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.skipped_notify_cb = dont_notify_cb;
g_opts.notify_payload = NULL; 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);
} }
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