diff: fix the diffing of a concrete blob against a null one
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
diff --git a/src/diff_output.c b/src/diff_output.c
index 788c8b8..dbcc89f 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 65b3500..9364bdc 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);
+}