summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/diff-format.txt7
-rw-r--r--diff.c22
-rw-r--r--diffcore-rename.c11
3 files changed, 25 insertions, 15 deletions
diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt
index 18d49d2c3b..001503205b 100644
--- a/Documentation/diff-format.txt
+++ b/Documentation/diff-format.txt
@@ -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 9938969fa5..e0edb98846 100644
--- 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);
diff --git a/diffcore-rename.c b/diffcore-rename.c
index 79c984c9cf..e0a89f3796 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -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 */