mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 22:39:38 +00:00
stash apply: check out a tree, not piecewise
This commit is contained in:
parent
7f26b1b9cf
commit
d0dd3fcee7
41
src/stash.c
41
src/stash.c
@ -652,7 +652,7 @@ static int apply_index(
|
|||||||
git_tree *index_parent_tree,
|
git_tree *index_parent_tree,
|
||||||
git_tree *index_tree)
|
git_tree *index_tree)
|
||||||
{
|
{
|
||||||
git_index* unstashed_index = NULL;
|
git_index *unstashed_index = NULL;
|
||||||
git_merge_options options = GIT_MERGE_OPTIONS_INIT;
|
git_merge_options options = GIT_MERGE_OPTIONS_INIT;
|
||||||
int error;
|
int error;
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
@ -675,43 +675,22 @@ cleanup:
|
|||||||
|
|
||||||
static int apply_untracked(
|
static int apply_untracked(
|
||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
|
git_tree *start_index_tree,
|
||||||
git_tree *untracked_tree)
|
git_tree *untracked_tree)
|
||||||
{
|
{
|
||||||
git_checkout_options options = GIT_CHECKOUT_OPTIONS_INIT;
|
git_checkout_options options = GIT_CHECKOUT_OPTIONS_INIT;
|
||||||
size_t i, count;
|
git_index *merged_index = NULL;
|
||||||
unsigned int status;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
for (i = 0, count = git_tree_entrycount(untracked_tree); i < count; ++i) {
|
options.checkout_strategy =
|
||||||
const git_tree_entry *entry = git_tree_entry_byindex(untracked_tree, i);
|
GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DONT_UPDATE_INDEX;
|
||||||
const char* path = git_tree_entry_name(entry);
|
|
||||||
error = git_status_file(&status, repo, path);
|
|
||||||
if (!error) {
|
|
||||||
giterr_set(GITERR_STASH, "Untracked or ignored file '%s' already exists", path);
|
|
||||||
return GIT_EEXISTS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if ((error = git_merge_trees(&merged_index,
|
||||||
The untracked tree only contains the untracked / ignores files so checking
|
repo, NULL, start_index_tree, untracked_tree, NULL)) == 0)
|
||||||
it out would remove all other files in the workdir. Since git_checkout_tree()
|
error = git_checkout_index(repo, merged_index, &options);
|
||||||
does not have a mode to leave removed files alone, we emulate it by checking
|
|
||||||
out files from the untracked tree one by one.
|
|
||||||
*/
|
|
||||||
|
|
||||||
options.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DONT_UPDATE_INDEX;
|
git_index_free(merged_index);
|
||||||
options.paths.count = 1;
|
|
||||||
for (i = 0, count = git_tree_entrycount(untracked_tree); i < count; ++i) {
|
|
||||||
const git_tree_entry *entry = git_tree_entry_byindex(untracked_tree, i);
|
|
||||||
|
|
||||||
const char* name = git_tree_entry_name(entry);
|
|
||||||
options.paths.strings = (char**)&name;
|
|
||||||
if ((error = git_checkout_tree(
|
|
||||||
repo, (git_object*)untracked_tree, &options)) < 0)
|
|
||||||
return error;
|
return error;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int checkout_modified_notify_callback(
|
static int checkout_modified_notify_callback(
|
||||||
@ -871,7 +850,7 @@ int git_stash_apply(
|
|||||||
|
|
||||||
/* If applicable, restore untracked / ignored files in workdir */
|
/* If applicable, restore untracked / ignored files in workdir */
|
||||||
if (untracked_tree) {
|
if (untracked_tree) {
|
||||||
if ((error = apply_untracked(repo, untracked_tree)) < 0)
|
if ((error = apply_untracked(repo, start_index_tree, untracked_tree)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ void test_stash_apply__conflict_untracked_with_default(void)
|
|||||||
{
|
{
|
||||||
cl_git_mkfile("stash/when", "nothing\n");
|
cl_git_mkfile("stash/when", "nothing\n");
|
||||||
|
|
||||||
cl_git_fail_with(git_stash_apply(repo, 0, GIT_APPLY_DEFAULT), GIT_EEXISTS);
|
cl_git_fail_with(git_stash_apply(repo, 0, GIT_APPLY_DEFAULT), GIT_EMERGECONFLICT);
|
||||||
|
|
||||||
cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
|
cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
|
||||||
assert_status(repo, "what", GIT_STATUS_CURRENT);
|
assert_status(repo, "what", GIT_STATUS_CURRENT);
|
||||||
@ -134,7 +134,7 @@ void test_stash_apply__conflict_untracked_with_reinstate_index(void)
|
|||||||
{
|
{
|
||||||
cl_git_mkfile("stash/when", "nothing\n");
|
cl_git_mkfile("stash/when", "nothing\n");
|
||||||
|
|
||||||
cl_git_fail_with(git_stash_apply(repo, 0, GIT_APPLY_REINSTATE_INDEX), GIT_EEXISTS);
|
cl_git_fail_with(git_stash_apply(repo, 0, GIT_APPLY_REINSTATE_INDEX), GIT_EMERGECONFLICT);
|
||||||
|
|
||||||
cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
|
cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
|
||||||
assert_status(repo, "what", GIT_STATUS_CURRENT);
|
assert_status(repo, "what", GIT_STATUS_CURRENT);
|
||||||
|
Loading…
Reference in New Issue
Block a user