summaryrefslogtreecommitdiff
path: root/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c87
1 files changed, 48 insertions, 39 deletions
diff --git a/diff.c b/diff.c
index 534c12e28e..c6da383c56 100644
--- a/diff.c
+++ b/diff.c
@@ -18,6 +18,7 @@
#include "ll-merge.h"
#include "string-list.h"
#include "argv-array.h"
+#include "graph.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
@@ -131,9 +132,11 @@ static int parse_dirstat_params(struct diff_options *options, const char *params
static int parse_submodule_params(struct diff_options *options, const char *value)
{
if (!strcmp(value, "log"))
- DIFF_OPT_SET(options, SUBMODULE_LOG);
+ options->submodule_format = DIFF_SUBMODULE_LOG;
else if (!strcmp(value, "short"))
- DIFF_OPT_CLR(options, SUBMODULE_LOG);
+ options->submodule_format = DIFF_SUBMODULE_SHORT;
+ else if (!strcmp(value, "diff"))
+ options->submodule_format = DIFF_SUBMODULE_INLINE_DIFF;
else
return -1;
return 0;
@@ -354,7 +357,6 @@ struct emit_callback {
const char **label_path;
struct diff_words_data *diff_words;
struct diff_options *opt;
- int *found_changesp;
struct strbuf *header;
};
@@ -722,7 +724,6 @@ static void emit_rewrite_diff(const char *name_a,
memset(&ecbdata, 0, sizeof(ecbdata));
ecbdata.color_diff = want_color(o->use_color);
- ecbdata.found_changesp = &o->found_changes;
ecbdata.ws_rule = whitespace_rule(name_b);
ecbdata.opt = o;
if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
@@ -1216,12 +1217,13 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
struct diff_options *o = ecbdata->opt;
const char *line_prefix = diff_line_prefix(o);
+ o->found_changes = 1;
+
if (ecbdata->header) {
- fprintf(ecbdata->opt->file, "%s", ecbdata->header->buf);
+ fprintf(o->file, "%s", ecbdata->header->buf);
strbuf_reset(ecbdata->header);
ecbdata->header = NULL;
}
- *(ecbdata->found_changesp) = 1;
if (ecbdata->label_path[0]) {
const char *name_a_tab, *name_b_tab;
@@ -1229,9 +1231,9 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
name_a_tab = strchr(ecbdata->label_path[0], ' ') ? "\t" : "";
name_b_tab = strchr(ecbdata->label_path[1], ' ') ? "\t" : "";
- fprintf(ecbdata->opt->file, "%s%s--- %s%s%s\n",
+ fprintf(o->file, "%s%s--- %s%s%s\n",
line_prefix, meta, ecbdata->label_path[0], reset, name_a_tab);
- fprintf(ecbdata->opt->file, "%s%s+++ %s%s%s\n",
+ fprintf(o->file, "%s%s+++ %s%s%s\n",
line_prefix, meta, ecbdata->label_path[1], reset, name_b_tab);
ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
}
@@ -1249,15 +1251,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
find_lno(line, ecbdata);
emit_hunk_header(ecbdata, line, len);
if (line[len-1] != '\n')
- putc('\n', ecbdata->opt->file);
- return;
- }
-
- if (len < 1) {
- emit_line(ecbdata->opt, reset, reset, line, len);
- if (ecbdata->diff_words
- && ecbdata->diff_words->type == DIFF_WORDS_PORCELAIN)
- fputs("~\n", ecbdata->opt->file);
+ putc('\n', o->file);
return;
}
@@ -1282,8 +1276,8 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
}
diff_words_flush(ecbdata);
if (ecbdata->diff_words->type == DIFF_WORDS_PORCELAIN) {
- emit_line(ecbdata->opt, context, reset, line, len);
- fputs("~\n", ecbdata->opt->file);
+ emit_line(o, context, reset, line, len);
+ fputs("~\n", o->file);
} else {
/*
* Skip the prefix character, if any. With
@@ -1294,7 +1288,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
line++;
len--;
}
- emit_line(ecbdata->opt, context, reset, line, len);
+ emit_line(o, context, reset, line, len);
}
return;
}
@@ -1316,8 +1310,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
default:
/* incomplete line at the end */
ecbdata->lno_in_preimage++;
- emit_line(ecbdata->opt,
- diff_get_color(ecbdata->color_diff, DIFF_CONTEXT),
+ emit_line(o, diff_get_color(ecbdata->color_diff, DIFF_CONTEXT),
reset, line, len);
break;
}
@@ -1625,7 +1618,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
*/
if (options->stat_width == -1)
- width = term_columns() - options->output_prefix_length;
+ width = term_columns() - strlen(line_prefix);
else
width = options->stat_width ? options->stat_width : 80;
number_width = decimal_width(max_change) > number_width ?
@@ -2299,17 +2292,37 @@ static void builtin_diff(const char *name_a,
struct strbuf header = STRBUF_INIT;
const char *line_prefix = diff_line_prefix(o);
- if (DIFF_OPT_TST(o, SUBMODULE_LOG) &&
- (!one->mode || S_ISGITLINK(one->mode)) &&
- (!two->mode || S_ISGITLINK(two->mode))) {
+ diff_set_mnemonic_prefix(o, "a/", "b/");
+ if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
+ a_prefix = o->b_prefix;
+ b_prefix = o->a_prefix;
+ } else {
+ a_prefix = o->a_prefix;
+ b_prefix = o->b_prefix;
+ }
+
+ if (o->submodule_format == DIFF_SUBMODULE_LOG &&
+ (!one->mode || S_ISGITLINK(one->mode)) &&
+ (!two->mode || S_ISGITLINK(two->mode))) {
const char *del = diff_get_color_opt(o, DIFF_FILE_OLD);
const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
show_submodule_summary(o->file, one->path ? one->path : two->path,
line_prefix,
- one->oid.hash, two->oid.hash,
+ &one->oid, &two->oid,
two->dirty_submodule,
meta, del, add, reset);
return;
+ } else if (o->submodule_format == DIFF_SUBMODULE_INLINE_DIFF &&
+ (!one->mode || S_ISGITLINK(one->mode)) &&
+ (!two->mode || S_ISGITLINK(two->mode))) {
+ const char *del = diff_get_color_opt(o, DIFF_FILE_OLD);
+ const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
+ show_submodule_inline_diff(o->file, one->path ? one->path : two->path,
+ line_prefix,
+ &one->oid, &two->oid,
+ two->dirty_submodule,
+ meta, del, add, reset, o);
+ return;
}
if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) {
@@ -2317,15 +2330,6 @@ static void builtin_diff(const char *name_a,
textconv_two = get_textconv(two);
}
- diff_set_mnemonic_prefix(o, "a/", "b/");
- if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
- a_prefix = o->b_prefix;
- b_prefix = o->a_prefix;
- } else {
- a_prefix = o->a_prefix;
- b_prefix = o->b_prefix;
- }
-
/* Never use a non-valid filename anywhere if at all possible */
name_a = DIFF_FILE_VALID(one) ? name_a : name_b;
name_b = DIFF_FILE_VALID(two) ? name_b : name_a;
@@ -2438,7 +2442,6 @@ static void builtin_diff(const char *name_a,
memset(&ecbdata, 0, sizeof(ecbdata));
ecbdata.label_path = lbl;
ecbdata.color_diff = want_color(o->use_color);
- ecbdata.found_changesp = &o->found_changes;
ecbdata.ws_rule = whitespace_rule(name_b);
if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
check_blank_at_eof(&mf1, &mf2, &ecbdata);
@@ -2700,7 +2703,7 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
* This is not the sha1 we are looking for, or
* unreusable because it is not a regular file.
*/
- if (hashcmp(sha1, ce->sha1) || !S_ISREG(ce->ce_mode))
+ if (hashcmp(sha1, ce->oid.hash) || !S_ISREG(ce->ce_mode))
return 0;
/*
@@ -3915,7 +3918,7 @@ int diff_opt_parse(struct diff_options *options,
DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
handle_ignore_submodules_arg(options, arg);
} else if (!strcmp(arg, "--submodule"))
- DIFF_OPT_SET(options, SUBMODULE_LOG);
+ options->submodule_format = DIFF_SUBMODULE_LOG;
else if (skip_prefix(arg, "--submodule=", &arg))
return parse_submodule_opt(options, arg);
else if (skip_prefix(arg, "--ws-error-highlight=", &arg))
@@ -3966,6 +3969,12 @@ int diff_opt_parse(struct diff_options *options,
options->a_prefix = optarg;
return argcount;
}
+ else if ((argcount = parse_long_opt("line-prefix", av, &optarg))) {
+ options->line_prefix = optarg;
+ options->line_prefix_length = strlen(options->line_prefix);
+ graph_setup_line_prefix(options);
+ return argcount;
+ }
else if ((argcount = parse_long_opt("dst-prefix", av, &optarg))) {
options->b_prefix = optarg;
return argcount;