void test_diff_tree__larger_hunks(void) { const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69"; const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10"; git_tree *a, *b; git_diff_options opts = {0}; git_diff_list *diff = NULL; size_t d, num_d, h, num_h, l, num_l, header_len, line_len; const git_diff_delta *delta; git_diff_patch *patch; const git_diff_range *range; const char *header, *line; char origin; g_repo = cl_git_sandbox_init("diff"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); opts.context_lines = 1; opts.interhunk_lines = 0; cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, a, b, &diff)); num_d = git_diff_num_deltas(diff); for (d = 0; d < num_d; ++d) { cl_git_pass(git_diff_get_patch(&patch, &delta, diff, d)); cl_assert(patch && delta); num_h = git_diff_patch_num_hunks(patch); for (h = 0; h < num_h; h++) { cl_git_pass(git_diff_patch_get_hunk( &range, &header, &header_len, &num_l, patch, h)); for (l = 0; l < num_l; ++l) { cl_git_pass(git_diff_patch_get_line_in_hunk( &origin, &line, &line_len, NULL, NULL, patch, h, l)); cl_assert(line); } cl_git_fail(git_diff_patch_get_line_in_hunk( &origin, &line, &line_len, NULL, NULL, patch, h, num_l)); } cl_git_fail(git_diff_patch_get_hunk( &range, &header, &header_len, &num_l, patch, num_h)); git_diff_patch_free(patch); } cl_git_fail(git_diff_get_patch(&patch, &delta, diff, num_d)); cl_assert_equal_i(2, (int)num_d); git_diff_list_free(diff); diff = NULL; git_tree_free(a); git_tree_free(b); }
void test_diff_tree__bare(void) { const char *a_commit = "8496071c1b46c85"; const char *b_commit = "be3563ae3f79"; g_repo = cl_git_sandbox_init("testrepo.git"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); opts.context_lines = 1; opts.interhunk_lines = 1; cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect)); cl_assert_equal_i(3, expect.files); cl_assert_equal_i(2, expect.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(0, expect.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(1, expect.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(3, expect.hunks); cl_assert_equal_i(4, expect.lines); cl_assert_equal_i(0, expect.line_ctxt); cl_assert_equal_i(3, expect.line_adds); cl_assert_equal_i(1, expect.line_dels); }
void test_diff_index__1(void) { /* grabbed a couple of commit oids from the history of the attr repo */ const char *a_commit = "26a125ee1bf"; /* the current HEAD */ const char *b_commit = "0017bd4ab1ec3"; /* the start */ git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit); git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit); git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_diff *diff = NULL; diff_expects exp; cl_assert(a); cl_assert(b); opts.context_lines = 1; opts.interhunk_lines = 1; memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts)); cl_assert_equal_i(1, git_diff_foreach( diff, diff_stop_after_2_files, NULL, NULL, NULL, &exp) ); cl_assert_equal_i(2, exp.files); git_diff_free(diff); diff = NULL; git_tree_free(a); git_tree_free(b); }
void test_diff_tree__0(void) { /* grabbed a couple of commit oids from the history of the attr repo */ const char *a_commit = "605812a"; const char *b_commit = "370fe9ec22"; const char *c_commit = "f5b0af1fb4f5c"; git_tree *c; g_repo = cl_git_sandbox_init("attr"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL); opts.context_lines = 1; opts.interhunk_lines = 1; cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect)); cl_assert_equal_i(5, expect.files); cl_assert_equal_i(2, expect.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(1, expect.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(2, expect.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(5, expect.hunks); cl_assert_equal_i(7 + 24 + 1 + 6 + 6, expect.lines); cl_assert_equal_i(1, expect.line_ctxt); cl_assert_equal_i(24 + 1 + 5 + 5, expect.line_adds); cl_assert_equal_i(7 + 1, expect.line_dels); git_diff_free(diff); diff = NULL; memset(&expect, 0, sizeof(expect)); cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, c, b, &opts)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect)); cl_assert_equal_i(2, expect.files); cl_assert_equal_i(0, expect.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(0, expect.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(2, expect.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(2, expect.hunks); cl_assert_equal_i(8 + 15, expect.lines); cl_assert_equal_i(1, expect.line_ctxt); cl_assert_equal_i(1, expect.line_adds); cl_assert_equal_i(7 + 14, expect.line_dels); git_tree_free(c); }
void process_tree_to_tree_diffing( const char *old_commit, const char *new_commit) { g_repo = cl_git_sandbox_init("unsymlinked.git"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, old_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, new_commit)) != NULL); cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, NULL, NULL, NULL, &expect)); }
static void tree_iterator_test( const char *sandbox, const char *treeish, const char *start, const char *end, int expected_count, const char **expected_values) { git_tree *t; git_iterator *i; const git_index_entry *entry; int count = 0; git_repository *repo = cl_git_sandbox_init(sandbox); cl_assert(t = resolve_commit_oid_to_tree(repo, treeish)); cl_git_pass(git_iterator_for_tree_range(&i, repo, t, start, end)); cl_git_pass(git_iterator_current(i, &entry)); while (entry != NULL) { if (expected_values != NULL) cl_assert_equal_s(expected_values[count], entry->path); count++; cl_git_pass(git_iterator_advance(i, &entry)); } git_iterator_free(i); cl_assert(expected_count == count); git_tree_free(t); }
void test_diff_index__to_index(void) { const char *a_commit = "26a125ee1bf"; /* the current HEAD */ git_tree *old_tree; git_index *old_index; git_index *new_index; git_diff *diff; diff_expects exp; cl_git_pass(git_index_new(&old_index)); old_tree = resolve_commit_oid_to_tree(g_repo, a_commit); cl_git_pass(git_index_read_tree(old_index, old_tree)); cl_git_pass(git_repository_index(&new_index, g_repo)); cl_git_pass(git_diff_index_to_index(&diff, g_repo, old_index, new_index, NULL)); memset(&exp, 0, sizeof(diff_expects)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp)); cl_assert_equal_i(8, exp.files); cl_assert_equal_i(3, exp.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(0, exp.file_status[GIT_DELTA_CONFLICTED]); git_diff_free(diff); git_index_free(new_index); git_index_free(old_index); git_tree_free(old_tree); }
void test_diff_index__not_in_head_conflicted(void) { const char *a_commit = "26a125ee1bf"; /* the current HEAD */ git_index_entry theirs = {{0}}; git_index *index; git_diff *diff; const git_diff_delta *delta; git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit); cl_git_pass(git_repository_index(&index, g_repo)); cl_git_pass(git_index_read_tree(index, a)); theirs.path = "file_not_in_head"; theirs.mode = GIT_FILEMODE_BLOB; git_oid_fromstr(&theirs.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); cl_git_pass(git_index_conflict_add(index, NULL, NULL, &theirs)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, index, NULL)); cl_assert_equal_i(git_diff_num_deltas(diff), 1); delta = git_diff_get_delta(diff, 0); cl_assert_equal_i(delta->status, GIT_DELTA_CONFLICTED); git_diff_free(diff); git_index_free(index); git_tree_free(a); }
void test_diff_workdir__submodules(void) { const char *a_commit = "873585b94bdeabccea991ea5e3ec1a277895b698"; git_tree *a; git_diff_options opts = {0}; git_diff_list *diff = NULL; diff_expects exp; g_repo = cl_git_sandbox_init("submod2"); cl_fixture_sandbox("submod2_target"); p_rename("submod2_target/.gitted", "submod2_target/.git"); rewrite_gitmodules(git_repository_workdir(g_repo)); p_rename("submod2/not_submodule/.gitted", "submod2/not_submodule/.git"); cl_fixture_cleanup("submod2_target"); a = resolve_commit_oid_to_tree(g_repo, a_commit); opts.flags = GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_RECURSE_UNTRACKED_DIRS | GIT_DIFF_INCLUDE_UNTRACKED_CONTENT; cl_git_pass(git_diff_workdir_to_tree(g_repo, &opts, a, &diff)); /* diff_print(stderr, diff); */ /* essentially doing: git diff 873585b94bdeabccea991ea5e3ec1a277895b698 */ memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_foreach( diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); /* the following differs from "git diff 873585" by one "untracked" file * because the diff list includes the "not_submodule/" directory which * is not displayed in the text diff. */ cl_assert_equal_i(10, exp.files); cl_assert_equal_i(0, exp.file_adds); cl_assert_equal_i(0, exp.file_dels); cl_assert_equal_i(1, exp.file_mods); cl_assert_equal_i(0, exp.file_ignored); cl_assert_equal_i(9, exp.file_untracked); /* the following numbers match "git diff 873585" exactly */ cl_assert_equal_i(9, exp.hunks); cl_assert_equal_i(33, exp.lines); cl_assert_equal_i(2, exp.line_ctxt); cl_assert_equal_i(30, exp.line_adds); cl_assert_equal_i(1, exp.line_dels); git_diff_list_free(diff); git_tree_free(a); }
void test_diff_tree__merge(void) { /* grabbed a couple of commit oids from the history of the attr repo */ const char *a_commit = "605812a"; const char *b_commit = "370fe9ec22"; const char *c_commit = "f5b0af1fb4f5c"; git_tree *a, *b, *c; git_diff_list *diff1 = NULL, *diff2 = NULL; diff_expects exp; g_repo = cl_git_sandbox_init("attr"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL); cl_git_pass(git_diff_tree_to_tree(g_repo, NULL, a, b, &diff1)); cl_git_pass(git_diff_tree_to_tree(g_repo, NULL, c, b, &diff2)); git_tree_free(a); git_tree_free(b); git_tree_free(c); cl_git_pass(git_diff_merge(diff1, diff2)); git_diff_list_free(diff2); memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_foreach( diff1, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); cl_assert_equal_i(6, exp.files); cl_assert_equal_i(2, exp.file_adds); cl_assert_equal_i(1, exp.file_dels); cl_assert_equal_i(3, exp.file_mods); cl_assert_equal_i(6, exp.hunks); cl_assert_equal_i(59, exp.lines); cl_assert_equal_i(1, exp.line_ctxt); cl_assert_equal_i(36, exp.line_adds); cl_assert_equal_i(22, exp.line_dels); git_diff_list_free(diff1); }
void test_diff_tree__larger_hunks(void) { const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69"; const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10"; size_t d, num_d, h, num_h, l, num_l; git_patch *patch; const git_diff_hunk *hunk; const git_diff_line *line; g_repo = cl_git_sandbox_init("diff"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); opts.context_lines = 1; opts.interhunk_lines = 0; cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts)); num_d = git_diff_num_deltas(diff); for (d = 0; d < num_d; ++d) { cl_git_pass(git_patch_from_diff(&patch, diff, d)); cl_assert(patch); num_h = git_patch_num_hunks(patch); for (h = 0; h < num_h; h++) { cl_git_pass(git_patch_get_hunk(&hunk, &num_l, patch, h)); for (l = 0; l < num_l; ++l) { cl_git_pass(git_patch_get_line_in_hunk(&line, patch, h, l)); cl_assert(line); } cl_git_fail(git_patch_get_line_in_hunk(&line, patch, h, num_l)); } cl_git_fail(git_patch_get_hunk(&hunk, &num_l, patch, num_h)); git_patch_free(patch); } cl_git_fail(git_patch_from_diff(&patch, diff, num_d)); cl_assert_equal_i(2, (int)num_d); }
void test_diff_iterator__tree_special_functions(void) { git_tree *t; git_iterator *i; git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT; const git_index_entry *entry; git_repository *repo = cl_git_sandbox_init("attr"); int error, cases = 0; const char *rootoid = "ce39a97a7fb1fa90bcf5e711249c1e507476ae0e"; t = resolve_commit_oid_to_tree( repo, "24fa9a9fc4e202313e24b648087495441dab432b"); cl_assert(t != NULL); i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE; cl_git_pass(git_iterator_for_tree(&i, t, &i_opts)); while (!(error = git_iterator_advance(&entry, i))) { cl_assert(entry); if (strcmp(entry->path, "sub/file") == 0) { cases++; check_tree_entry( i, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "ecb97df2a174987475ac816e3847fc8e9f6c596b", rootoid, NULL); } else if (strcmp(entry->path, "sub/sub/subsub.txt") == 0) { cases++; check_tree_entry( i, "9e5bdc47d6a80f2be0ea3049ad74231b94609242", "4e49ba8c5b6c32ff28cd9dcb60be34df50fcc485", "ecb97df2a174987475ac816e3847fc8e9f6c596b", rootoid); } else if (strcmp(entry->path, "subdir/.gitattributes") == 0) { cases++; check_tree_entry( i, "99eae476896f4907224978b88e5ecaa6c5bb67a9", "9fb40b6675dde60b5697afceae91b66d908c02d9", rootoid, NULL); } else if (strcmp(entry->path, "subdir2/subdir2_test1") == 0) { cases++; check_tree_entry( i, "dccada462d3df8ac6de596fb8c896aba9344f941", "2929de282ce999e95183aedac6451d3384559c4b", rootoid, NULL); } } cl_assert_equal_i(GIT_ITEROVER, error); cl_assert(!entry); cl_assert_equal_i(4, cases); git_iterator_free(i); git_tree_free(t); }
void test_diff_parse__get_patch_from_diff(void) { git_repository *repo; git_diff *computed, *parsed; git_tree *a, *b; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_buf computed_buf = GIT_BUF_INIT; git_patch *patch_computed, *patch_parsed; repo = cl_git_sandbox_init("diff"); opts.flags = GIT_DIFF_SHOW_BINARY; cl_assert((a = resolve_commit_oid_to_tree(repo, "d70d245ed97ed2aa596dd1af6536e4bfdb047b69")) != NULL); cl_assert((b = resolve_commit_oid_to_tree(repo, "7a9e0b02e63179929fed24f0a3e0f19168114d10")) != NULL); cl_git_pass(git_diff_tree_to_tree(&computed, repo, a, b, &opts)); cl_git_pass(git_diff_to_buf(&computed_buf, computed, GIT_DIFF_FORMAT_PATCH)); cl_git_pass(git_patch_from_diff(&patch_computed, computed, 0)); cl_git_pass(git_diff_from_buffer(&parsed, computed_buf.ptr, computed_buf.size)); cl_git_pass(git_patch_from_diff(&patch_parsed, parsed, 0)); cl_assert_equal_i( git_patch_num_hunks(patch_computed), git_patch_num_hunks(patch_parsed)); git_patch_free(patch_computed); git_patch_free(patch_parsed); git_tree_free(a); git_tree_free(b); git_diff_free(computed); git_diff_free(parsed); git_buf_free(&computed_buf); cl_git_sandbox_cleanup(); }
static void test_tree_to_tree_computed_to_parsed( const char *sandbox, const char *a_id, const char *b_id, uint32_t diff_flags, uint32_t find_flags) { git_repository *repo; git_diff *computed, *parsed; git_tree *a, *b; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT; git_buf computed_buf = GIT_BUF_INIT; repo = cl_git_sandbox_init(sandbox); opts.id_abbrev = GIT_OID_HEXSZ; opts.flags = GIT_DIFF_SHOW_BINARY | diff_flags; findopts.flags = find_flags; cl_assert((a = resolve_commit_oid_to_tree(repo, a_id)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(repo, b_id)) != NULL); cl_git_pass(git_diff_tree_to_tree(&computed, repo, a, b, &opts)); if (find_flags) cl_git_pass(git_diff_find_similar(computed, &findopts)); cl_git_pass(git_diff_to_buf(&computed_buf, computed, GIT_DIFF_FORMAT_PATCH)); cl_git_pass(git_diff_from_buffer(&parsed, computed_buf.ptr, computed_buf.size)); diff_assert_equal(computed, parsed); git_tree_free(a); git_tree_free(b); git_diff_free(computed); git_diff_free(parsed); git_buf_free(&computed_buf); cl_git_sandbox_cleanup(); }
void test_diff_tree__merge(void) { /* grabbed a couple of commit oids from the history of the attr repo */ const char *a_commit = "605812a"; const char *b_commit = "370fe9ec22"; const char *c_commit = "f5b0af1fb4f5c"; git_tree *c; git_diff *diff1 = NULL, *diff2 = NULL; g_repo = cl_git_sandbox_init("attr"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL); cl_git_pass(git_diff_tree_to_tree(&diff1, g_repo, a, b, NULL)); cl_git_pass(git_diff_tree_to_tree(&diff2, g_repo, c, b, NULL)); git_tree_free(c); cl_git_pass(git_diff_merge(diff1, diff2)); git_diff_free(diff2); cl_git_pass(git_diff_foreach( diff1, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect)); cl_assert_equal_i(6, expect.files); cl_assert_equal_i(2, expect.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(1, expect.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(3, expect.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(6, expect.hunks); cl_assert_equal_i(59, expect.lines); cl_assert_equal_i(1, expect.line_ctxt); cl_assert_equal_i(36, expect.line_adds); cl_assert_equal_i(22, expect.line_dels); git_diff_free(diff1); }
void test_diff_tree__checks_options_version(void) { const char *a_commit = "8496071c1b46c85"; const char *b_commit = "be3563ae3f79"; const git_error *err; g_repo = cl_git_sandbox_init("testrepo.git"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); opts.version = 0; cl_git_fail(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts)); err = giterr_last(); cl_assert_equal_i(GITERR_INVALID, err->klass); giterr_clear(); opts.version = 1024; cl_git_fail(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts)); err = giterr_last(); }
void test_diff_tree__bare(void) { const char *a_commit = "8496071c1b46c85"; const char *b_commit = "be3563ae3f79"; git_tree *a, *b; git_diff_options opts = {0}; git_diff_list *diff = NULL; diff_expects exp; g_repo = cl_git_sandbox_init("testrepo.git"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); opts.context_lines = 1; opts.interhunk_lines = 1; memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, a, b, &diff)); cl_git_pass(git_diff_foreach( diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); cl_assert(exp.files == 3); cl_assert(exp.file_adds == 2); cl_assert(exp.file_dels == 0); cl_assert(exp.file_mods == 1); cl_assert(exp.hunks == 3); cl_assert(exp.lines == 4); cl_assert(exp.line_ctxt == 0); cl_assert(exp.line_adds == 3); cl_assert(exp.line_dels == 1); git_diff_list_free(diff); git_tree_free(a); git_tree_free(b); }
void test_diff_tree__issue_1397(void) { /* this test shows that it is not needed */ g_repo = cl_git_sandbox_init("issue_1397"); cl_repo_set_bool(g_repo, "core.autocrlf", true); cl_assert((a = resolve_commit_oid_to_tree(g_repo, "8a7ef04")) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, "7f483a7")) != NULL); cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts)); cl_git_pass(git_diff_foreach(diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect)); cl_assert_equal_i(1, expect.files); cl_assert_equal_i(0, expect.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(1, expect.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(0, expect.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(0, expect.file_status[GIT_DELTA_TYPECHANGE]); }
static void tree_iterator_test( const char *sandbox, const char *treeish, const char *start, const char *end, int expected_count, const char **expected_values) { git_tree *t; git_iterator *i; git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT; const git_index_entry *entry; int error, count = 0, count_post_reset = 0; git_repository *repo = cl_git_sandbox_init(sandbox); i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE; i_opts.start = start; i_opts.end = end; cl_assert(t = resolve_commit_oid_to_tree(repo, treeish)); cl_git_pass(git_iterator_for_tree(&i, t, &i_opts)); /* test loop */ while (!(error = git_iterator_advance(&entry, i))) { cl_assert(entry); if (expected_values != NULL) cl_assert_equal_s(expected_values[count], entry->path); count++; } cl_assert_equal_i(GIT_ITEROVER, error); cl_assert(!entry); cl_assert_equal_i(expected_count, count); /* test reset */ cl_git_pass(git_iterator_reset(i, NULL, NULL)); while (!(error = git_iterator_advance(&entry, i))) { cl_assert(entry); if (expected_values != NULL) cl_assert_equal_s(expected_values[count_post_reset], entry->path); count_post_reset++; } cl_assert_equal_i(GIT_ITEROVER, error); cl_assert(!entry); cl_assert_equal_i(count, count_post_reset); git_iterator_free(i); git_tree_free(t); }
void test_diff_index__checks_options_version(void) { const char *a_commit = "26a125ee1bf"; git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit); git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_diff *diff = NULL; const git_error *err; opts.version = 0; cl_git_fail(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts)); err = giterr_last(); cl_assert_equal_i(GITERR_INVALID, err->klass); cl_assert_equal_p(diff, NULL); giterr_clear(); opts.version = 1024; cl_git_fail(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts)); err = giterr_last(); cl_assert_equal_i(GITERR_INVALID, err->klass); cl_assert_equal_p(diff, NULL); git_tree_free(a); }
static void do_conflicted_diff(diff_expects *exp, unsigned long flags) { const char *a_commit = "26a125ee1bf"; /* the current HEAD */ git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit); git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_index_entry ancestor = {{0}}, ours = {{0}}, theirs = {{0}}; git_diff *diff = NULL; git_index *index; cl_assert(a); opts.context_lines = 1; opts.interhunk_lines = 1; opts.flags |= flags; memset(exp, 0, sizeof(diff_expects)); cl_git_pass(git_repository_index(&index, g_repo)); ancestor.path = ours.path = theirs.path = "staged_changes"; ancestor.mode = ours.mode = theirs.mode = GIT_FILEMODE_BLOB; git_oid_fromstr(&ancestor.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); git_oid_fromstr(&ours.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); git_oid_fromstr(&theirs.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); cl_git_pass(git_index_conflict_add(index, &ancestor, &ours, &theirs)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, index, &opts)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, exp)); git_diff_free(diff); git_tree_free(a); git_index_free(index); }
void test_diff_workdir__head_index_and_workdir_all_differ(void) { git_diff_options opts = {0}; git_diff_list *diff_i2t = NULL, *diff_w2i = NULL; diff_expects exp; char *pathspec = "staged_changes_modified_file"; git_tree *tree; int use_iterator; /* For this file, * - head->index diff has 1 line of context, 1 line of diff * - index->workdir diff has 2 lines of context, 1 line of diff * but * - head->workdir diff has 1 line of context, 2 lines of diff * Let's make sure the right one is returned from each fn. */ g_repo = cl_git_sandbox_init("status"); tree = resolve_commit_oid_to_tree(g_repo, "26a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f"); opts.pathspec.strings = &pathspec; opts.pathspec.count = 1; cl_git_pass(git_diff_index_to_tree(g_repo, &opts, tree, &diff_i2t)); cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff_w2i)); for (use_iterator = 0; use_iterator <= 1; use_iterator++) { memset(&exp, 0, sizeof(exp)); if (use_iterator) cl_git_pass(diff_foreach_via_iterator( diff_i2t, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); else cl_git_pass(git_diff_foreach( diff_i2t, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); cl_assert_equal_i(1, exp.files); cl_assert_equal_i(0, exp.file_adds); cl_assert_equal_i(0, exp.file_dels); cl_assert_equal_i(1, exp.file_mods); cl_assert_equal_i(1, exp.hunks); cl_assert_equal_i(2, exp.lines); cl_assert_equal_i(1, exp.line_ctxt); cl_assert_equal_i(1, exp.line_adds); cl_assert_equal_i(0, exp.line_dels); } for (use_iterator = 0; use_iterator <= 1; use_iterator++) { memset(&exp, 0, sizeof(exp)); if (use_iterator) cl_git_pass(diff_foreach_via_iterator( diff_w2i, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); else cl_git_pass(git_diff_foreach( diff_w2i, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); cl_assert_equal_i(1, exp.files); cl_assert_equal_i(0, exp.file_adds); cl_assert_equal_i(0, exp.file_dels); cl_assert_equal_i(1, exp.file_mods); cl_assert_equal_i(1, exp.hunks); cl_assert_equal_i(3, exp.lines); cl_assert_equal_i(2, exp.line_ctxt); cl_assert_equal_i(1, exp.line_adds); cl_assert_equal_i(0, exp.line_dels); } cl_git_pass(git_diff_merge(diff_i2t, diff_w2i)); for (use_iterator = 0; use_iterator <= 1; use_iterator++) { memset(&exp, 0, sizeof(exp)); if (use_iterator) cl_git_pass(diff_foreach_via_iterator( diff_i2t, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); else cl_git_pass(git_diff_foreach( diff_i2t, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); cl_assert_equal_i(1, exp.files); cl_assert_equal_i(0, exp.file_adds); cl_assert_equal_i(0, exp.file_dels); cl_assert_equal_i(1, exp.file_mods); cl_assert_equal_i(1, exp.hunks); cl_assert_equal_i(3, exp.lines); cl_assert_equal_i(1, exp.line_ctxt); cl_assert_equal_i(2, exp.line_adds); cl_assert_equal_i(0, exp.line_dels); } git_diff_list_free(diff_i2t); git_diff_list_free(diff_w2i); git_tree_free(tree); }
void test_diff_tree__0(void) { /* grabbed a couple of commit oids from the history of the attr repo */ const char *a_commit = "605812a"; const char *b_commit = "370fe9ec22"; const char *c_commit = "f5b0af1fb4f5c"; git_tree *a, *b, *c; git_diff_options opts = {0}; git_diff_list *diff = NULL; diff_expects exp; g_repo = cl_git_sandbox_init("attr"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL); opts.context_lines = 1; opts.interhunk_lines = 1; memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, a, b, &diff)); cl_git_pass(git_diff_foreach( diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); cl_assert(exp.files == 5); cl_assert(exp.file_adds == 2); cl_assert(exp.file_dels == 1); cl_assert(exp.file_mods == 2); cl_assert(exp.hunks == 5); cl_assert(exp.lines == 7 + 24 + 1 + 6 + 6); cl_assert(exp.line_ctxt == 1); cl_assert(exp.line_adds == 24 + 1 + 5 + 5); cl_assert(exp.line_dels == 7 + 1); git_diff_list_free(diff); diff = NULL; memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, c, b, &diff)); cl_git_pass(git_diff_foreach( diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); cl_assert(exp.files == 2); cl_assert(exp.file_adds == 0); cl_assert(exp.file_dels == 0); cl_assert(exp.file_mods == 2); cl_assert(exp.hunks == 2); cl_assert(exp.lines == 8 + 15); cl_assert(exp.line_ctxt == 1); cl_assert(exp.line_adds == 1); cl_assert(exp.line_dels == 7 + 14); git_diff_list_free(diff); git_tree_free(a); git_tree_free(b); git_tree_free(c); }
void test_diff_index__0(void) { /* grabbed a couple of commit oids from the history of the attr repo */ const char *a_commit = "26a125ee1bf"; /* the current HEAD */ const char *b_commit = "0017bd4ab1ec3"; /* the start */ git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit); git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit); git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_diff *diff = NULL; diff_expects exp; cl_assert(a); cl_assert(b); opts.context_lines = 1; opts.interhunk_lines = 1; memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp)); /* to generate these values: * - cd to tests/resources/status, * - mv .gitted .git * - git diff --name-status --cached 26a125ee1bf * - git diff -U1 --cached 26a125ee1bf * - mv .git .gitted */ cl_assert_equal_i(8, exp.files); cl_assert_equal_i(3, exp.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(8, exp.hunks); cl_assert_equal_i(11, exp.lines); cl_assert_equal_i(3, exp.line_ctxt); cl_assert_equal_i(6, exp.line_adds); cl_assert_equal_i(2, exp.line_dels); git_diff_free(diff); diff = NULL; memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, b, NULL, &opts)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp)); /* to generate these values: * - cd to tests/resources/status, * - mv .gitted .git * - git diff --name-status --cached 0017bd4ab1ec3 * - git diff -U1 --cached 0017bd4ab1ec3 * - mv .git .gitted */ cl_assert_equal_i(12, exp.files); cl_assert_equal_i(7, exp.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(12, exp.hunks); cl_assert_equal_i(16, exp.lines); cl_assert_equal_i(3, exp.line_ctxt); cl_assert_equal_i(11, exp.line_adds); cl_assert_equal_i(2, exp.line_dels); git_diff_free(diff); diff = NULL; git_tree_free(a); git_tree_free(b); }
void test_diff_workdir__to_tree(void) { /* grabbed a couple of commit oids from the history of the attr repo */ const char *a_commit = "26a125ee1bf"; /* the current HEAD */ const char *b_commit = "0017bd4ab1ec3"; /* the start */ git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit); git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit); git_diff_options opts = {0}; git_diff_list *diff = NULL; git_diff_list *diff2 = NULL; diff_expects exp; opts.context_lines = 3; opts.interhunk_lines = 1; opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED; memset(&exp, 0, sizeof(exp)); /* You can't really generate the equivalent of git_diff_workdir_to_tree() * using C git. It really wants to interpose the index into the diff. * * To validate the following results with command line git, I ran the * following: * - git ls-tree 26a125 * - find . ! -path ./.git/\* -a -type f | git hash-object --stdin-paths * The results are documented at the bottom of this file in the * long comment entitled "PREPARATION OF TEST DATA". */ cl_git_pass(git_diff_workdir_to_tree(g_repo, &opts, a, &diff)); cl_git_pass(git_diff_foreach( diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); cl_assert(exp.files == 13); cl_assert(exp.file_adds == 0); cl_assert(exp.file_dels == 4); cl_assert(exp.file_mods == 4); cl_assert(exp.file_ignored == 1); cl_assert(exp.file_untracked == 4); /* Since there is no git diff equivalent, let's just assume that the * text diffs produced by git_diff_foreach are accurate here. We will * do more apples-to-apples test comparison below. */ git_diff_list_free(diff); diff = NULL; memset(&exp, 0, sizeof(exp)); /* This is a compatible emulation of "git diff <sha>" which looks like * a workdir to tree diff (even though it is not really). This is what * you would get from "git diff --name-status 26a125ee1bf" */ cl_git_pass(git_diff_index_to_tree(g_repo, &opts, a, &diff)); cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff2)); cl_git_pass(git_diff_merge(diff, diff2)); git_diff_list_free(diff2); cl_git_pass(git_diff_foreach( diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); cl_assert(exp.files == 14); cl_assert(exp.file_adds == 2); cl_assert(exp.file_dels == 5); cl_assert(exp.file_mods == 4); cl_assert(exp.file_ignored == 1); cl_assert(exp.file_untracked == 2); cl_assert(exp.hunks == 11); cl_assert(exp.lines == 17); cl_assert(exp.line_ctxt == 4); cl_assert(exp.line_adds == 8); cl_assert(exp.line_dels == 5); git_diff_list_free(diff); diff = NULL; memset(&exp, 0, sizeof(exp)); /* Again, emulating "git diff <sha>" for testing purposes using * "git diff --name-status 0017bd4ab1ec3" instead. */ cl_git_pass(git_diff_index_to_tree(g_repo, &opts, b, &diff)); cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff2)); cl_git_pass(git_diff_merge(diff, diff2)); git_diff_list_free(diff2); cl_git_pass(git_diff_foreach( diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn)); cl_assert(exp.files == 15); cl_assert(exp.file_adds == 5); cl_assert(exp.file_dels == 4); cl_assert(exp.file_mods == 3); cl_assert(exp.file_ignored == 1); cl_assert(exp.file_untracked == 2); cl_assert(exp.hunks == 12); cl_assert(exp.lines == 19); cl_assert(exp.line_ctxt == 3); cl_assert(exp.line_adds == 12); cl_assert(exp.line_dels == 4); git_diff_list_free(diff); git_tree_free(a); git_tree_free(b); }
void test_diff_tree__options(void) { /* grabbed a couple of commit oids from the history of the attr repo */ const char *a_commit = "6bab5c79cd5140d0"; const char *b_commit = "605812ab7fe421fdd"; const char *c_commit = "f5b0af1fb4f5"; const char *d_commit = "a97cc019851"; git_tree *a, *b, *c, *d; git_diff_options opts = {0}; git_diff_list *diff = NULL; diff_expects actual; int test_ab_or_cd[] = { 0, 0, 0, 0, 1, 1, 1, 1, 1 }; git_diff_options test_options[] = { /* a vs b tests */ { GIT_DIFF_NORMAL, 1, 1, NULL, NULL, {0} }, { GIT_DIFF_NORMAL, 3, 1, NULL, NULL, {0} }, { GIT_DIFF_REVERSE, 2, 1, NULL, NULL, {0} }, { GIT_DIFF_FORCE_TEXT, 2, 1, NULL, NULL, {0} }, /* c vs d tests */ { GIT_DIFF_NORMAL, 3, 1, NULL, NULL, {0} }, { GIT_DIFF_IGNORE_WHITESPACE, 3, 1, NULL, NULL, {0} }, { GIT_DIFF_IGNORE_WHITESPACE_CHANGE, 3, 1, NULL, NULL, {0} }, { GIT_DIFF_IGNORE_WHITESPACE_EOL, 3, 1, NULL, NULL, {0} }, { GIT_DIFF_IGNORE_WHITESPACE | GIT_DIFF_REVERSE, 1, 1, NULL, NULL, {0} }, }; /* to generate these values: * - cd to tests/resources/attr, * - mv .gitted .git * - git diff [options] 6bab5c79cd5140d0 605812ab7fe421fdd * - mv .git .gitted */ diff_expects test_expects[] = { /* a vs b tests */ { 5, 3, 0, 2, 0, 0, 0, 4, 0, 0, 51, 2, 46, 3 }, { 5, 3, 0, 2, 0, 0, 0, 4, 0, 0, 53, 4, 46, 3 }, { 5, 0, 3, 2, 0, 0, 0, 4, 0, 0, 52, 3, 3, 46 }, { 5, 3, 0, 2, 0, 0, 0, 5, 0, 0, 54, 3, 48, 3 }, /* c vs d tests */ { 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 22, 9, 10, 3 }, { 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 19, 12, 7, 0 }, { 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 20, 11, 8, 1 }, { 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 20, 11, 8, 1 }, { 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 18, 11, 0, 7 }, { 0 }, }; diff_expects *expected; int i; g_repo = cl_git_sandbox_init("attr"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL); cl_assert((d = resolve_commit_oid_to_tree(g_repo, d_commit)) != NULL); for (i = 0; test_expects[i].files > 0; i++) { memset(&actual, 0, sizeof(actual)); /* clear accumulator */ opts = test_options[i]; if (test_ab_or_cd[i] == 0) cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, a, b, &diff)); else cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, c, d, &diff)); cl_git_pass(git_diff_foreach( diff, &actual, diff_file_fn, diff_hunk_fn, diff_line_fn)); expected = &test_expects[i]; cl_assert_equal_i(actual.files, expected->files); cl_assert_equal_i(actual.file_adds, expected->file_adds); cl_assert_equal_i(actual.file_dels, expected->file_dels); cl_assert_equal_i(actual.file_mods, expected->file_mods); cl_assert_equal_i(actual.hunks, expected->hunks); cl_assert_equal_i(actual.lines, expected->lines); cl_assert_equal_i(actual.line_ctxt, expected->line_ctxt); cl_assert_equal_i(actual.line_adds, expected->line_adds); cl_assert_equal_i(actual.line_dels, expected->line_dels); git_diff_list_free(diff); diff = NULL; } git_tree_free(a); git_tree_free(b); git_tree_free(c); git_tree_free(d); }
void test_diff_drivers__patterns(void) { git_config *cfg; const char *one_sha = "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13"; git_tree *one; git_diff_list *diff; git_diff_patch *patch; char *text; const char *expected0 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Comes through the blood of the vanguards who\n dreamed--too soon--it had sounded.\r\n \r\n -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n"; const char *expected1 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\nBinary files a/untimely.txt and b/untimely.txt differ\n"; const char *expected2 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Heaven delivers on earth the Hour that cannot be\n dreamed--too soon--it had sounded.\r\n \r\n -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n"; g_repo = cl_git_sandbox_init("renames"); one = resolve_commit_oid_to_tree(g_repo, one_sha); /* no diff */ cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL)); cl_assert_equal_i(0, (int)git_diff_num_deltas(diff)); git_diff_list_free(diff); /* default diff */ cl_git_append2file("renames/untimely.txt", "\r\nSome new stuff\r\n"); cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL)); cl_assert_equal_i(1, (int)git_diff_num_deltas(diff)); cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0)); cl_git_pass(git_diff_patch_to_str(&text, patch)); cl_assert_equal_s(expected0, text); git__free(text); git_diff_patch_free(patch); git_diff_list_free(diff); /* attribute diff set to false */ cl_git_rewritefile("renames/.gitattributes", "untimely.txt -diff\n"); cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL)); cl_assert_equal_i(1, (int)git_diff_num_deltas(diff)); cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0)); cl_git_pass(git_diff_patch_to_str(&text, patch)); cl_assert_equal_s(expected1, text); git__free(text); git_diff_patch_free(patch); git_diff_list_free(diff); /* attribute diff set to unconfigured value (should use default) */ cl_git_rewritefile("renames/.gitattributes", "untimely.txt diff=kipling0\n"); cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL)); cl_assert_equal_i(1, (int)git_diff_num_deltas(diff)); cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0)); cl_git_pass(git_diff_patch_to_str(&text, patch)); cl_assert_equal_s(expected0, text); git__free(text); git_diff_patch_free(patch); git_diff_list_free(diff); /* let's define that driver */ cl_git_pass(git_repository_config(&cfg, g_repo)); cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 1)); git_config_free(cfg); cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL)); cl_assert_equal_i(1, (int)git_diff_num_deltas(diff)); cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0)); cl_git_pass(git_diff_patch_to_str(&text, patch)); cl_assert_equal_s(expected1, text); git__free(text); git_diff_patch_free(patch); git_diff_list_free(diff); /* let's use a real driver with some regular expressions */ git_diff_driver_registry_free(g_repo->diff_drivers); g_repo->diff_drivers = NULL; cl_git_pass(git_repository_config(&cfg, g_repo)); cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 0)); cl_git_pass(git_config_set_string(cfg, "diff.kipling0.xfuncname", "^H")); git_config_free(cfg); cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL)); cl_assert_equal_i(1, (int)git_diff_num_deltas(diff)); cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0)); cl_git_pass(git_diff_patch_to_str(&text, patch)); cl_assert_equal_s(expected2, text); git__free(text); git_diff_patch_free(patch); git_diff_list_free(diff); git_tree_free(one); }
void test_diff_tree__options(void) { /* grabbed a couple of commit oids from the history of the attr repo */ const char *a_commit = "6bab5c79cd5140d0"; const char *b_commit = "605812ab7fe421fdd"; const char *c_commit = "f5b0af1fb4f5"; const char *d_commit = "a97cc019851"; git_tree *c, *d; diff_expects actual; int test_ab_or_cd[] = { 0, 0, 0, 0, 1, 1, 1, 1, 1 }; git_diff_options test_options[] = { /* a vs b tests */ DIFF_OPTS(GIT_DIFF_NORMAL, 1), DIFF_OPTS(GIT_DIFF_NORMAL, 3), DIFF_OPTS(GIT_DIFF_REVERSE, 2), DIFF_OPTS(GIT_DIFF_FORCE_TEXT, 2), /* c vs d tests */ DIFF_OPTS(GIT_DIFF_NORMAL, 3), DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE, 3), DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE_CHANGE, 3), DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE_EOL, 3), DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE | GIT_DIFF_REVERSE, 1), }; /* to generate these values: * - cd to tests/resources/attr, * - mv .gitted .git * - git diff [options] 6bab5c79cd5140d0 605812ab7fe421fdd * - mv .git .gitted */ #define EXPECT_STATUS_ADM(ADDS,DELS,MODS) { 0, ADDS, DELS, MODS, 0, 0, 0, 0, 0 } diff_expects test_expects[] = { /* a vs b tests */ { 5, 0, EXPECT_STATUS_ADM(3, 0, 2), 4, 0, 0, 51, 2, 46, 3 }, { 5, 0, EXPECT_STATUS_ADM(3, 0, 2), 4, 0, 0, 53, 4, 46, 3 }, { 5, 0, EXPECT_STATUS_ADM(0, 3, 2), 4, 0, 0, 52, 3, 3, 46 }, { 5, 0, EXPECT_STATUS_ADM(3, 0, 2), 5, 0, 0, 54, 3, 47, 4 }, /* c vs d tests */ { 1, 0, EXPECT_STATUS_ADM(0, 0, 1), 1, 0, 0, 22, 9, 10, 3 }, { 1, 0, EXPECT_STATUS_ADM(0, 0, 1), 1, 0, 0, 19, 12, 7, 0 }, { 1, 0, EXPECT_STATUS_ADM(0, 0, 1), 1, 0, 0, 20, 11, 8, 1 }, { 1, 0, EXPECT_STATUS_ADM(0, 0, 1), 1, 0, 0, 20, 11, 8, 1 }, { 1, 0, EXPECT_STATUS_ADM(0, 0, 1), 1, 0, 0, 18, 11, 0, 7 }, { 0 }, }; diff_expects *expected; int i, j; g_repo = cl_git_sandbox_init("attr"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL); cl_assert((d = resolve_commit_oid_to_tree(g_repo, d_commit)) != NULL); for (i = 0; test_expects[i].files > 0; i++) { memset(&actual, 0, sizeof(actual)); /* clear accumulator */ opts = test_options[i]; if (test_ab_or_cd[i] == 0) cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts)); else cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, c, d, &opts)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &actual)); expected = &test_expects[i]; cl_assert_equal_i(actual.files, expected->files); for (j = GIT_DELTA_UNMODIFIED; j <= GIT_DELTA_TYPECHANGE; ++j) cl_assert_equal_i(expected->file_status[j], actual.file_status[j]); cl_assert_equal_i(actual.hunks, expected->hunks); cl_assert_equal_i(actual.lines, expected->lines); cl_assert_equal_i(actual.line_ctxt, expected->line_ctxt); cl_assert_equal_i(actual.line_adds, expected->line_adds); cl_assert_equal_i(actual.line_dels, expected->line_dels); git_diff_free(diff); diff = NULL; } git_tree_free(c); git_tree_free(d); }
void test_diff_tree__diff_configs(void) { const char *a_commit = "d70d245e"; const char *b_commit = "7a9e0b02"; g_repo = cl_git_sandbox_init("diff"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, NULL)); cl_git_pass(git_diff_foreach(diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect)); cl_assert_equal_i(2, expect.files); cl_assert_equal_i(2, expect.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(6, expect.hunks); cl_assert_equal_i(55, expect.lines); cl_assert_equal_i(33, expect.line_ctxt); cl_assert_equal_i(7, expect.line_adds); cl_assert_equal_i(15, expect.line_dels); git_diff_free(diff); diff = NULL; set_config_int(g_repo, "diff.context", 1); memset(&expect, 0, sizeof(expect)); cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, NULL)); cl_git_pass(git_diff_foreach(diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect)); cl_assert_equal_i(2, expect.files); cl_assert_equal_i(2, expect.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(7, expect.hunks); cl_assert_equal_i(34, expect.lines); cl_assert_equal_i(12, expect.line_ctxt); cl_assert_equal_i(7, expect.line_adds); cl_assert_equal_i(15, expect.line_dels); git_diff_free(diff); diff = NULL; set_config_int(g_repo, "diff.context", 0); set_config_int(g_repo, "diff.noprefix", 1); memset(&expect, 0, sizeof(expect)); cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, NULL)); cl_git_pass(git_diff_foreach(diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect)); cl_assert_equal_i(2, expect.files); cl_assert_equal_i(2, expect.file_status[GIT_DELTA_MODIFIED]); cl_assert_equal_i(7, expect.hunks); cl_assert_equal_i(22, expect.lines); cl_assert_equal_i(0, expect.line_ctxt); cl_assert_equal_i(7, expect.line_adds); cl_assert_equal_i(15, expect.line_dels); }
void test_diff_workdir__larger_hunks(void) { const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69"; const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10"; git_tree *a, *b; git_diff_options opts = {0}; size_t i, d, num_d, h, num_h, l, num_l, header_len, line_len; g_repo = cl_git_sandbox_init("diff"); cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL); cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL); opts.context_lines = 1; opts.interhunk_lines = 0; for (i = 0; i <= 2; ++i) { git_diff_list *diff = NULL; git_diff_patch *patch; const git_diff_range *range; const char *header, *line; char origin; /* okay, this is a bit silly, but oh well */ switch (i) { case 0: cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff)); break; case 1: cl_git_pass(git_diff_workdir_to_tree(g_repo, &opts, a, &diff)); break; case 2: cl_git_pass(git_diff_workdir_to_tree(g_repo, &opts, b, &diff)); break; } num_d = git_diff_num_deltas(diff); cl_assert_equal_i(2, (int)num_d); for (d = 0; d < num_d; ++d) { cl_git_pass(git_diff_get_patch(&patch, NULL, diff, d)); cl_assert(patch); num_h = git_diff_patch_num_hunks(patch); for (h = 0; h < num_h; h++) { cl_git_pass(git_diff_patch_get_hunk( &range, &header, &header_len, &num_l, patch, h)); for (l = 0; l < num_l; ++l) { cl_git_pass(git_diff_patch_get_line_in_hunk( &origin, &line, &line_len, NULL, NULL, patch, h, l)); cl_assert(line); } /* confirm fail after the last item */ cl_git_fail(git_diff_patch_get_line_in_hunk( &origin, &line, &line_len, NULL, NULL, patch, h, num_l)); } /* confirm fail after the last item */ cl_git_fail(git_diff_patch_get_hunk( &range, &header, &header_len, &num_l, patch, num_h)); git_diff_patch_free(patch); } git_diff_list_free(diff); } git_tree_free(a); git_tree_free(b); }