Commit 74a627f0 by Russell Belfer

Tweak to git_diff_delta structure for nfiles

While the base git_diff_delta structure always contains two files,
when we introduce conflict data, it will be helpful to have an
indicator when an additional file is involved.
parent 10672e3e
...@@ -292,8 +292,9 @@ typedef struct { ...@@ -292,8 +292,9 @@ typedef struct {
*/ */
typedef struct { typedef struct {
git_delta_t status; git_delta_t status;
uint32_t similarity; /**< for RENAMED and COPIED, value 0-100 */ uint32_t flags; /**< git_diff_flag_t values */
uint32_t flags; uint16_t similarity; /**< for RENAMED and COPIED, value 0-100 */
uint16_t nfiles; /**< number of files in this delta */
git_diff_file old_file; git_diff_file old_file;
git_diff_file new_file; git_diff_file new_file;
} git_diff_delta; } git_diff_delta;
......
...@@ -90,6 +90,7 @@ static int diff_delta__from_one( ...@@ -90,6 +90,7 @@ static int diff_delta__from_one(
/* This fn is just for single-sided diffs */ /* This fn is just for single-sided diffs */
assert(status != GIT_DELTA_MODIFIED); assert(status != GIT_DELTA_MODIFIED);
delta->nfiles = 1;
if (delta->status == GIT_DELTA_DELETED) { if (delta->status == GIT_DELTA_DELETED) {
delta->old_file.mode = entry->mode; delta->old_file.mode = entry->mode;
...@@ -148,6 +149,7 @@ static int diff_delta__from_two( ...@@ -148,6 +149,7 @@ static int diff_delta__from_two(
delta = diff_delta__alloc(diff, status, canonical_path); delta = diff_delta__alloc(diff, status, canonical_path);
GITERR_CHECK_ALLOC(delta); GITERR_CHECK_ALLOC(delta);
delta->nfiles = 2;
git_oid_cpy(&delta->old_file.oid, &old_entry->oid); git_oid_cpy(&delta->old_file.oid, &old_entry->oid);
delta->old_file.size = old_entry->file_size; delta->old_file.size = old_entry->file_size;
......
...@@ -350,6 +350,7 @@ static int apply_splits_and_deletes( ...@@ -350,6 +350,7 @@ static int apply_splits_and_deletes(
goto on_error; goto on_error;
deleted->status = GIT_DELTA_DELETED; deleted->status = GIT_DELTA_DELETED;
deleted->nfiles = 1;
memset(&deleted->new_file, 0, sizeof(deleted->new_file)); memset(&deleted->new_file, 0, sizeof(deleted->new_file));
deleted->new_file.path = deleted->old_file.path; deleted->new_file.path = deleted->old_file.path;
deleted->new_file.flags |= GIT_DIFF_FLAG_VALID_OID; deleted->new_file.flags |= GIT_DIFF_FLAG_VALID_OID;
...@@ -361,6 +362,7 @@ static int apply_splits_and_deletes( ...@@ -361,6 +362,7 @@ static int apply_splits_and_deletes(
delta->status = GIT_DELTA_UNTRACKED; delta->status = GIT_DELTA_UNTRACKED;
else else
delta->status = GIT_DELTA_ADDED; delta->status = GIT_DELTA_ADDED;
delta->nfiles = 1;
memset(&delta->old_file, 0, sizeof(delta->old_file)); memset(&delta->old_file, 0, sizeof(delta->old_file));
delta->old_file.path = delta->new_file.path; delta->old_file.path = delta->new_file.path;
delta->old_file.flags |= GIT_DIFF_FLAG_VALID_OID; delta->old_file.flags |= GIT_DIFF_FLAG_VALID_OID;
...@@ -612,7 +614,7 @@ static int calc_self_similarity( ...@@ -612,7 +614,7 @@ static int calc_self_similarity(
return error; return error;
if (similarity >= 0) { if (similarity >= 0) {
delta->similarity = (uint32_t)similarity; delta->similarity = (uint16_t)similarity;
delta->flags |= GIT_DIFF_FLAG__HAS_SELF_SIMILARITY; delta->flags |= GIT_DIFF_FLAG__HAS_SELF_SIMILARITY;
} }
...@@ -745,17 +747,18 @@ GIT_INLINE(bool) delta_is_new_only(git_diff_delta *delta) ...@@ -745,17 +747,18 @@ GIT_INLINE(bool) delta_is_new_only(git_diff_delta *delta)
} }
GIT_INLINE(void) delta_make_rename( GIT_INLINE(void) delta_make_rename(
git_diff_delta *to, const git_diff_delta *from, uint32_t similarity) git_diff_delta *to, const git_diff_delta *from, uint16_t similarity)
{ {
to->status = GIT_DELTA_RENAMED; to->status = GIT_DELTA_RENAMED;
to->similarity = similarity; to->similarity = similarity;
to->nfiles = 2;
memcpy(&to->old_file, &from->old_file, sizeof(to->old_file)); memcpy(&to->old_file, &from->old_file, sizeof(to->old_file));
to->flags &= ~GIT_DIFF_FLAG__TO_SPLIT; to->flags &= ~GIT_DIFF_FLAG__TO_SPLIT;
} }
typedef struct { typedef struct {
uint32_t idx; size_t idx;
uint32_t similarity; uint16_t similarity;
} diff_find_match; } diff_find_match;
int git_diff_find_similar( int git_diff_find_similar(
...@@ -763,7 +766,8 @@ int git_diff_find_similar( ...@@ -763,7 +766,8 @@ int git_diff_find_similar(
const git_diff_find_options *given_opts) const git_diff_find_options *given_opts)
{ {
size_t s, t; size_t s, t;
int error = 0, similarity; int error = 0, result;
uint16_t similarity;
git_diff_delta *src, *tgt; git_diff_delta *src, *tgt;
git_diff_find_options opts; git_diff_find_options opts;
size_t num_deltas, num_srcs = 0, num_tgts = 0; size_t num_deltas, num_srcs = 0, num_tgts = 0;
...@@ -839,17 +843,18 @@ find_best_matches: ...@@ -839,17 +843,18 @@ find_best_matches:
/* calculate similarity for this pair and find best match */ /* calculate similarity for this pair and find best match */
if (s == t) if (s == t)
similarity = -1; /* don't measure self-similarity here */ result = -1; /* don't measure self-similarity here */
else if ((error = similarity_measure( else if ((error = similarity_measure(
&similarity, diff, &opts, sigcache, 2 * s, 2 * t + 1)) < 0) &result, diff, &opts, sigcache, 2 * s, 2 * t + 1)) < 0)
goto cleanup; goto cleanup;
if (similarity < 0) if (result < 0)
continue; continue;
similarity = (uint16_t)result;
/* is this a better rename? */ /* is this a better rename? */
if (tgt2src[t].similarity < (uint32_t)similarity && if (tgt2src[t].similarity < similarity &&
src2tgt[s].similarity < (uint32_t)similarity) src2tgt[s].similarity < similarity)
{ {
/* eject old mapping */ /* eject old mapping */
if (src2tgt[s].similarity > 0) { if (src2tgt[s].similarity > 0) {
...@@ -862,18 +867,18 @@ find_best_matches: ...@@ -862,18 +867,18 @@ find_best_matches:
} }
/* write new mapping */ /* write new mapping */
tgt2src[t].idx = (uint32_t)s; tgt2src[t].idx = s;
tgt2src[t].similarity = (uint32_t)similarity; tgt2src[t].similarity = similarity;
src2tgt[s].idx = (uint32_t)t; src2tgt[s].idx = t;
src2tgt[s].similarity = (uint32_t)similarity; src2tgt[s].similarity = similarity;
} }
/* keep best absolute match for copies */ /* keep best absolute match for copies */
if (tgt2src_copy != NULL && if (tgt2src_copy != NULL &&
tgt2src_copy[t].similarity < (uint32_t)similarity) tgt2src_copy[t].similarity < similarity)
{ {
tgt2src_copy[t].idx = (uint32_t)s; tgt2src_copy[t].idx = s;
tgt2src_copy[t].similarity = (uint32_t)similarity; tgt2src_copy[t].similarity = similarity;
} }
if (++tried_srcs >= num_srcs) if (++tried_srcs >= num_srcs)
...@@ -943,7 +948,7 @@ find_best_matches: ...@@ -943,7 +948,7 @@ find_best_matches:
delta_make_rename(tgt, src, best_match->similarity); delta_make_rename(tgt, src, best_match->similarity);
num_rewrites--; num_rewrites--;
src->status = GIT_DELTA_DELETED; assert(src->status == GIT_DELTA_DELETED);
memcpy(&src->old_file, &swap, sizeof(src->old_file)); memcpy(&src->old_file, &swap, sizeof(src->old_file));
memset(&src->new_file, 0, sizeof(src->new_file)); memset(&src->new_file, 0, sizeof(src->new_file));
src->new_file.path = src->old_file.path; src->new_file.path = src->old_file.path;
...@@ -953,7 +958,7 @@ find_best_matches: ...@@ -953,7 +958,7 @@ find_best_matches:
if (src2tgt[t].similarity > 0 && src2tgt[t].idx > t) { if (src2tgt[t].similarity > 0 && src2tgt[t].idx > t) {
/* what used to be at src t is now at src s */ /* what used to be at src t is now at src s */
tgt2src[src2tgt[t].idx].idx = (uint32_t)s; tgt2src[src2tgt[t].idx].idx = s;
} }
} }
} }
...@@ -969,6 +974,7 @@ find_best_matches: ...@@ -969,6 +974,7 @@ find_best_matches:
src->status = (diff->new_src == GIT_ITERATOR_TYPE_WORKDIR) ? src->status = (diff->new_src == GIT_ITERATOR_TYPE_WORKDIR) ?
GIT_DELTA_UNTRACKED : GIT_DELTA_ADDED; GIT_DELTA_UNTRACKED : GIT_DELTA_ADDED;
src->nfiles = 1;
memset(&src->old_file, 0, sizeof(src->old_file)); memset(&src->old_file, 0, sizeof(src->old_file));
src->old_file.path = src->new_file.path; src->old_file.path = src->new_file.path;
src->old_file.flags |= GIT_DIFF_FLAG_VALID_OID; src->old_file.flags |= GIT_DIFF_FLAG_VALID_OID;
...@@ -1006,7 +1012,7 @@ find_best_matches: ...@@ -1006,7 +1012,7 @@ find_best_matches:
/* otherwise, if we just overwrote a source, update mapping */ /* otherwise, if we just overwrote a source, update mapping */
else if (src2tgt[t].similarity > 0 && src2tgt[t].idx > t) { else if (src2tgt[t].similarity > 0 && src2tgt[t].idx > t) {
/* what used to be at src t is now at src s */ /* what used to be at src t is now at src s */
tgt2src[src2tgt[t].idx].idx = (uint32_t)s; tgt2src[src2tgt[t].idx].idx = s;
} }
num_updates++; num_updates++;
...@@ -1026,6 +1032,7 @@ find_best_matches: ...@@ -1026,6 +1032,7 @@ find_best_matches:
tgt->status = GIT_DELTA_COPIED; tgt->status = GIT_DELTA_COPIED;
tgt->similarity = best_match->similarity; tgt->similarity = best_match->similarity;
tgt->nfiles = 2;
memcpy(&tgt->old_file, &src->old_file, sizeof(tgt->old_file)); memcpy(&tgt->old_file, &src->old_file, sizeof(tgt->old_file));
num_updates++; num_updates++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment