diff options
| author | Vicent Martà <vicent@github.com> | 2013-11-04 08:05:55 -0800 |
|---|---|---|
| committer | Vicent Martà <vicent@github.com> | 2013-11-04 08:05:55 -0800 |
| commit | 5a0b88036f612ce7e9cdc24517c9b9eb6100a3d7 (patch) | |
| tree | 835825d113deeceef856702bfd7b427648579b4d /tests-clar/diff | |
| parent | becb13c0f04c4ba54cf27303136293dbf8abfd73 (diff) | |
| parent | 3e57069e821ecf966c3de9c79923cd77657e923b (diff) | |
| download | libgit2-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.c | 3 | ||||
| -rw-r--r-- | tests-clar/diff/diff_helpers.c | 14 | ||||
| -rw-r--r-- | tests-clar/diff/tree.c | 7 | ||||
| -rw-r--r-- | tests-clar/diff/workdir.c | 156 |
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); +} |
