summaryrefslogtreecommitdiff
path: root/diffcore-rename.c
diff options
context:
space:
mode:
Diffstat (limited to 'diffcore-rename.c')
-rw-r--r--diffcore-rename.c39
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)