From 17e6019a2ac9ad392c2e1c7fb6ce9c53d3d45acf Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 6 Jul 2006 00:35:47 -0700 Subject: diffcore-rename: try matching up renames without populating filespec first. Signed-off-by: Junio C Hamano --- diffcore-rename.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'diffcore-rename.c') diff --git a/diffcore-rename.c b/diffcore-rename.c index d57e8656cd..1de8d32502 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -96,11 +96,15 @@ static struct diff_rename_src *register_rename_src(struct diff_filespec *one, return &(rename_src[first]); } -static int is_exact_match(struct diff_filespec *src, struct diff_filespec *dst) +static int is_exact_match(struct diff_filespec *src, + struct diff_filespec *dst, + int contents_too) { if (src->sha1_valid && dst->sha1_valid && !memcmp(src->sha1, dst->sha1, 20)) return 1; + if (!contents_too) + return 0; if (diff_populate_filespec(src, 1) || diff_populate_filespec(dst, 1)) return 0; if (src->size != dst->size) @@ -242,7 +246,7 @@ void diffcore_rename(struct diff_options *options) struct diff_queue_struct *q = &diff_queued_diff; struct diff_queue_struct outq; struct diff_score *mx; - int i, j, rename_count; + int i, j, rename_count, contents_too; int num_create, num_src, dst_cnt; if (!minimum_score) @@ -273,16 +277,23 @@ void diffcore_rename(struct diff_options *options) /* We really want to cull the candidates list early * with cheap tests in order to avoid doing deltas. + * The first round matches up the up-to-date entries, + * and then during the second round we try to match + * cache-dirty entries as well. */ - for (i = 0; i < rename_dst_nr; i++) { - struct diff_filespec *two = rename_dst[i].two; - for (j = 0; j < rename_src_nr; j++) { - struct diff_filespec *one = rename_src[j].one; - if (!is_exact_match(one, two)) - continue; - record_rename_pair(i, j, MAX_SCORE); - rename_count++; - break; /* we are done with this entry */ + for (contents_too = 0; contents_too < 2; contents_too++) { + for (i = 0; i < rename_dst_nr; i++) { + struct diff_filespec *two = rename_dst[i].two; + if (rename_dst[i].pair) + continue; /* dealt with an earlier round */ + for (j = 0; j < rename_src_nr; j++) { + struct diff_filespec *one = rename_src[j].one; + if (!is_exact_match(one, two, contents_too)) + continue; + record_rename_pair(i, j, MAX_SCORE); + rename_count++; + break; /* we are done with this entry */ + } } } -- cgit v1.3-5-g9baa From ef677686efe1868432d3cc9d4c41a93b44f3def8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 3 Aug 2006 12:01:01 -0700 Subject: diff.c: do not use pathname comparison to tell renames The final output from diff used to compare pathnames between preimage and postimage to tell if the filepair is a rename/copy. By explicitly marking the filepair created by diffcore_rename(), the output routine, resolve_rename_copy(), does not have to do so anymore. This helps feeding a filepair that has different pathnames in one and two elements to the diff machinery (most notably, comparing two blobs). Signed-off-by: Junio C Hamano --- diff.c | 6 +----- diffcore-rename.c | 1 + diffcore.h | 3 ++- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'diffcore-rename.c') diff --git a/diff.c b/diff.c index 607c357f5a..895c137655 100644 --- a/diff.c +++ b/diff.c @@ -1786,13 +1786,9 @@ struct diff_filepair *diff_queue(struct diff_queue_struct *queue, struct diff_filespec *one, struct diff_filespec *two) { - struct diff_filepair *dp = xmalloc(sizeof(*dp)); + struct diff_filepair *dp = xcalloc(1, sizeof(*dp)); dp->one = one; dp->two = two; - dp->score = 0; - dp->status = 0; - dp->source_stays = 0; - dp->broken_pair = 0; if (queue) diff_q(queue, dp); return dp; diff --git a/diffcore-rename.c b/diffcore-rename.c index 1de8d32502..0ec488a903 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -205,6 +205,7 @@ static void record_rename_pair(int dst_index, int src_index, int score) fill_filespec(two, dst->sha1, dst->mode); dp = diff_queue(NULL, one, two); + dp->renamed_pair = 1; if (!strcmp(src->path, dst->path)) dp->score = rename_src[src_index].score; else diff --git a/diffcore.h b/diffcore.h index 73c7842cc7..2249bc2c05 100644 --- a/diffcore.h +++ b/diffcore.h @@ -53,11 +53,12 @@ struct diff_filepair { char status; /* M C R N D U (see Documentation/diff-format.txt) */ unsigned source_stays : 1; /* all of R/C are copies */ unsigned broken_pair : 1; + unsigned renamed_pair : 1; }; #define DIFF_PAIR_UNMERGED(p) \ (!DIFF_FILE_VALID((p)->one) && !DIFF_FILE_VALID((p)->two)) -#define DIFF_PAIR_RENAME(p) (strcmp((p)->one->path, (p)->two->path)) +#define DIFF_PAIR_RENAME(p) ((p)->renamed_pair) #define DIFF_PAIR_BROKEN(p) \ ( (!DIFF_FILE_VALID((p)->one) != !DIFF_FILE_VALID((p)->two)) && \ -- cgit v1.3-5-g9baa