summaryrefslogtreecommitdiff
path: root/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c72
1 files changed, 37 insertions, 35 deletions
diff --git a/diff.c b/diff.c
index 51603117a9..a1961526c0 100644
--- a/diff.c
+++ b/diff.c
@@ -57,7 +57,7 @@ static int diff_detect_rename_default;
static int diff_indent_heuristic = 1;
static int diff_rename_limit_default = 1000;
static int diff_suppress_blank_empty;
-static int diff_use_color_default = -1;
+static enum git_colorbool diff_use_color_default = GIT_COLOR_UNKNOWN;
static int diff_color_moved_default;
static int diff_color_moved_ws_default;
static int diff_context_default = 3;
@@ -1351,6 +1351,9 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
int len = eds->len;
unsigned flags = eds->flags;
+ if (!o->file)
+ return;
+
switch (s) {
case DIFF_SYMBOL_NO_LF_EOF:
context = diff_get_color_opt(o, DIFF_CONTEXT);
@@ -1672,7 +1675,7 @@ static void emit_hunk_header(struct emit_callback *ecbdata,
const char *frag = diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO);
const char *func = diff_get_color(ecbdata->color_diff, DIFF_FUNCINFO);
const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
- const char *reverse = ecbdata->color_diff ? GIT_COLOR_REVERSE : "";
+ const char *reverse = want_color(ecbdata->color_diff) ? GIT_COLOR_REVERSE : "";
static const char atat[2] = { '@', '@' };
const char *cp, *ep;
struct strbuf msgbuf = STRBUF_INIT;
@@ -1826,7 +1829,7 @@ static void emit_rewrite_diff(const char *name_a,
size_two = fill_textconv(o->repo, textconv_two, two, &data_two);
memset(&ecbdata, 0, sizeof(ecbdata));
- ecbdata.color_diff = want_color(o->use_color);
+ ecbdata.color_diff = o->use_color;
ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b);
ecbdata.opt = o;
if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
@@ -2303,7 +2306,7 @@ static void free_diff_words_data(struct emit_callback *ecbdata)
}
}
-const char *diff_get_color(int diff_use_color, enum color_diff ix)
+const char *diff_get_color(enum git_colorbool diff_use_color, enum color_diff ix)
{
if (want_color(diff_use_color))
return diff_colors[ix];
@@ -3732,7 +3735,7 @@ static void builtin_diff(const char *name_a,
if (o->flags.suppress_diff_headers)
lbl[0] = NULL;
ecbdata.label_path = lbl;
- ecbdata.color_diff = want_color(o->use_color);
+ ecbdata.color_diff = o->use_color;
ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b);
if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
check_blank_at_eof(&mf1, &mf2, &ecbdata);
@@ -3762,9 +3765,9 @@ static void builtin_diff(const char *name_a,
if (o->word_diff)
init_diff_words_data(&ecbdata, o, one, two);
- if (o->dry_run) {
+ if (!o->file) {
/*
- * Unlike the !dry_run case, we need to ignore the
+ * Unlike the normal output case, we need to ignore the
* return value from xdi_diff_outf() here, because
* xdi_diff_outf() takes non-zero return from its
* callback function as a sign of error and returns
@@ -4420,7 +4423,6 @@ static void run_external_diff(const struct external_diff *pgm,
{
struct child_process cmd = CHILD_PROCESS_INIT;
struct diff_queue_struct *q = &diff_queued_diff;
- int quiet = !(o->output_format & DIFF_FORMAT_PATCH);
int rc;
/*
@@ -4429,7 +4431,7 @@ static void run_external_diff(const struct external_diff *pgm,
* external diff program lacks the ability to tell us whether
* it's empty then we consider it non-empty without even asking.
*/
- if (!pgm->trust_exit_code && quiet) {
+ if (!pgm->trust_exit_code && !o->file) {
o->found_changes = 1;
return;
}
@@ -4454,7 +4456,10 @@ static void run_external_diff(const struct external_diff *pgm,
diff_free_filespec_data(one);
diff_free_filespec_data(two);
cmd.use_shell = 1;
- cmd.no_stdout = quiet;
+ if (!o->file)
+ cmd.no_stdout = 1;
+ else if (o->file != stdout)
+ cmd.out = xdup(fileno(o->file));
rc = run_command(&cmd);
if (!pgm->trust_exit_code && rc == 0)
o->found_changes = 1;
@@ -4497,7 +4502,7 @@ static void fill_metainfo(struct strbuf *msg,
struct diff_options *o,
struct diff_filepair *p,
int *must_show_header,
- int use_color)
+ enum git_colorbool use_color)
{
const char *set = diff_get_color(use_color, DIFF_METAINFO);
const char *reset = diff_get_color(use_color, DIFF_RESET);
@@ -4596,7 +4601,7 @@ static void run_diff_cmd(const struct external_diff *pgm,
*/
fill_metainfo(msg, name, other, one, two, o, p,
&must_show_header,
- want_color(o->use_color) && !pgm);
+ pgm ? GIT_COLOR_NEVER : o->use_color);
xfrm_msg = msg->len ? msg->buf : NULL;
}
@@ -4615,7 +4620,8 @@ static void run_diff_cmd(const struct external_diff *pgm,
p->status == DIFF_STATUS_RENAMED)
o->found_changes = 1;
} else {
- fprintf(o->file, "* Unmerged path %s\n", name);
+ if (o->file)
+ fprintf(o->file, "* Unmerged path %s\n", name);
o->found_changes = 1;
}
}
@@ -4995,8 +5001,7 @@ void diff_setup_done(struct diff_options *options)
if (options->flags.follow_renames)
diff_check_follow_pathspec(&options->pathspec, 1);
- if (!options->use_color ||
- (options->flags.allow_external && external_diff()))
+ if (options->flags.allow_external && external_diff())
options->color_moved = 0;
if (options->filter_not) {
@@ -5278,7 +5283,7 @@ static int diff_opt_color_words(const struct option *opt,
struct diff_options *options = opt->value;
BUG_ON_OPT_NEG(unset);
- options->use_color = 1;
+ options->use_color = GIT_COLOR_ALWAYS;
options->word_diff = DIFF_WORDS_COLOR;
options->word_regex = arg;
return 0;
@@ -5600,7 +5605,7 @@ static int diff_opt_word_diff(const struct option *opt,
if (!strcmp(arg, "plain"))
options->word_diff = DIFF_WORDS_PLAIN;
else if (!strcmp(arg, "color")) {
- options->use_color = 1;
+ options->use_color = GIT_COLOR_ALWAYS;
options->word_diff = DIFF_WORDS_COLOR;
}
else if (!strcmp(arg, "porcelain"))
@@ -6193,15 +6198,15 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)
/* return 1 if any change is found; otherwise, return 0 */
static int diff_flush_patch_quietly(struct diff_filepair *p, struct diff_options *o)
{
- int saved_dry_run = o->dry_run;
+ FILE *saved_file = o->file;
int saved_found_changes = o->found_changes;
int ret;
- o->dry_run = 1;
+ o->file = NULL;
o->found_changes = 0;
diff_flush_patch(p, o);
ret = o->found_changes;
- o->dry_run = saved_dry_run;
+ o->file = saved_file;
o->found_changes |= saved_found_changes;
return ret;
}
@@ -6733,7 +6738,7 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
if (WSEH_NEW & WS_RULE_MASK)
BUG("WS rules bit mask overlaps with diff symbol flags");
- if (o->color_moved)
+ if (o->color_moved && want_color(o->use_color))
o->emitted_symbols = &esm;
if (o->additional_path_headers)
@@ -6746,20 +6751,17 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
}
if (o->emitted_symbols) {
- if (o->color_moved) {
- struct mem_pool entry_pool;
- struct moved_entry_list *entry_list;
-
- mem_pool_init(&entry_pool, 1024 * 1024);
- entry_list = add_lines_to_move_detection(o,
- &entry_pool);
- mark_color_as_moved(o, entry_list);
- if (o->color_moved == COLOR_MOVED_ZEBRA_DIM)
- dim_moved_lines(o);
-
- mem_pool_discard(&entry_pool, 0);
- free(entry_list);
- }
+ struct mem_pool entry_pool;
+ struct moved_entry_list *entry_list;
+
+ mem_pool_init(&entry_pool, 1024 * 1024);
+ entry_list = add_lines_to_move_detection(o, &entry_pool);
+ mark_color_as_moved(o, entry_list);
+ if (o->color_moved == COLOR_MOVED_ZEBRA_DIM)
+ dim_moved_lines(o);
+
+ mem_pool_discard(&entry_pool, 0);
+ free(entry_list);
for (i = 0; i < esm.nr; i++)
emit_diff_symbol_from_struct(o, &esm.buf[i]);