Teach git list-objects logic not to follow gitlinks
[gitweb.git] / diffcore-rename.c
index 1de8d32502a77b641e004e9df9da3fcc188eef9c..79030412dbf883147f35678505ad147dc9c240a8 100644 (file)
@@ -101,7 +101,7 @@ static int is_exact_match(struct diff_filespec *src,
                          int contents_too)
 {
        if (src->sha1_valid && dst->sha1_valid &&
-           !memcmp(src->sha1, dst->sha1, 20))
+           !hashcmp(src->sha1, dst->sha1))
                return 1;
        if (!contents_too)
                return 0;
@@ -109,6 +109,8 @@ static int is_exact_match(struct diff_filespec *src,
                return 0;
        if (src->size != dst->size)
                return 0;
+       if (src->sha1_valid && dst->sha1_valid)
+           return !hashcmp(src->sha1, dst->sha1);
        if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0))
                return 0;
        if (src->size == dst->size &&
@@ -170,7 +172,8 @@ static int estimate_similarity(struct diff_filespec *src,
                return 0; /* error but caught downstream */
 
 
-       delta_limit = base_size * (MAX_SCORE-minimum_score) / MAX_SCORE;
+       delta_limit = (unsigned long)
+               (base_size * (MAX_SCORE-minimum_score) / MAX_SCORE);
        if (diffcore_count_changes(src->data, src->size,
                                   dst->data, dst->size,
                                   &src->cnt_data, &dst->cnt_data,
@@ -184,7 +187,7 @@ static int estimate_similarity(struct diff_filespec *src,
        if (!dst->size)
                score = 0; /* should not happen */
        else
-               score = src_copied * MAX_SCORE / max_size;
+               score = (int)(src_copied * MAX_SCORE / max_size);
        return score;
 }
 
@@ -205,6 +208,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
@@ -255,11 +259,15 @@ void diffcore_rename(struct diff_options *options)
 
        for (i = 0; i < q->nr; i++) {
                struct diff_filepair *p = q->queue[i];
-               if (!DIFF_FILE_VALID(p->one))
+               if (!DIFF_FILE_VALID(p->one)) {
                        if (!DIFF_FILE_VALID(p->two))
                                continue; /* unmerged */
+                       else if (options->single_follow &&
+                                strcmp(options->single_follow, p->two->path))
+                               continue; /* not interested */
                        else
                                locate_rename_dst(p->two, 1);
+               }
                else if (!DIFF_FILE_VALID(p->two)) {
                        /* If the source is a broken "delete", and
                         * they did not really want to get broken,
@@ -290,7 +298,7 @@ void diffcore_rename(struct diff_options *options)
                                struct diff_filespec *one = rename_src[j].one;
                                if (!is_exact_match(one, two, contents_too))
                                        continue;
-                               record_rename_pair(i, j, MAX_SCORE);
+                               record_rename_pair(i, j, (int)MAX_SCORE);
                                rename_count++;
                                break; /* we are done with this entry */
                        }