diff: for conflicts w/o workdir, blank nitem side Make sure that we provide a blanked nitem side when the item does not exist in the working directory.
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
diff --git a/src/diff.c b/src/diff.c
index 765956a..c061a90 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -77,11 +77,24 @@ static int diff_insert_delta(
static int diff_delta__from_one(
git_diff *diff,
git_delta_t status,
- const git_index_entry *entry)
+ const git_index_entry *oitem,
+ const git_index_entry *nitem)
{
+ const git_index_entry *entry = nitem;
+ bool has_old = false;
git_diff_delta *delta;
const char *matched_pathspec;
+ assert((oitem != NULL) ^ (nitem != NULL));
+
+ if (oitem) {
+ entry = oitem;
+ has_old = true;
+ }
+
+ if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_REVERSE))
+ has_old = !has_old;
+
if ((entry->flags & GIT_IDXENTRY_VALID) != 0)
return 0;
@@ -111,7 +124,7 @@ static int diff_delta__from_one(
assert(status != GIT_DELTA_MODIFIED);
delta->nfiles = 1;
- if (delta->status == GIT_DELTA_DELETED) {
+ if (has_old) {
delta->old_file.mode = entry->mode;
delta->old_file.size = entry->file_size;
git_oid_cpy(&delta->old_file.id, &entry->id);
@@ -123,8 +136,7 @@ static int diff_delta__from_one(
delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID;
- if (delta->status == GIT_DELTA_DELETED ||
- !git_oid_iszero(&delta->new_file.id))
+ if (has_old || !git_oid_iszero(&delta->new_file.id))
delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
return diff_insert_delta(diff, delta, matched_pathspec);
@@ -764,13 +776,13 @@ static int maybe_modified(
if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE))
status = GIT_DELTA_TYPECHANGE;
else if (nmode == GIT_FILEMODE_UNREADABLE) {
- if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem)))
- error = diff_delta__from_one(diff, GIT_DELTA_UNREADABLE, nitem);
+ if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem, NULL)))
+ error = diff_delta__from_one(diff, GIT_DELTA_UNREADABLE, NULL, nitem);
return error;
}
else {
- if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem)))
- error = diff_delta__from_one(diff, GIT_DELTA_ADDED, nitem);
+ if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem, NULL)))
+ error = diff_delta__from_one(diff, GIT_DELTA_ADDED, NULL, nitem);
return error;
}
}
@@ -850,8 +862,9 @@ static int maybe_modified(
DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_CASECHANGE) &&
strcmp(oitem->path, nitem->path) != 0) {
- if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem)))
- error = diff_delta__from_one(diff, GIT_DELTA_ADDED, nitem);
+ if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem, NULL)))
+ error = diff_delta__from_one(diff, GIT_DELTA_ADDED, NULL, nitem);
+
return error;
}
@@ -1006,7 +1019,7 @@ static int handle_unmatched_new_item(
git_iterator_status_t untracked_state;
/* attempt to insert record for this directory */
- if ((error = diff_delta__from_one(diff, delta_type, nitem)) != 0)
+ if ((error = diff_delta__from_one(diff, delta_type, NULL, nitem)) != 0)
return error;
/* if delta wasn't created (because of rules), just skip ahead */
@@ -1087,7 +1100,7 @@ static int handle_unmatched_new_item(
}
/* Actually create the record for this item if necessary */
- if ((error = diff_delta__from_one(diff, delta_type, nitem)) != 0)
+ if ((error = diff_delta__from_one(diff, delta_type, NULL, nitem)) != 0)
return error;
/* If user requested TYPECHANGE records, then check for that instead of
@@ -1118,7 +1131,7 @@ static int handle_unmatched_old_item(
if (git_index_entry_stage(info->oitem))
delta_type = GIT_DELTA_CONFLICTED;
- if ((error = diff_delta__from_one(diff, delta_type, info->oitem)) < 0)
+ if ((error = diff_delta__from_one(diff, delta_type, info->oitem, NULL)) < 0)
return error;
/* if we are generating TYPECHANGE records then check for that