summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2021-08-29 21:49:33 -0400
committerGitHub <noreply@github.com>2021-08-29 21:49:33 -0400
commit2998a84ab644ad39b62553baf9c4b30269be7d75 (patch)
tree092a637f24a094a31c3f40bd3a5616a336d97e49
parent147b659f3b1b54752e37c267862a5ade3eb9a902 (diff)
parentaebdee8e3d2871ef4606f1feb0f46a82cfca1373 (diff)
downloadlibgit2-2998a84ab644ad39b62553baf9c4b30269be7d75.tar.gz
Merge pull request #5841 from J0Nes90/features/checkout-dry-run
Checkout dry-run
-rw-r--r--include/git2/checkout.h6
-rw-r--r--src/checkout.c3
-rw-r--r--tests/checkout/tree.c46
3 files changed, 55 insertions, 0 deletions
diff --git a/include/git2/checkout.h b/include/git2/checkout.h
index ca6f17aa6..c7aeee431 100644
--- a/include/git2/checkout.h
+++ b/include/git2/checkout.h
@@ -178,6 +178,12 @@ typedef enum {
GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23),
/**
+ * Show what would be done by a checkout. Stop after sending
+ * notifications; don't update the working directory or index.
+ */
+ GIT_CHECKOUT_DRY_RUN = (1u << 24),
+
+ /**
* THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
*/
diff --git a/src/checkout.c b/src/checkout.c
index 31d473ec8..713159152 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -2622,6 +2622,9 @@ int git_checkout_iterator(
if ((error = checkout_get_actions(&actions, &counts, &data, workdir)) != 0)
goto cleanup;
+ if (data.strategy & GIT_CHECKOUT_DRY_RUN)
+ goto cleanup;
+
data.total_steps = counts[CHECKOUT_ACTION__REMOVE] +
counts[CHECKOUT_ACTION__REMOVE_CONFLICT] +
counts[CHECKOUT_ACTION__UPDATE_BLOB] +
diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c
index f8d9abe55..3241a3eb7 100644
--- a/tests/checkout/tree.c
+++ b/tests/checkout/tree.c
@@ -1636,3 +1636,49 @@ void test_checkout_tree__no_index_refresh(void)
modify_index_and_checkout_tree(&opts);
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);
+}