diff options: add --color
This patch is a slightly adjusted version of Junio's patch: http://www.gelato.unsw.edu.au/archives/git/0604/19354.html However, instead of using a config variable, this patch makes it available as a diff option. Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
ae448e3854
commit
cd112cef99
79
diff.c
79
diff.c
@ -25,6 +25,20 @@ int git_diff_config(const char *var, const char *value)
|
||||
return git_default_config(var, value);
|
||||
}
|
||||
|
||||
enum color_diff {
|
||||
DIFF_PLAIN = 0,
|
||||
DIFF_METAINFO = 1,
|
||||
DIFF_FILE_OLD = 2,
|
||||
DIFF_FILE_NEW = 3,
|
||||
};
|
||||
|
||||
static const char *diff_colors[] = {
|
||||
"\033[0;0m",
|
||||
"\033[1;35m",
|
||||
"\033[1;31m",
|
||||
"\033[1;34m",
|
||||
};
|
||||
|
||||
static char *quote_one(const char *str)
|
||||
{
|
||||
int needlen;
|
||||
@ -177,23 +191,54 @@ static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
|
||||
}
|
||||
|
||||
struct emit_callback {
|
||||
struct xdiff_emit_state xm;
|
||||
int nparents, color_diff;
|
||||
const char **label_path;
|
||||
};
|
||||
|
||||
static int fn_out(void *priv, mmbuffer_t *mb, int nbuf)
|
||||
static inline void color_diff(int diff_use_color, enum color_diff ix)
|
||||
{
|
||||
if (diff_use_color)
|
||||
fputs(diff_colors[ix], stdout);
|
||||
}
|
||||
|
||||
static void fn_out_consume(void *priv, char *line, unsigned long len)
|
||||
{
|
||||
int i;
|
||||
struct emit_callback *ecbdata = priv;
|
||||
|
||||
if (ecbdata->label_path[0]) {
|
||||
color_diff(ecbdata->color_diff, DIFF_METAINFO);
|
||||
printf("--- %s\n", ecbdata->label_path[0]);
|
||||
color_diff(ecbdata->color_diff, DIFF_METAINFO);
|
||||
printf("+++ %s\n", ecbdata->label_path[1]);
|
||||
ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
|
||||
}
|
||||
for (i = 0; i < nbuf; i++)
|
||||
if (!fwrite(mb[i].ptr, mb[i].size, 1, stdout))
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
/* This is not really necessary for now because
|
||||
* this codepath only deals with two-way diffs.
|
||||
*/
|
||||
for (i = 0; i < len && line[i] == '@'; i++)
|
||||
;
|
||||
if (2 <= i && i < len && line[i] == ' ') {
|
||||
ecbdata->nparents = i - 1;
|
||||
color_diff(ecbdata->color_diff, DIFF_METAINFO);
|
||||
}
|
||||
else if (len < ecbdata->nparents)
|
||||
color_diff(ecbdata->color_diff, DIFF_PLAIN);
|
||||
else {
|
||||
int nparents = ecbdata->nparents;
|
||||
int color = DIFF_PLAIN;
|
||||
for (i = 0; i < nparents && len; i++) {
|
||||
if (line[i] == '-')
|
||||
color = DIFF_FILE_OLD;
|
||||
else if (line[i] == '+')
|
||||
color = DIFF_FILE_NEW;
|
||||
}
|
||||
color_diff(ecbdata->color_diff, color);
|
||||
}
|
||||
fwrite(line, len, 1, stdout);
|
||||
color_diff(ecbdata->color_diff, DIFF_PLAIN);
|
||||
}
|
||||
|
||||
static char *pprint_rename(const char *a, const char *b)
|
||||
@ -549,25 +594,35 @@ static void builtin_diff(const char *name_a,
|
||||
b_two = quote_two("b/", name_b);
|
||||
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
|
||||
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
|
||||
color_diff(o->color_diff, DIFF_METAINFO);
|
||||
printf("diff --git %s %s\n", a_one, b_two);
|
||||
if (lbl[0][0] == '/') {
|
||||
/* /dev/null */
|
||||
color_diff(o->color_diff, DIFF_METAINFO);
|
||||
printf("new file mode %06o\n", two->mode);
|
||||
if (xfrm_msg && xfrm_msg[0])
|
||||
if (xfrm_msg && xfrm_msg[0]) {
|
||||
color_diff(o->color_diff, DIFF_METAINFO);
|
||||
puts(xfrm_msg);
|
||||
}
|
||||
}
|
||||
else if (lbl[1][0] == '/') {
|
||||
printf("deleted file mode %06o\n", one->mode);
|
||||
if (xfrm_msg && xfrm_msg[0])
|
||||
if (xfrm_msg && xfrm_msg[0]) {
|
||||
color_diff(o->color_diff, DIFF_METAINFO);
|
||||
puts(xfrm_msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (one->mode != two->mode) {
|
||||
color_diff(o->color_diff, DIFF_METAINFO);
|
||||
printf("old mode %06o\n", one->mode);
|
||||
color_diff(o->color_diff, DIFF_METAINFO);
|
||||
printf("new mode %06o\n", two->mode);
|
||||
}
|
||||
if (xfrm_msg && xfrm_msg[0])
|
||||
if (xfrm_msg && xfrm_msg[0]) {
|
||||
color_diff(o->color_diff, DIFF_METAINFO);
|
||||
puts(xfrm_msg);
|
||||
}
|
||||
/*
|
||||
* we do not run diff between different kind
|
||||
* of objects.
|
||||
@ -575,6 +630,7 @@ static void builtin_diff(const char *name_a,
|
||||
if ((one->mode ^ two->mode) & S_IFMT)
|
||||
goto free_ab_and_return;
|
||||
if (complete_rewrite) {
|
||||
color_diff(o->color_diff, DIFF_PLAIN);
|
||||
emit_rewrite_diff(name_a, name_b, one, two);
|
||||
goto free_ab_and_return;
|
||||
}
|
||||
@ -602,7 +658,9 @@ static void builtin_diff(const char *name_a,
|
||||
xdemitcb_t ecb;
|
||||
struct emit_callback ecbdata;
|
||||
|
||||
memset(&ecbdata, 0, sizeof(ecbdata));
|
||||
ecbdata.label_path = lbl;
|
||||
ecbdata.color_diff = o->color_diff;
|
||||
xpp.flags = XDF_NEED_MINIMAL;
|
||||
xecfg.ctxlen = o->context;
|
||||
xecfg.flags = XDL_EMIT_FUNCNAMES;
|
||||
@ -612,8 +670,9 @@ static void builtin_diff(const char *name_a,
|
||||
xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
|
||||
else if (!strncmp(diffopts, "-u", 2))
|
||||
xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
|
||||
ecb.outf = fn_out;
|
||||
ecb.outf = xdiff_outf;
|
||||
ecb.priv = &ecbdata;
|
||||
ecbdata.xm.consume = fn_out_consume;
|
||||
xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
|
||||
}
|
||||
|
||||
@ -1456,6 +1515,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
|
||||
else if (40 < options->abbrev)
|
||||
options->abbrev = 40;
|
||||
}
|
||||
else if (!strcmp(arg, "--color"))
|
||||
options->color_diff = 1;
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
|
3
diff.h
3
diff.h
@ -32,7 +32,8 @@ struct diff_options {
|
||||
full_index:1,
|
||||
silent_on_remove:1,
|
||||
find_copies_harder:1,
|
||||
summary:1;
|
||||
summary:1,
|
||||
color_diff:1;
|
||||
int context;
|
||||
int break_opt;
|
||||
int detect_rename;
|
||||
|
Loading…
Reference in New Issue
Block a user