diff: fix coloring of extended diff headers

Coloring the extended headers where done as a whole not per line. less with
option -R (which is the default from git) does not support this coloring
mode because of performance reasons. The -r option would be an alternative
but has problems with lines that are longer than the screen. Therefore
stick to the idiom to color each line separately. The problem is, that the
result of ill_metainfo() will also be used as an parameter to an external
diff driver, so we need to disable coloring in this case.

Because coloring is now done inside fill_metainfo() we can simply add this
string to the diff header and therefore keep the last newline in the
extended header. This results also into the fact that the external diff
driver now gets this last newline too. Which is a change in behavior
but a good one.

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Bert Wesarg 2010-05-04 00:38:07 +02:00 коммит произвёл Junio C Hamano
Родитель d599e0484f
Коммит 374664478f
1 изменённых файлов: 35 добавлений и 26 удалений

61
diff.c
Просмотреть файл

@ -1650,21 +1650,21 @@ static void builtin_diff(const char *name_a,
if (lbl[0][0] == '/') { if (lbl[0][0] == '/') {
/* /dev/null */ /* /dev/null */
strbuf_addf(&header, "%snew file mode %06o%s\n", set, two->mode, reset); strbuf_addf(&header, "%snew file mode %06o%s\n", set, two->mode, reset);
if (xfrm_msg && xfrm_msg[0]) if (xfrm_msg)
strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset); strbuf_addstr(&header, xfrm_msg);
} }
else if (lbl[1][0] == '/') { else if (lbl[1][0] == '/') {
strbuf_addf(&header, "%sdeleted file mode %06o%s\n", set, one->mode, reset); strbuf_addf(&header, "%sdeleted file mode %06o%s\n", set, one->mode, reset);
if (xfrm_msg && xfrm_msg[0]) if (xfrm_msg)
strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset); strbuf_addstr(&header, xfrm_msg);
} }
else { else {
if (one->mode != two->mode) { if (one->mode != two->mode) {
strbuf_addf(&header, "%sold mode %06o%s\n", set, one->mode, reset); strbuf_addf(&header, "%sold mode %06o%s\n", set, one->mode, reset);
strbuf_addf(&header, "%snew mode %06o%s\n", set, two->mode, reset); strbuf_addf(&header, "%snew mode %06o%s\n", set, two->mode, reset);
} }
if (xfrm_msg && xfrm_msg[0]) if (xfrm_msg)
strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset); strbuf_addstr(&header, xfrm_msg);
/* /*
* we do not run diff between different kind * we do not run diff between different kind
@ -2323,30 +2323,36 @@ static void fill_metainfo(struct strbuf *msg,
struct diff_filespec *one, struct diff_filespec *one,
struct diff_filespec *two, struct diff_filespec *two,
struct diff_options *o, struct diff_options *o,
struct diff_filepair *p) struct diff_filepair *p,
int use_color)
{ {
const char *set = diff_get_color(use_color, DIFF_METAINFO);
const char *reset = diff_get_color(use_color, DIFF_RESET);
strbuf_init(msg, PATH_MAX * 2 + 300); strbuf_init(msg, PATH_MAX * 2 + 300);
switch (p->status) { switch (p->status) {
case DIFF_STATUS_COPIED: case DIFF_STATUS_COPIED:
strbuf_addf(msg, "similarity index %d%%", similarity_index(p)); strbuf_addf(msg, "%ssimilarity index %d%%",
strbuf_addstr(msg, "\ncopy from "); set, similarity_index(p));
strbuf_addf(msg, "%s\n%scopy from ", reset, set);
quote_c_style(name, msg, NULL, 0); quote_c_style(name, msg, NULL, 0);
strbuf_addstr(msg, "\ncopy to "); strbuf_addf(msg, "%s\n%scopy to ", reset, set);
quote_c_style(other, msg, NULL, 0); quote_c_style(other, msg, NULL, 0);
strbuf_addch(msg, '\n'); strbuf_addf(msg, "%s\n", reset);
break; break;
case DIFF_STATUS_RENAMED: case DIFF_STATUS_RENAMED:
strbuf_addf(msg, "similarity index %d%%", similarity_index(p)); strbuf_addf(msg, "%ssimilarity index %d%%",
strbuf_addstr(msg, "\nrename from "); set, similarity_index(p));
strbuf_addf(msg, "%s\n%srename from ", reset, set);
quote_c_style(name, msg, NULL, 0); quote_c_style(name, msg, NULL, 0);
strbuf_addstr(msg, "\nrename to "); strbuf_addf(msg, "%s\n%srename to ", reset, set);
quote_c_style(other, msg, NULL, 0); quote_c_style(other, msg, NULL, 0);
strbuf_addch(msg, '\n'); strbuf_addf(msg, "%s\n", reset);
break; break;
case DIFF_STATUS_MODIFIED: case DIFF_STATUS_MODIFIED:
if (p->score) { if (p->score) {
strbuf_addf(msg, "dissimilarity index %d%%\n", strbuf_addf(msg, "%sdissimilarity index %d%%%s\n",
similarity_index(p)); set, similarity_index(p), reset);
break; break;
} }
/* fallthru */ /* fallthru */
@ -2363,15 +2369,13 @@ static void fill_metainfo(struct strbuf *msg,
(!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
abbrev = 40; abbrev = 40;
} }
strbuf_addf(msg, "index %.*s..%.*s", strbuf_addf(msg, "%sindex %.*s..%.*s", set,
abbrev, sha1_to_hex(one->sha1), abbrev, sha1_to_hex(one->sha1),
abbrev, sha1_to_hex(two->sha1)); abbrev, sha1_to_hex(two->sha1));
if (one->mode == two->mode) if (one->mode == two->mode)
strbuf_addf(msg, " %06o", one->mode); strbuf_addf(msg, " %06o", one->mode);
strbuf_addch(msg, '\n'); strbuf_addf(msg, "%s\n", reset);
} }
if (msg->len)
strbuf_setlen(msg, msg->len - 1);
} }
static void run_diff_cmd(const char *pgm, static void run_diff_cmd(const char *pgm,
@ -2387,11 +2391,6 @@ static void run_diff_cmd(const char *pgm,
const char *xfrm_msg = NULL; const char *xfrm_msg = NULL;
int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score; int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score;
if (msg) {
fill_metainfo(msg, name, other, one, two, o, p);
xfrm_msg = msg->len ? msg->buf : NULL;
}
if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL)) if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL))
pgm = NULL; pgm = NULL;
else { else {
@ -2400,6 +2399,16 @@ static void run_diff_cmd(const char *pgm,
pgm = drv->external; pgm = drv->external;
} }
if (msg) {
/*
* don't use colors when the header is intended for an
* external diff driver
*/
fill_metainfo(msg, name, other, one, two, o, p,
DIFF_OPT_TST(o, COLOR_DIFF) && !pgm);
xfrm_msg = msg->len ? msg->buf : NULL;
}
if (pgm) { if (pgm) {
run_external_diff(pgm, name, other, one, two, xfrm_msg, run_external_diff(pgm, name, other, one, two, xfrm_msg,
complete_rewrite); complete_rewrite);