Commit 9db66c790d04ee81e838160d2c60c6193daef82f

Edward Thomson 2018-06-29T12:50:38

apply test: apply with non-conflicting changes Ensure that we can apply to the working directory or the index when the application target is modified, so long as there are not conflicting changes to the items.

diff --git a/tests/apply/index.c b/tests/apply/index.c
index 23ead1a..52510d6 100644
--- a/tests/apply/index.c
+++ b/tests/apply/index.c
@@ -226,3 +226,46 @@ void test_apply_index__application_failure_leaves_index_unmodified(void)
 
 	git_diff_free(diff);
 }
+
+void test_apply_index__keeps_nonconflicting_changes(void)
+{
+	git_diff *diff;
+	git_index *index;
+	git_index_entry idx_entry;
+	git_apply_options opts = GIT_APPLY_OPTIONS_INIT;
+
+	const char *diff_file = DIFF_MODIFY_TWO_FILES;
+
+	struct merge_index_entry index_expected[] = {
+		{ 0100644, "ffb36e513f5fdf8a6ba850a20142676a2ac4807d", 0, "asparagus.txt" },
+		{ 0100644, "898d12687fb35be271c27c795a6b32c8b51da79e", 0, "beef.txt" },
+		{ 0100644, "c4e6cca3ec6ae0148ed231f97257df8c311e015f", 0, "gravy.txt" },
+		{ 0100644, "68af1fc7407fd9addf1701a87eb1c95c7494c598", 0, "oyster.txt" },
+		{ 0100644, "a7b066537e6be7109abfe4ff97b675d4e077da20", 0, "veal.txt" },
+	};
+	size_t index_expected_cnt = sizeof(index_expected) /
+		sizeof(struct merge_index_entry);
+
+	/* mutate the index */
+	cl_git_pass(git_repository_index(&index, repo));
+
+	memset(&idx_entry, 0, sizeof(git_index_entry));
+	idx_entry.mode = 0100644;
+	idx_entry.path = "beef.txt";
+	cl_git_pass(git_oid_fromstr(&idx_entry.id, "898d12687fb35be271c27c795a6b32c8b51da79e"));
+	cl_git_pass(git_index_add(index, &idx_entry));
+
+	cl_git_pass(git_index_remove(index, "bouilli.txt", 0));
+	cl_git_pass(git_index_write(index));
+	git_index_free(index);
+
+	cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
+
+	opts.location = GIT_APPLY_LOCATION_INDEX;
+	cl_git_pass(git_apply(repo, diff, &opts));
+
+	validate_apply_index(repo, index_expected, index_expected_cnt);
+	validate_workdir_unchanged(repo);
+
+	git_diff_free(diff);
+}
diff --git a/tests/apply/workdir.c b/tests/apply/workdir.c
index 3d1f39b..34d1072 100644
--- a/tests/apply/workdir.c
+++ b/tests/apply/workdir.c
@@ -216,3 +216,30 @@ void test_apply_workdir__application_failure_leaves_workdir_unmodified(void)
 
 	git_diff_free(diff);
 }
+
+void test_apply_workdir__keeps_nonconflicting_changes(void)
+{
+	git_diff *diff;
+
+	struct merge_index_entry workdir_expected[] = {
+		{ 0100644, "ffb36e513f5fdf8a6ba850a20142676a2ac4807d", 0, "asparagus.txt" },
+		{ 0100644, "68f6182f4c85d39e1309d97c7e456156dc9c0096", 0, "beef.txt" },
+		{ 0100644, "4b7c5650008b2e747fe1809eeb5a1dde0e80850a", 0, "bouilli.txt" },
+		{ 0100644, "f75ba05f340c51065cbea2e1fdbfe5fe13144c97", 0, "gravy.txt" },
+		{ 0100644, "a7b066537e6be7109abfe4ff97b675d4e077da20", 0, "veal.txt" },
+	};
+	size_t workdir_expected_cnt = sizeof(workdir_expected) /
+	    sizeof(struct merge_index_entry);
+
+	cl_git_rmfile("merge-recursive/oyster.txt");
+	cl_git_rewritefile("merge-recursive/gravy.txt", "Hello, world.\n");
+
+	cl_git_pass(git_diff_from_buffer(&diff,
+		DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES)));
+	cl_git_pass(git_apply(repo, diff, NULL));
+
+	validate_index_unchanged(repo);
+	validate_apply_workdir(repo, workdir_expected, workdir_expected_cnt);
+
+	git_diff_free(diff);
+}