mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-04 08:43:55 +00:00
Fix handling of GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH flag.
git_checkout_tree() sets up its working directory iterator to respect the pathlist if GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH is present, which is great. What's not so great is that this iterator is then used side-by-side with an iterator created by git_checkout_iterator(), which did not set up its pathlist appropriately (although the iterator mirrors all other iterator options). This could cause git_checkout_tree() to delete working tree files which were not specified in the pathlist when GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH was used, as the unsynchronized iterators causes git_checkout_tree() to think that files have been deleted between the two trees. Oops. And added a test which fails without this fix (specifically, the final check for "testrepo/README" to still be present fails).
This commit is contained in:
parent
238b8ccd1a
commit
5f959dca0d
@ -2553,6 +2553,10 @@ int git_checkout_iterator(
|
||||
GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE;
|
||||
baseline_opts.start = data.pfx;
|
||||
baseline_opts.end = data.pfx;
|
||||
if (opts && (opts->checkout_strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH)) {
|
||||
baseline_opts.pathlist.count = opts->paths.count;
|
||||
baseline_opts.pathlist.strings = opts->paths.strings;
|
||||
}
|
||||
|
||||
if (data.opts.baseline_index) {
|
||||
if ((error = git_iterator_for_index(
|
||||
|
@ -422,6 +422,44 @@ void test_checkout_tree__can_checkout_with_pattern(void)
|
||||
cl_assert(git_path_exists("testrepo/new.txt"));
|
||||
}
|
||||
|
||||
void test_checkout_tree__pathlist_checkout_ignores_non_matches(void)
|
||||
{
|
||||
char *entries[] = { "branch_file.txt", "link_to_new.txt" };
|
||||
|
||||
/* reset to beginning of history (i.e. just a README file) */
|
||||
|
||||
g_opts.checkout_strategy =
|
||||
GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
|
||||
|
||||
cl_git_pass(git_revparse_single(&g_object, g_repo, "refs/heads/master"));
|
||||
|
||||
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
|
||||
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master"));
|
||||
|
||||
cl_assert(git_path_exists("testrepo/README"));
|
||||
cl_assert(git_path_exists("testrepo/branch_file.txt"));
|
||||
cl_assert(git_path_exists("testrepo/link_to_new.txt"));
|
||||
cl_assert(git_path_exists("testrepo/new.txt"));
|
||||
|
||||
cl_git_pass(git_revparse_single(&g_object, g_repo, "8496071c1b46c854b31185ea97743be6a8774479"));
|
||||
|
||||
g_opts.checkout_strategy =
|
||||
GIT_CHECKOUT_FORCE | GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH;
|
||||
g_opts.paths.strings = entries;
|
||||
g_opts.paths.count = 2;
|
||||
|
||||
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
|
||||
|
||||
cl_assert(git_path_exists("testrepo/README"));
|
||||
cl_assert(!git_path_exists("testrepo/branch_file.txt"));
|
||||
cl_assert(!git_path_exists("testrepo/link_to_new.txt"));
|
||||
cl_assert(git_path_exists("testrepo/new.txt"));
|
||||
|
||||
git_object_free(g_object);
|
||||
g_object = NULL;
|
||||
|
||||
}
|
||||
|
||||
void test_checkout_tree__can_disable_pattern_match(void)
|
||||
{
|
||||
char *entries[] = { "b*.txt" };
|
||||
|
Loading…
Reference in New Issue
Block a user