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);
|
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)
|
static char *quote_one(const char *str)
|
||||||
{
|
{
|
||||||
int needlen;
|
int needlen;
|
||||||
@ -177,23 +191,54 @@ static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct emit_callback {
|
struct emit_callback {
|
||||||
|
struct xdiff_emit_state xm;
|
||||||
|
int nparents, color_diff;
|
||||||
const char **label_path;
|
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;
|
int i;
|
||||||
struct emit_callback *ecbdata = priv;
|
struct emit_callback *ecbdata = priv;
|
||||||
|
|
||||||
if (ecbdata->label_path[0]) {
|
if (ecbdata->label_path[0]) {
|
||||||
|
color_diff(ecbdata->color_diff, DIFF_METAINFO);
|
||||||
printf("--- %s\n", ecbdata->label_path[0]);
|
printf("--- %s\n", ecbdata->label_path[0]);
|
||||||
|
color_diff(ecbdata->color_diff, DIFF_METAINFO);
|
||||||
printf("+++ %s\n", ecbdata->label_path[1]);
|
printf("+++ %s\n", ecbdata->label_path[1]);
|
||||||
ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
|
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))
|
/* This is not really necessary for now because
|
||||||
return -1;
|
* this codepath only deals with two-way diffs.
|
||||||
return 0;
|
*/
|
||||||
|
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)
|
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);
|
b_two = quote_two("b/", name_b);
|
||||||
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
|
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
|
||||||
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/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);
|
printf("diff --git %s %s\n", a_one, b_two);
|
||||||
if (lbl[0][0] == '/') {
|
if (lbl[0][0] == '/') {
|
||||||
/* /dev/null */
|
/* /dev/null */
|
||||||
|
color_diff(o->color_diff, DIFF_METAINFO);
|
||||||
printf("new file mode %06o\n", two->mode);
|
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);
|
puts(xfrm_msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (lbl[1][0] == '/') {
|
else if (lbl[1][0] == '/') {
|
||||||
printf("deleted file mode %06o\n", one->mode);
|
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);
|
puts(xfrm_msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (one->mode != two->mode) {
|
if (one->mode != two->mode) {
|
||||||
|
color_diff(o->color_diff, DIFF_METAINFO);
|
||||||
printf("old mode %06o\n", one->mode);
|
printf("old mode %06o\n", one->mode);
|
||||||
|
color_diff(o->color_diff, DIFF_METAINFO);
|
||||||
printf("new mode %06o\n", two->mode);
|
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);
|
puts(xfrm_msg);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* we do not run diff between different kind
|
* we do not run diff between different kind
|
||||||
* of objects.
|
* of objects.
|
||||||
@ -575,6 +630,7 @@ static void builtin_diff(const char *name_a,
|
|||||||
if ((one->mode ^ two->mode) & S_IFMT)
|
if ((one->mode ^ two->mode) & S_IFMT)
|
||||||
goto free_ab_and_return;
|
goto free_ab_and_return;
|
||||||
if (complete_rewrite) {
|
if (complete_rewrite) {
|
||||||
|
color_diff(o->color_diff, DIFF_PLAIN);
|
||||||
emit_rewrite_diff(name_a, name_b, one, two);
|
emit_rewrite_diff(name_a, name_b, one, two);
|
||||||
goto free_ab_and_return;
|
goto free_ab_and_return;
|
||||||
}
|
}
|
||||||
@ -602,7 +658,9 @@ static void builtin_diff(const char *name_a,
|
|||||||
xdemitcb_t ecb;
|
xdemitcb_t ecb;
|
||||||
struct emit_callback ecbdata;
|
struct emit_callback ecbdata;
|
||||||
|
|
||||||
|
memset(&ecbdata, 0, sizeof(ecbdata));
|
||||||
ecbdata.label_path = lbl;
|
ecbdata.label_path = lbl;
|
||||||
|
ecbdata.color_diff = o->color_diff;
|
||||||
xpp.flags = XDF_NEED_MINIMAL;
|
xpp.flags = XDF_NEED_MINIMAL;
|
||||||
xecfg.ctxlen = o->context;
|
xecfg.ctxlen = o->context;
|
||||||
xecfg.flags = XDL_EMIT_FUNCNAMES;
|
xecfg.flags = XDL_EMIT_FUNCNAMES;
|
||||||
@ -612,8 +670,9 @@ static void builtin_diff(const char *name_a,
|
|||||||
xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
|
xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
|
||||||
else if (!strncmp(diffopts, "-u", 2))
|
else if (!strncmp(diffopts, "-u", 2))
|
||||||
xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
|
xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
|
||||||
ecb.outf = fn_out;
|
ecb.outf = xdiff_outf;
|
||||||
ecb.priv = &ecbdata;
|
ecb.priv = &ecbdata;
|
||||||
|
ecbdata.xm.consume = fn_out_consume;
|
||||||
xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
|
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)
|
else if (40 < options->abbrev)
|
||||||
options->abbrev = 40;
|
options->abbrev = 40;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(arg, "--color"))
|
||||||
|
options->color_diff = 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
3
diff.h
3
diff.h
@ -32,7 +32,8 @@ struct diff_options {
|
|||||||
full_index:1,
|
full_index:1,
|
||||||
silent_on_remove:1,
|
silent_on_remove:1,
|
||||||
find_copies_harder:1,
|
find_copies_harder:1,
|
||||||
summary:1;
|
summary:1,
|
||||||
|
color_diff:1;
|
||||||
int context;
|
int context;
|
||||||
int break_opt;
|
int break_opt;
|
||||||
int detect_rename;
|
int detect_rename;
|
||||||
|
2
pager.c
2
pager.c
@ -46,7 +46,7 @@ void setup_pager(void)
|
|||||||
close(fd[0]);
|
close(fd[0]);
|
||||||
close(fd[1]);
|
close(fd[1]);
|
||||||
|
|
||||||
setenv("LESS", "-S", 0);
|
setenv("LESS", "-RS", 0);
|
||||||
run_pager(pager);
|
run_pager(pager);
|
||||||
die("unable to execute pager '%s'", pager);
|
die("unable to execute pager '%s'", pager);
|
||||||
exit(255);
|
exit(255);
|
||||||
|
Loading…
Reference in New Issue
Block a user