summaryrefslogtreecommitdiff
path: root/tests-clar/diff
diff options
context:
space:
mode:
Diffstat (limited to 'tests-clar/diff')
-rw-r--r--tests-clar/diff/diff_helpers.c14
-rw-r--r--tests-clar/diff/workdir.c70
2 files changed, 79 insertions, 5 deletions
diff --git a/tests-clar/diff/diff_helpers.c b/tests-clar/diff/diff_helpers.c
index 466d0ef54..33bb561f6 100644
--- a/tests-clar/diff/diff_helpers.c
+++ b/tests-clar/diff/diff_helpers.c
@@ -221,11 +221,15 @@ static int diff_print_cb(
const git_diff_line *line,
void *payload)
{
- GIT_UNUSED(payload);
- GIT_UNUSED(delta);
- GIT_UNUSED(hunk);
- fprintf((FILE *)payload, "%c%.*s",
- line->origin, (int)line->content_len, line->content);
+ FILE *fp = payload;
+
+ GIT_UNUSED(delta); GIT_UNUSED(hunk);
+
+ if (line->origin == GIT_DIFF_LINE_CONTEXT ||
+ line->origin == GIT_DIFF_LINE_ADDITION ||
+ line->origin == GIT_DIFF_LINE_DELETION)
+ fputc(line->origin, fp);
+ fwrite(line->content, 1, line->content_len, fp);
return 0;
}
diff --git a/tests-clar/diff/workdir.c b/tests-clar/diff/workdir.c
index e72acdb03..8611be8c8 100644
--- a/tests-clar/diff/workdir.c
+++ b/tests-clar/diff/workdir.c
@@ -1329,3 +1329,73 @@ void test_diff_workdir__patience_diff(void)
git_patch_free(patch);
git_diff_free(diff);
}
+
+void test_diff_workdir__with_stale_index(void)
+{
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff *diff = NULL;
+ git_index *idx = NULL;
+ diff_expects exp;
+
+ g_repo = cl_git_sandbox_init("status");
+ cl_git_pass(git_repository_index(&idx, g_repo));
+
+ /* make the in-memory index invalid */
+ {
+ git_repository *r2;
+ git_index *idx2;
+ cl_git_pass(git_repository_open(&r2, "status"));
+ cl_git_pass(git_repository_index(&idx2, r2));
+ cl_git_pass(git_index_add_bypath(idx2, "new_file"));
+ cl_git_pass(git_index_add_bypath(idx2, "subdir/new_file"));
+ cl_git_pass(git_index_remove_bypath(idx2, "staged_new_file"));
+ cl_git_pass(git_index_remove_bypath(idx2, "staged_changes_file_deleted"));
+ cl_git_pass(git_index_write(idx2));
+ git_index_free(idx2);
+ git_repository_free(r2);
+ }
+
+ opts.context_lines = 3;
+ opts.interhunk_lines = 1;
+ opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_INCLUDE_UNMODIFIED;
+
+ /* first try with index pointer which should prevent reload */
+
+ cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, idx, &opts));
+
+ memset(&exp, 0, sizeof(exp));
+
+ cl_git_pass(git_diff_foreach(
+ diff, diff_file_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+ cl_assert_equal_i(17, exp.files);
+ cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+ cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
+ cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
+ cl_assert_equal_i(4, exp.file_status[GIT_DELTA_UNTRACKED]);
+ cl_assert_equal_i(5, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+ git_diff_free(diff);
+
+ /* now let's try without the index pointer which should trigger reload */
+
+ /* two files that were UNTRACKED should have become UNMODIFIED */
+ /* one file that was UNMODIFIED should now have become UNTRACKED */
+ /* one file that was DELETED should now be gone completely */
+
+ cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+ memset(&exp, 0, sizeof(exp));
+
+ cl_git_pass(git_diff_foreach(
+ diff, diff_file_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+ cl_assert_equal_i(16, exp.files);
+ cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+ cl_assert_equal_i(3, exp.file_status[GIT_DELTA_DELETED]);
+ cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
+ cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNTRACKED]);
+ cl_assert_equal_i(6, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+ git_index_free(idx);
+}