summaryrefslogtreecommitdiff
path: root/tests-clar/diff
diff options
context:
space:
mode:
authorVicent Martí <vicent@github.com>2013-11-04 08:05:55 -0800
committerVicent Martí <vicent@github.com>2013-11-04 08:05:55 -0800
commit5a0b88036f612ce7e9cdc24517c9b9eb6100a3d7 (patch)
tree835825d113deeceef856702bfd7b427648579b4d /tests-clar/diff
parentbecb13c0f04c4ba54cf27303136293dbf8abfd73 (diff)
parent3e57069e821ecf966c3de9c79923cd77657e923b (diff)
downloadlibgit2-5a0b88036f612ce7e9cdc24517c9b9eb6100a3d7.tar.gz
Merge pull request #1929 from libgit2/rb/misc-diff-fixes
Fix some observed problems with incorrect diffs
Diffstat (limited to 'tests-clar/diff')
-rw-r--r--tests-clar/diff/blob.c3
-rw-r--r--tests-clar/diff/diff_helpers.c14
-rw-r--r--tests-clar/diff/tree.c7
-rw-r--r--tests-clar/diff/workdir.c156
4 files changed, 169 insertions, 11 deletions
diff --git a/tests-clar/diff/blob.c b/tests-clar/diff/blob.c
index b51bc0f38..93f20711c 100644
--- a/tests-clar/diff/blob.c
+++ b/tests-clar/diff/blob.c
@@ -26,9 +26,8 @@ void test_diff_blob__initialize(void)
g_repo = cl_git_sandbox_init("attr");
- GIT_INIT_STRUCTURE(&opts, GIT_DIFF_OPTIONS_VERSION);
+ cl_git_pass(git_diff_options_init(&opts, GIT_DIFF_OPTIONS_VERSION));
opts.context_lines = 1;
- opts.interhunk_lines = 0;
memset(&expected, 0, sizeof(expected));
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/tree.c b/tests-clar/diff/tree.c
index ca2daf5fb..582174b8b 100644
--- a/tests-clar/diff/tree.c
+++ b/tests-clar/diff/tree.c
@@ -9,9 +9,7 @@ static diff_expects expect;
void test_diff_tree__initialize(void)
{
- GIT_INIT_STRUCTURE(&opts, GIT_DIFF_OPTIONS_VERSION);
- /* The default context lines is set by _INIT which we can't use here */
- opts.context_lines = 3;
+ cl_git_pass(git_diff_options_init(&opts, GIT_DIFF_OPTIONS_VERSION));
memset(&expect, 0, sizeof(expect));
@@ -91,7 +89,8 @@ void test_diff_tree__0(void)
}
#define DIFF_OPTS(FLAGS, CTXT) \
- {GIT_DIFF_OPTIONS_VERSION, (FLAGS), 0, {NULL,0}, NULL, NULL, (CTXT), 1}
+ {GIT_DIFF_OPTIONS_VERSION, (FLAGS), GIT_SUBMODULE_IGNORE_DEFAULT, \
+ {NULL,0}, NULL, NULL, (CTXT), 1}
void test_diff_tree__options(void)
{
diff --git a/tests-clar/diff/workdir.c b/tests-clar/diff/workdir.c
index 60acd365d..df31e7322 100644
--- a/tests-clar/diff/workdir.c
+++ b/tests-clar/diff/workdir.c
@@ -63,6 +63,60 @@ void test_diff_workdir__to_index(void)
git_diff_free(diff);
}
+void test_diff_workdir__to_index_with_assume_unchanged(void)
+{
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff *diff = NULL;
+ git_index *idx = NULL;
+ diff_expects exp;
+ const git_index_entry *iep;
+ git_index_entry ie;
+
+ g_repo = cl_git_sandbox_init("status");
+
+ /* do initial diff */
+
+ 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(8, 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]);
+ git_diff_free(diff);
+
+ /* mark a couple of entries with ASSUME_UNCHANGED */
+
+ cl_git_pass(git_repository_index(&idx, g_repo));
+
+ cl_assert((iep = git_index_get_bypath(idx, "modified_file", 0)) != NULL);
+ memcpy(&ie, iep, sizeof(ie));
+ ie.flags |= GIT_IDXENTRY_VALID;
+ cl_git_pass(git_index_add(idx, &ie));
+
+ cl_assert((iep = git_index_get_bypath(idx, "file_deleted", 0)) != NULL);
+ memcpy(&ie, iep, sizeof(ie));
+ ie.flags |= GIT_IDXENTRY_VALID;
+ cl_git_pass(git_index_add(idx, &ie));
+
+ cl_git_pass(git_index_write(idx));
+ git_index_free(idx);
+
+ /* redo diff and see that entries are skipped */
+
+ 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(6, 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(3, exp.file_status[GIT_DELTA_MODIFIED]);
+ git_diff_free(diff);
+
+}
+
void test_diff_workdir__to_tree(void)
{
/* grabbed a couple of commit oids from the history of the attr repo */
@@ -196,6 +250,38 @@ void test_diff_workdir__to_tree(void)
git_diff_free(diff);
+ /* Let's try that once more with a reversed diff */
+
+ opts.flags |= GIT_DIFF_REVERSE;
+
+ cl_git_pass(git_diff_tree_to_index(&diff, g_repo, b, NULL, &opts));
+ cl_git_pass(git_diff_index_to_workdir(&diff2, g_repo, NULL, &opts));
+ cl_git_pass(git_diff_merge(diff, diff2));
+ git_diff_free(diff2);
+
+ 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(5, exp.file_status[GIT_DELTA_DELETED]);
+ cl_assert_equal_i(4, exp.file_status[GIT_DELTA_ADDED]);
+ cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
+ cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+ cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+ cl_assert_equal_i(12, exp.hunks);
+
+ cl_assert_equal_i(19, exp.lines);
+ cl_assert_equal_i(3, exp.line_ctxt);
+ cl_assert_equal_i(12, exp.line_dels);
+ cl_assert_equal_i(4, exp.line_adds);
+
+ git_diff_free(diff);
+
+ /* all done now */
+
git_tree_free(a);
git_tree_free(b);
}
@@ -1330,3 +1416,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);
+}