implement GIT_CHECKOUT_DRY_RUN to allow notifications without touching the working directory

parent ac77d306
...@@ -177,6 +177,9 @@ typedef enum { ...@@ -177,6 +177,9 @@ typedef enum {
/** Normally checkout writes the index upon completion; this prevents that. */ /** Normally checkout writes the index upon completion; this prevents that. */
GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23), GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23),
/** Stop checkout after the notifications happend but before the working directory is touched. */
GIT_CHECKOUT_DRY_RUN = (1u << 24),
/** /**
* THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
*/ */
......
...@@ -2606,6 +2606,9 @@ int git_checkout_iterator( ...@@ -2606,6 +2606,9 @@ int git_checkout_iterator(
if ((error = checkout_get_actions(&actions, &counts, &data, workdir)) != 0) if ((error = checkout_get_actions(&actions, &counts, &data, workdir)) != 0)
goto cleanup; goto cleanup;
if (data.strategy & GIT_CHECKOUT_DRY_RUN)
goto cleanup;
data.total_steps = counts[CHECKOUT_ACTION__REMOVE] + data.total_steps = counts[CHECKOUT_ACTION__REMOVE] +
counts[CHECKOUT_ACTION__REMOVE_CONFLICT] + counts[CHECKOUT_ACTION__REMOVE_CONFLICT] +
counts[CHECKOUT_ACTION__UPDATE_BLOB] + counts[CHECKOUT_ACTION__UPDATE_BLOB] +
......
...@@ -1636,3 +1636,49 @@ void test_checkout_tree__no_index_refresh(void) ...@@ -1636,3 +1636,49 @@ void test_checkout_tree__no_index_refresh(void)
modify_index_and_checkout_tree(&opts); modify_index_and_checkout_tree(&opts);
assert_status_entrycount(g_repo, 0); assert_status_entrycount(g_repo, 0);
} }
void test_checkout_tree__dry_run(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_oid oid;
git_object *obj = NULL;
checkout_counts ct;
/* first let's get things into a known state - by checkout out the HEAD */
assert_on_branch(g_repo, "master");
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert(!git_path_isdir("testrepo/a"));
check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n");
/* now checkout branch but with dry run enabled */
memset(&ct, 0, sizeof(ct));
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DRY_RUN;
opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
opts.notify_cb = checkout_count_callback;
opts.notify_payload = &ct;
cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));
assert_on_branch(g_repo, "dir");
/* these normally would have been created and updated, but with
* DRY_RUN they will be unchanged.
*/
cl_assert(!git_path_isdir("testrepo/a"));
check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n");
/* check that notify callback was invoked */
cl_assert_equal_i(ct.n_updates, 2);
git_object_free(obj);
}
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