diff --git a/src/diff_output.c b/src/diff_output.c index 788c8b8f0..dbcc89fa5 100644 --- a/src/diff_output.c +++ b/src/diff_output.c @@ -686,7 +686,6 @@ int git_diff_print_patch( return error; } - int git_diff_blobs( git_blob *old_blob, git_blob *new_blob, @@ -701,44 +700,43 @@ int git_diff_blobs( xpparam_t xdiff_params; xdemitconf_t xdiff_config; xdemitcb_t xdiff_callback; + git_blob *new, *old; + + memset(&delta, 0, sizeof(delta)); + + new = new_blob; + old = old_blob; if (options && (options->flags & GIT_DIFF_REVERSE)) { - git_blob *swap = old_blob; - old_blob = new_blob; - new_blob = swap; + git_blob *swap = old; + old = new; + new = swap; } - if (old_blob) { - old_data.ptr = (char *)git_blob_rawcontent(old_blob); - old_data.size = git_blob_rawsize(old_blob); + if (old) { + old_data.ptr = (char *)git_blob_rawcontent(old); + old_data.size = git_blob_rawsize(old); + git_oid_cpy(&delta.old_file.oid, git_object_id((const git_object *)old)); } else { old_data.ptr = ""; old_data.size = 0; } - if (new_blob) { - new_data.ptr = (char *)git_blob_rawcontent(new_blob); - new_data.size = git_blob_rawsize(new_blob); + if (new) { + new_data.ptr = (char *)git_blob_rawcontent(new); + new_data.size = git_blob_rawsize(new); + git_oid_cpy(&delta.new_file.oid, git_object_id((const git_object *)new)); } else { new_data.ptr = ""; new_data.size = 0; } /* populate a "fake" delta record */ - delta.status = old_data.ptr ? - (new_data.ptr ? GIT_DELTA_MODIFIED : GIT_DELTA_DELETED) : - (new_data.ptr ? GIT_DELTA_ADDED : GIT_DELTA_UNTRACKED); - delta.old_file.mode = 0000000; /* can't know the truth from a blob alone */ - delta.new_file.mode = 0000000; - git_oid_cpy(&delta.old_file.oid, git_object_id((const git_object *)old_blob)); - git_oid_cpy(&delta.new_file.oid, git_object_id((const git_object *)new_blob)); - delta.old_file.path = NULL; - delta.new_file.path = NULL; + delta.status = new ? + (old ? GIT_DELTA_MODIFIED : GIT_DELTA_ADDED) : + (old ? GIT_DELTA_DELETED : GIT_DELTA_UNTRACKED); delta.old_file.size = old_data.size; delta.new_file.size = new_data.size; - delta.old_file.flags = 0; - delta.new_file.flags = 0; - delta.similarity = 0; info.diff = NULL; info.delta = δ diff --git a/tests-clar/diff/blob.c b/tests-clar/diff/blob.c index 65b350005..9364bdc6d 100644 --- a/tests-clar/diff/blob.c +++ b/tests-clar/diff/blob.c @@ -2,23 +2,38 @@ #include "diff_helpers.h" static git_repository *g_repo = NULL; +static diff_expects exp; +static git_diff_options opts; +static git_blob *d; void test_diff_blob__initialize(void) { + git_oid d_oid; + g_repo = cl_git_sandbox_init("attr"); + + memset(&opts, 0, sizeof(opts)); + opts.context_lines = 1; + opts.interhunk_lines = 1; + + memset(&exp, 0, sizeof(exp)); + + /* tests/resources/attr/root_test4.txt */ + cl_git_pass(git_oid_fromstrn(&d_oid, "fe773770c5a6", 12)); + cl_git_pass(git_blob_lookup_prefix(&d, g_repo, &d_oid, 6)); } void test_diff_blob__cleanup(void) { + git_blob_free(d); + cl_git_sandbox_cleanup(); } void test_diff_blob__can_compare_text_blobs(void) { - git_blob *a, *b, *c, *d; - git_oid a_oid, b_oid, c_oid, d_oid; - git_diff_options opts = {0}; - diff_expects exp; + git_blob *a, *b, *c; + git_oid a_oid, b_oid, c_oid; /* tests/resources/attr/root_test1 */ cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8)); @@ -32,16 +47,8 @@ void test_diff_blob__can_compare_text_blobs(void) cl_git_pass(git_oid_fromstrn(&c_oid, "c96bbb2c2557a832", 16)); cl_git_pass(git_blob_lookup_prefix(&c, g_repo, &c_oid, 8)); - /* tests/resources/attr/root_test4.txt */ - cl_git_pass(git_oid_fromstrn(&d_oid, "fe773770c5a6", 12)); - cl_git_pass(git_blob_lookup_prefix(&d, g_repo, &d_oid, 6)); - /* Doing the equivalent of a `git diff -U1` on these files */ - opts.context_lines = 1; - opts.interhunk_lines = 1; - - memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_blobs( a, b, &opts, &exp, diff_hunk_fn, diff_line_fn)); @@ -86,6 +93,28 @@ void test_diff_blob__can_compare_text_blobs(void) git_blob_free(a); git_blob_free(b); git_blob_free(c); - git_blob_free(d); } +void test_diff_blob__can_compare_against_null_blobs(void) +{ + git_blob *e = NULL; + + cl_git_pass(git_diff_blobs( + d, e, &opts, &exp, diff_hunk_fn, diff_line_fn)); + + cl_assert(exp.hunks == 1); + cl_assert(exp.hunk_old_lines == 14); + cl_assert(exp.lines == 14); + cl_assert(exp.line_dels == 14); + + opts.flags |= GIT_DIFF_REVERSE; + memset(&exp, 0, sizeof(exp)); + + cl_git_pass(git_diff_blobs( + d, e, &opts, &exp, diff_hunk_fn, diff_line_fn)); + + cl_assert(exp.hunks == 1); + cl_assert(exp.hunk_new_lines == 14); + cl_assert(exp.lines == 14); + cl_assert(exp.line_adds == 14); +}