From 493c340ceff0c2fd17deb9f5c18548771f8dd4f5 Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Fri, 12 Sep 2014 21:59:09 +0200 Subject: [PATCH 1/3] Added test case to illustrate bogus conflicts detected if no files were merged, and untracked files exist in the workdir. --- tests/cherrypick/workdir.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/cherrypick/workdir.c b/tests/cherrypick/workdir.c index f41d47833..feacde323 100644 --- a/tests/cherrypick/workdir.c +++ b/tests/cherrypick/workdir.c @@ -92,6 +92,47 @@ void test_cherrypick_workdir__automerge(void) git_signature_free(signature); } +/* git reset --hard cfc4f0999a8367568e049af4f72e452d40828a15 + * git cherry-pick a43a050c588d4e92f11a6b139680923e9728477d*/ +void test_cherrypick_workdir__empty_result(void) +{ + git_oid head_oid; + git_signature *signature = NULL; + git_commit *head = NULL, *commit = NULL; + git_oid cherry_oid; + + const char *cherrypick_oid = "a43a050c588d4e92f11a6b139680923e9728477d"; + + struct merge_index_entry merge_index_entries[] = { + { 0100644, "19c5c7207054604b69c84d08a7571ef9672bb5c2", 0, "file1.txt" }, + { 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 0, "file2.txt" }, + { 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 0, "file3.txt" }, + }; + + cl_git_pass(git_signature_new(&signature, "Picker", "picker@example.org", time(NULL), 0)); + + git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15"); + + /* Create an untracked file that should not conflict */ + cl_git_mkfile(TEST_REPO_PATH "/file4.txt", ""); + cl_assert(git_path_exists(TEST_REPO_PATH "/file4.txt")); + + cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); + cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL, NULL)); + + git_oid_fromstr(&cherry_oid, cherrypick_oid); + cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); + cl_git_pass(git_cherrypick(repo, commit, NULL)); + + /* The resulting tree should not have changed, the change was already on HEAD */ + cl_assert(merge_test_index(repo_index, merge_index_entries, 3)); + + git_commit_free(head); + git_commit_free(commit); + + git_signature_free(signature); +} + /* git reset --hard bafbf6912c09505ac60575cd43d3f2aba3bd84d8 * git cherry-pick e9b63f3655b2ad80c0ff587389b5a9589a3a7110 */ From a565f364aba55c730908f80e63c90d9432667075 Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Fri, 12 Sep 2014 22:53:56 +0200 Subject: [PATCH 2/3] Only check for workdir conflicts if the index has merged files Passing 0 as the length of the paths to check to git_diff_index_to_workdir results in all files being treated as conflicting, that is, all untracked or modified files in the worktree is reported as conflicting --- src/merge.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/merge.c b/src/merge.c index 926a600cc..341f9a645 100644 --- a/src/merge.c +++ b/src/merge.c @@ -2347,6 +2347,16 @@ static int merge_check_workdir(size_t *conflicts, git_repository *repo, git_inde *conflicts = 0; + /* We need to have merged at least 1 file for the possibility to exist to + * have conflicts with the workdir. Passing 0 as the pathspec count paramter + * will consider all files in the working directory, that is, we may detect + * a conflict if there were untracked files in the workdir prior to starting + * the merge. This typically happens when cherry-picking a commmit whose + * changes have already been applied. + */ + if (merged_paths->length == 0) + return 0; + opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED; /* Workdir changes may exist iff they do not conflict with changes that From dc68ee8d158e4a773f3eaef4cdcb038e042e0e4e Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Fri, 12 Sep 2014 22:37:15 +0200 Subject: [PATCH 3/3] Remove local unused index_repo variable --- src/merge.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/merge.c b/src/merge.c index 341f9a645..ddeea8752 100644 --- a/src/merge.c +++ b/src/merge.c @@ -2338,7 +2338,6 @@ done: static int merge_check_workdir(size_t *conflicts, git_repository *repo, git_index *index_new, git_vector *merged_paths) { - git_index *index_repo = NULL; git_diff *wd_diff_list = NULL; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; int error = 0; @@ -2366,13 +2365,12 @@ static int merge_check_workdir(size_t *conflicts, git_repository *repo, git_inde opts.pathspec.count = merged_paths->length; opts.pathspec.strings = (char **)merged_paths->contents; - if ((error = git_diff_index_to_workdir(&wd_diff_list, repo, index_repo, &opts)) < 0) + if ((error = git_diff_index_to_workdir(&wd_diff_list, repo, NULL, &opts)) < 0) goto done; *conflicts = wd_diff_list->deltas.length; done: - git_index_free(index_repo); git_diff_free(wd_diff_list); return error;