static int use_size_cache;
-int diff_rename_limit_default = -1;
-
-int git_diff_config(const char *var, const char *value)
-{
- if (!strcmp(var, "diff.renamelimit")) {
- diff_rename_limit_default = git_config_int(var, value);
- return 0;
- }
-
- return git_default_config(var, value);
-}
+static int diff_rename_limit_default = -1;
+static int diff_use_color_default = 0;
enum color_diff {
DIFF_RESET = 0,
#define COLOR_CYAN "\033[36m"
#define COLOR_WHITE "\033[37m"
-#define COLOR_CYANBG "\033[46m"
-#define COLOR_GRAYBG "\033[47m" // Good for xterm
-
static const char *diff_colors[] = {
[DIFF_RESET] = COLOR_RESET,
[DIFF_PLAIN] = COLOR_NORMAL,
[DIFF_FILE_NEW] = COLOR_GREEN,
};
+static int parse_diff_color_slot(const char *var, int ofs)
+{
+ if (!strcasecmp(var+ofs, "plain"))
+ return DIFF_PLAIN;
+ if (!strcasecmp(var+ofs, "meta"))
+ return DIFF_METAINFO;
+ if (!strcasecmp(var+ofs, "frag"))
+ return DIFF_FRAGINFO;
+ if (!strcasecmp(var+ofs, "old"))
+ return DIFF_FILE_OLD;
+ if (!strcasecmp(var+ofs, "new"))
+ return DIFF_FILE_NEW;
+ die("bad config variable '%s'", var);
+}
+
+static const char *parse_diff_color_value(const char *value, const char *var)
+{
+ if (!strcasecmp(value, "normal"))
+ return COLOR_NORMAL;
+ if (!strcasecmp(value, "bold"))
+ return COLOR_BOLD;
+ if (!strcasecmp(value, "dim"))
+ return COLOR_DIM;
+ if (!strcasecmp(value, "ul"))
+ return COLOR_UL;
+ if (!strcasecmp(value, "blink"))
+ return COLOR_BLINK;
+ if (!strcasecmp(value, "reverse"))
+ return COLOR_REVERSE;
+ if (!strcasecmp(value, "reset"))
+ return COLOR_RESET;
+ if (!strcasecmp(value, "black"))
+ return COLOR_BLACK;
+ if (!strcasecmp(value, "red"))
+ return COLOR_RED;
+ if (!strcasecmp(value, "green"))
+ return COLOR_GREEN;
+ if (!strcasecmp(value, "yellow"))
+ return COLOR_YELLOW;
+ if (!strcasecmp(value, "blue"))
+ return COLOR_BLUE;
+ if (!strcasecmp(value, "magenta"))
+ return COLOR_MAGENTA;
+ if (!strcasecmp(value, "cyan"))
+ return COLOR_CYAN;
+ if (!strcasecmp(value, "white"))
+ return COLOR_WHITE;
+ die("bad config value '%s' for variable '%s'", value, var);
+}
+
+int git_diff_config(const char *var, const char *value)
+{
+ if (!strcmp(var, "diff.renamelimit")) {
+ diff_rename_limit_default = git_config_int(var, value);
+ return 0;
+ }
+ if (!strcmp(var, "diff.color")) {
+ if (!value)
+ diff_use_color_default = 1; /* bool */
+ else if (!strcasecmp(value, "auto"))
+ diff_use_color_default = isatty(1);
+ else if (!strcasecmp(value, "never"))
+ diff_use_color_default = 0;
+ else if (!strcasecmp(value, "always"))
+ diff_use_color_default = 1;
+ else
+ diff_use_color_default = git_config_bool(var, value);
+ return 0;
+ }
+ if (!strncmp(var, "diff.color.", 11)) {
+ int slot = parse_diff_color_slot(var, 11);
+ diff_colors[slot] = parse_diff_color_value(value, var);
+ return 0;
+ }
+ return git_default_config(var, value);
+}
+
static char *quote_one(const char *str)
{
int needlen;
static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
{
if (!DIFF_FILE_VALID(one)) {
- mf->ptr = ""; /* does not matter */
+ mf->ptr = (char *)""; /* does not matter */
mf->size = 0;
return 0;
}
}
for (i = 0; i < data->nr; i++) {
- char *prefix = "";
+ const char *prefix = "";
char *name = data->files[i]->name;
int added = data->files[i]->added;
int deleted = data->files[i]->deleted;
const char *lbl[2];
char *a_one, *b_two;
const char *set = get_color(o->color_diff, DIFF_METAINFO);
- const char *reset = get_color(o->color_diff, DIFF_PLAIN);
+ const char *reset = get_color(o->color_diff, DIFF_RESET);
a_one = quote_two("a/", name_a);
b_two = quote_two("b/", name_b);
memset(&ecbdata, 0, sizeof(ecbdata));
ecbdata.label_path = lbl;
ecbdata.color_diff = o->color_diff;
- xpp.flags = XDF_NEED_MINIMAL;
+ xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
xecfg.ctxlen = o->context;
xecfg.flags = XDL_EMIT_FUNCNAMES;
if (!diffopts)
struct diff_filespec *one,
struct diff_filespec *two,
struct diffstat_t *diffstat,
+ struct diff_options *o,
int complete_rewrite)
{
mmfile_t mf1, mf2;
xdemitconf_t xecfg;
xdemitcb_t ecb;
- xpp.flags = XDF_NEED_MINIMAL;
+ xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
xecfg.ctxlen = 0;
xecfg.flags = 0;
ecb.outf = xdiff_outf;
err_empty:
err = -1;
empty:
- s->data = "";
+ s->data = (char *)"";
s->size = 0;
return err;
}
if (DIFF_PAIR_UNMERGED(p)) {
/* unmerged */
- builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, 0);
+ builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, 0);
return;
}
if (p->status == DIFF_STATUS_MODIFIED && p->score)
complete_rewrite = 1;
- builtin_diffstat(name, other, p->one, p->two, diffstat, complete_rewrite);
+ builtin_diffstat(name, other, p->one, p->two, diffstat, o, complete_rewrite);
}
static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
options->change = diff_change;
options->add_remove = diff_addremove;
+ options->color_diff = diff_use_color_default;
}
int diff_setup_done(struct diff_options *options)
return 0;
}
-int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
+static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
{
char c, *eq;
int len;
}
else if (!strcmp(arg, "--color"))
options->color_diff = 1;
+ else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
+ options->xdl_opts |= XDF_IGNORE_WHITESPACE;
+ else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
+ options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
else
return 0;
return 1;
free((void*)path_two);
}
-static void diff_flush_name(struct diff_filepair *p,
- int inter_name_termination,
- int line_termination)
+static void diff_flush_name(struct diff_filepair *p, int line_termination)
{
char *path = p->two->path;
if (line_termination)
path = quote_one(p->two->path);
- else
- path = p->two->path;
printf("%s%c", path, line_termination);
if (p->two->path != path)
free(path);
options, diff_output_format);
break;
case DIFF_FORMAT_NAME:
- diff_flush_name(p,
- inter_name_termination,
- line_termination);
+ diff_flush_name(p, line_termination);
break;
case DIFF_FORMAT_NO_OUTPUT:
break;