Skip to content

Commit 2998a84

Browse files
authored
Merge pull request libgit2#5841 from J0Nes90/features/checkout-dry-run
Checkout dry-run
2 parents 147b659 + aebdee8 commit 2998a84

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

include/git2/checkout.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ typedef enum {
177177
/** Normally checkout writes the index upon completion; this prevents that. */
178178
GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23),
179179

180+
/**
181+
* Show what would be done by a checkout. Stop after sending
182+
* notifications; don't update the working directory or index.
183+
*/
184+
GIT_CHECKOUT_DRY_RUN = (1u << 24),
185+
180186
/**
181187
* THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
182188
*/

src/checkout.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2622,6 +2622,9 @@ int git_checkout_iterator(
26222622
if ((error = checkout_get_actions(&actions, &counts, &data, workdir)) != 0)
26232623
goto cleanup;
26242624

2625+
if (data.strategy & GIT_CHECKOUT_DRY_RUN)
2626+
goto cleanup;
2627+
26252628
data.total_steps = counts[CHECKOUT_ACTION__REMOVE] +
26262629
counts[CHECKOUT_ACTION__REMOVE_CONFLICT] +
26272630
counts[CHECKOUT_ACTION__UPDATE_BLOB] +

tests/checkout/tree.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,3 +1636,49 @@ void test_checkout_tree__no_index_refresh(void)
16361636
modify_index_and_checkout_tree(&opts);
16371637
assert_status_entrycount(g_repo, 0);
16381638
}
1639+
1640+
void test_checkout_tree__dry_run(void)
1641+
{
1642+
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
1643+
git_oid oid;
1644+
git_object *obj = NULL;
1645+
checkout_counts ct;
1646+
1647+
/* first let's get things into a known state - by checkout out the HEAD */
1648+
1649+
assert_on_branch(g_repo, "master");
1650+
1651+
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
1652+
cl_git_pass(git_checkout_head(g_repo, &opts));
1653+
1654+
cl_assert(!git_path_isdir("testrepo/a"));
1655+
1656+
check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n");
1657+
1658+
/* now checkout branch but with dry run enabled */
1659+
1660+
memset(&ct, 0, sizeof(ct));
1661+
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DRY_RUN;
1662+
opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
1663+
opts.notify_cb = checkout_count_callback;
1664+
opts.notify_payload = &ct;
1665+
1666+
cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
1667+
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
1668+
1669+
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
1670+
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));
1671+
1672+
assert_on_branch(g_repo, "dir");
1673+
1674+
/* these normally would have been created and updated, but with
1675+
* DRY_RUN they will be unchanged.
1676+
*/
1677+
cl_assert(!git_path_isdir("testrepo/a"));
1678+
check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n");
1679+
1680+
/* check that notify callback was invoked */
1681+
cl_assert_equal_i(ct.n_updates, 2);
1682+
1683+
git_object_free(obj);
1684+
}

0 commit comments

Comments
 (0)