git-svn: support for funky branch and project names over HTTP(S)
[gitweb.git] / diffcore-rename.c
index 394693222d5ef9e1f73cb84d271bdcee037d36ad..f9ebea56406090af207f79951618742dcd7d397f 100644 (file)
@@ -144,6 +144,20 @@ static int estimate_similarity(struct diff_filespec *src,
        if (!S_ISREG(src->mode) || !S_ISREG(dst->mode))
                return 0;
 
+       /*
+        * Need to check that source and destination sizes are
+        * filled in before comparing them.
+        *
+        * If we already have "cnt_data" filled in, we know it's
+        * all good (avoid checking the size for zero, as that
+        * is a possible size - we really should have a flag to
+        * say whether the size is valid or not!)
+        */
+       if (!src->cnt_data && diff_populate_filespec(src, 0))
+               return 0;
+       if (!dst->cnt_data && diff_populate_filespec(dst, 0))
+               return 0;
+
        max_size = ((src->size > dst->size) ? src->size : dst->size);
        base_size = ((src->size < dst->size) ? src->size : dst->size);
        delta_size = max_size - base_size;
@@ -159,11 +173,6 @@ static int estimate_similarity(struct diff_filespec *src,
        if (base_size * (MAX_SCORE-minimum_score) < delta_size * MAX_SCORE)
                return 0;
 
-       if ((!src->cnt_data && diff_populate_filespec(src, 0))
-               || (!dst->cnt_data && diff_populate_filespec(dst, 0)))
-               return 0; /* error but caught downstream */
-
-
        delta_limit = (unsigned long)
                (base_size * (MAX_SCORE-minimum_score) / MAX_SCORE);
        if (diffcore_count_changes(src, dst,
@@ -270,19 +279,11 @@ static int find_identical_files(struct file_similarity *src,
        return renames;
 }
 
-/*
- * Note: the rest of the rename logic depends on this
- * phase also populating all the filespecs for any
- * entry that isn't matched up with an exact rename.
- */
 static void free_similarity_list(struct file_similarity *p)
 {
        while (p) {
                struct file_similarity *entry = p;
                p = p->next;
-
-               /* Stupid special case, see note above! */
-               diff_populate_filespec(entry->filespec, 0);
                free(entry);
        }
 }
@@ -434,33 +435,37 @@ void diffcore_rename(struct diff_options *options)
         */
        rename_count = find_exact_renames();
 
+       /* Did we only want exact renames? */
+       if (minimum_score == MAX_SCORE)
+               goto cleanup;
+
+       /*
+        * Calculate how many renames are left (but all the source
+        * files still remain as options for rename/copies!)
+        */
+       num_create = (rename_dst_nr - rename_count);
+       num_src = rename_src_nr;
+
+       /* All done? */
+       if (!num_create)
+               goto cleanup;
+
        /*
         * This basically does a test for the rename matrix not
         * growing larger than a "rename_limit" square matrix, ie:
         *
-        *    rename_dst_nr * rename_src_nr > rename_limit * rename_limit
+        *    num_create * num_src > rename_limit * rename_limit
         *
         * but handles the potential overflow case specially (and we
         * assume at least 32-bit integers)
         */
        if (rename_limit <= 0 || rename_limit > 32767)
                rename_limit = 32767;
-       if (rename_dst_nr > rename_limit && rename_src_nr > rename_limit)
-               goto cleanup;
-       if (rename_dst_nr * rename_src_nr > rename_limit * rename_limit)
+       if (num_create > rename_limit && num_src > rename_limit)
                goto cleanup;
-
-       /* Have we run out the created file pool?  If so we can avoid
-        * doing the delta matrix altogether.
-        */
-       if (rename_count == rename_dst_nr)
+       if (num_create * num_src > rename_limit * rename_limit)
                goto cleanup;
 
-       if (minimum_score == MAX_SCORE)
-               goto cleanup;
-
-       num_create = (rename_dst_nr - rename_count);
-       num_src = rename_src_nr;
        mx = xmalloc(sizeof(*mx) * num_create * num_src);
        for (dst_cnt = i = 0; i < rename_dst_nr; i++) {
                int base = dst_cnt * num_src;