Merge branch 'rs/diff'
authorJunio C Hamano <gitster@pobox.com>
Sun, 1 Jul 2007 21:58:09 +0000 (14:58 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 1 Jul 2007 21:58:09 +0000 (14:58 -0700)
* rs/diff:
diff: round down similarity index
diffcore-rename: don't change similarity index based on basename equality

Documentation/diff-format.txt
diff.c
diffcore-rename.c
index 18d49d2c3baa81983b19a938598eb091fb7809ef..001503205b24d5c20ec10792c4ab6c4c7221bcb7 100644 (file)
@@ -126,6 +126,13 @@ the file that rename/copy produces, respectively.
     If there is need for such substitution then the whole
     pathname is put in double quotes.
 
+The similarity index is the percentage of unchanged lines, and
+the dissimilarity index is the percentage of changed lines.  It
+is a rounded down integer, followed by a percent sign.  The
+similarity index value of 100% is thus reserved for two equal
+files, while 100% dissimilarity means that no line from the old
+file made it into the new one.
+
 
 combined diff format
 --------------------
diff --git a/diff.c b/diff.c
index 9938969fa50e8af2a4eabe96ae122111ae42fe75..e0edb98846753f39cab9e377c9ac4af2d7fdbf35 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1813,6 +1813,11 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
                hashclr(one->sha1);
 }
 
+static int similarity_index(struct diff_filepair *p)
+{
+       return p->score * 100 / MAX_SCORE;
+}
+
 static void run_diff(struct diff_filepair *p, struct diff_options *o)
 {
        const char *pgm = external_diff();
@@ -1847,23 +1852,20 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
                                "similarity index %d%%\n"
                                "copy from %s\n"
                                "copy to %s\n",
-                               (int)(0.5 + p->score * 100.0/MAX_SCORE),
-                               name_munged, other_munged);
+                               similarity_index(p), name_munged, other_munged);
                break;
        case DIFF_STATUS_RENAMED:
                len += snprintf(msg + len, sizeof(msg) - len,
                                "similarity index %d%%\n"
                                "rename from %s\n"
                                "rename to %s\n",
-                               (int)(0.5 + p->score * 100.0/MAX_SCORE),
-                               name_munged, other_munged);
+                               similarity_index(p), name_munged, other_munged);
                break;
        case DIFF_STATUS_MODIFIED:
                if (p->score) {
                        len += snprintf(msg + len, sizeof(msg) - len,
                                        "dissimilarity index %d%%\n",
-                                       (int)(0.5 + p->score *
-                                             100.0/MAX_SCORE));
+                                       similarity_index(p));
                        complete_rewrite = 1;
                        break;
                }
@@ -2387,8 +2389,7 @@ static void diff_flush_raw(struct diff_filepair *p,
        }
 
        if (p->score)
-               sprintf(status, "%c%03d", p->status,
-                       (int)(0.5 + p->score * 100.0/MAX_SCORE));
+               sprintf(status, "%c%03d", p->status, similarity_index(p));
        else {
                status[0] = p->status;
                status[1] = 0;
@@ -2670,8 +2671,7 @@ static void show_rename_copy(const char *renamecopy, struct diff_filepair *p)
 {
        char *names = pprint_rename(p->one->path, p->two->path);
 
-       printf(" %s %s (%d%%)\n", renamecopy, names,
-              (int)(0.5 + p->score * 100.0/MAX_SCORE));
+       printf(" %s %s (%d%%)\n", renamecopy, names, similarity_index(p));
        free(names);
        show_mode_change(p, 0);
 }
@@ -2695,7 +2695,7 @@ static void diff_summary(struct diff_filepair *p)
                if (p->score) {
                        char *name = quote_one(p->two->path);
                        printf(" rewrite %s (%d%%)\n", name,
-                               (int)(0.5 + p->score * 100.0/MAX_SCORE));
+                              similarity_index(p));
                        free(name);
                        show_mode_change(p, 0);
                } else  show_mode_change(p, 1);
index 79c984c9cf5489d22f359b7a2ad3464ffc271c35..e0a89f3796890d0d23bb80b3fd6e3cac2ae1b752 100644 (file)
@@ -138,6 +138,7 @@ struct diff_score {
        int src; /* index in rename_src */
        int dst; /* index in rename_dst */
        int score;
+       int name_score;
 };
 
 static int estimate_similarity(struct diff_filespec *src,
@@ -201,11 +202,8 @@ static int estimate_similarity(struct diff_filespec *src,
         */
        if (!dst->size)
                score = 0; /* should not happen */
-       else {
+       else
                score = (int)(src_copied * MAX_SCORE / max_size);
-               if (basename_same(src, dst))
-                       score++;
-       }
        return score;
 }
 
@@ -242,6 +240,10 @@ static void record_rename_pair(int dst_index, int src_index, int score)
 static int score_compare(const void *a_, const void *b_)
 {
        const struct diff_score *a = a_, *b = b_;
+
+       if (a->score == b->score)
+               return b->name_score - a->name_score;
+
        return b->score - a->score;
 }
 
@@ -360,6 +362,7 @@ void diffcore_rename(struct diff_options *options)
                        m->dst = i;
                        m->score = estimate_similarity(one, two,
                                                       minimum_score);
+                       m->name_score = basename_same(one, two);
                        diff_free_filespec_data(one);
                }
                /* We do not need the text anymore */