diff options
Diffstat (limited to 'diffcore-rename.c')
-rw-r--r-- | diffcore-rename.c | 39 |
1 files changed, 13 insertions, 26 deletions
diff --git a/diffcore-rename.c b/diffcore-rename.c index 55a188abcc..a215421a9c 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -76,36 +76,23 @@ static struct diff_rename_src { } *rename_src; static int rename_src_nr, rename_src_alloc; -static struct diff_rename_src *register_rename_src(struct diff_filepair *p) +static void register_rename_src(struct diff_filepair *p) { - int first, last; - struct diff_filespec *one = p->one; - unsigned short score = p->score; - - first = 0; - last = rename_src_nr; - while (last > first) { - int next = first + ((last - first) >> 1); - struct diff_rename_src *src = &(rename_src[next]); - int cmp = strcmp(one->path, src->p->one->path); - if (!cmp) - return src; - if (cmp < 0) { - last = next; - continue; - } - first = next+1; - } + /* + * If we have multiple entries at the same path in the source tree + * (an invalid tree, to be sure), avoid using more more than one + * such entry in rename detection. Once upon a time, doing so + * caused segfaults; see commit 25d5ea410f ("[PATCH] Redo + * rename/copy detection logic.", 2005-05-24). + */ + if (rename_src_nr > 0 && + !strcmp(rename_src[rename_src_nr-1].p->one->path, p->one->path)) + return; - /* insert to make it at "first" */ ALLOC_GROW(rename_src, rename_src_nr + 1, rename_src_alloc); + rename_src[rename_src_nr].p = p; + rename_src[rename_src_nr].score = p->score; rename_src_nr++; - if (first < rename_src_nr) - MOVE_ARRAY(rename_src + first + 1, rename_src + first, - rename_src_nr - first - 1); - rename_src[first].p = p; - rename_src[first].score = score; - return &(rename_src[first]); } static int basename_same(struct diff_filespec *src, struct diff_filespec *dst) |