In a later patch, I want to propose an option to detect&color moved lines in a diff, which cannot be done in a one-pass over the diff. Instead we need to go over the whole diff twice, because we cannot detect the first line of the two corresponding lines (+ and -) that got moved. So to prepare the diff machinery for two pass algorithms (i.e. buffer it all up and then operate on the result), move all emissions to places, such that the only emitting function is emit_line_0. This prepares the code for submodules to go through the emit_line_0 function. Signed-off-by: Stefan Beller <sbeller@xxxxxxxxxx> --- diff.c | 5 ++--- diff.h | 3 +++ submodule.c | 42 +++++++++++++++++------------------------- submodule.h | 3 +-- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/diff.c b/diff.c index 3aa99d1..1892c2b 100644 --- a/diff.c +++ b/diff.c @@ -493,7 +493,7 @@ static void emit_line(struct diff_options *o, const char *set, const char *reset emit_line_0(o, set, reset, line[0], line+1, len-1); } -static void emit_line_fmt(struct diff_options *o, +void emit_line_fmt(struct diff_options *o, const char *set, const char *reset, const char *fmt, ...) { @@ -2306,8 +2306,7 @@ static void builtin_diff(const char *name_a, (!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, + show_submodule_summary(o, one->path ? one->path : two->path, one->oid.hash, two->oid.hash, two->dirty_submodule, meta, del, add, reset); diff --git a/diff.h b/diff.h index 7883729..1699d9c 100644 --- a/diff.h +++ b/diff.h @@ -180,6 +180,9 @@ struct diff_options { int diff_path_counter; }; +void emit_line_fmt(struct diff_options *o, const char *set, const char *reset, + const char *fmt, ...); + enum color_diff { DIFF_RESET = 0, DIFF_CONTEXT = 1, diff --git a/submodule.c b/submodule.c index 1b5cdfb..c817b46 100644 --- a/submodule.c +++ b/submodule.c @@ -304,8 +304,8 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path, return prepare_revision_walk(rev); } -static void print_submodule_summary(struct rev_info *rev, FILE *f, - const char *line_prefix, +static void print_submodule_summary(struct rev_info *rev, + struct diff_options *o, const char *del, const char *add, const char *reset) { static const char format[] = " %m %s"; @@ -317,24 +317,16 @@ static void print_submodule_summary(struct rev_info *rev, FILE *f, ctx.date_mode = rev->date_mode; ctx.output_encoding = get_log_output_encoding(); strbuf_setlen(&sb, 0); - strbuf_addstr(&sb, line_prefix); - if (commit->object.flags & SYMMETRIC_LEFT) { - if (del) - strbuf_addstr(&sb, del); - } - else if (add) - strbuf_addstr(&sb, add); format_commit_message(commit, format, &sb, &ctx); - if (reset) - strbuf_addstr(&sb, reset); - strbuf_addch(&sb, '\n'); - fprintf(f, "%s", sb.buf); + if (commit->object.flags & SYMMETRIC_LEFT) + emit_line_fmt(o, del, reset, "%s\n", sb.buf); + else if (add) + emit_line_fmt(o, add, reset, "%s\n", sb.buf); } strbuf_release(&sb); } -void show_submodule_summary(FILE *f, const char *path, - const char *line_prefix, +void show_submodule_summary(struct diff_options *o, const char *path, unsigned char one[20], unsigned char two[20], unsigned dirty_submodule, const char *meta, const char *del, const char *add, const char *reset) @@ -359,30 +351,30 @@ void show_submodule_summary(FILE *f, const char *path, message = "(revision walker failed)"; if (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED) - fprintf(f, "%sSubmodule %s contains untracked content\n", - line_prefix, path); + emit_line_fmt(o, 0, 0, + "Submodule %s contains untracked content\n", path); if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED) - fprintf(f, "%sSubmodule %s contains modified content\n", - line_prefix, path); + emit_line_fmt(o, 0, 0, + "Submodule %s contains modified content\n", path); if (!hashcmp(one, two)) { strbuf_release(&sb); return; } - strbuf_addf(&sb, "%s%sSubmodule %s %s..", line_prefix, meta, path, - find_unique_abbrev(one, DEFAULT_ABBREV)); + strbuf_addf(&sb, "Submodule %s %s..", path, + find_unique_abbrev(one, DEFAULT_ABBREV)); if (!fast_backward && !fast_forward) strbuf_addch(&sb, '.'); strbuf_addf(&sb, "%s", find_unique_abbrev(two, DEFAULT_ABBREV)); if (message) - strbuf_addf(&sb, " %s%s\n", message, reset); + strbuf_addf(&sb, " %s\n", message); else - strbuf_addf(&sb, "%s:%s\n", fast_backward ? " (rewind)" : "", reset); - fwrite(sb.buf, sb.len, 1, f); + strbuf_addf(&sb, "%s:\n", fast_backward ? " (rewind)" : ""); + emit_line_fmt(o, meta, reset, "%s", sb.buf); if (!message) /* only NULL if we succeeded in setting up the walk */ - print_submodule_summary(&rev, f, line_prefix, del, add, reset); + print_submodule_summary(&rev, o, del, add, reset); if (left) clear_commit_marks(left, ~0); if (right) diff --git a/submodule.h b/submodule.h index 2af9390..fefc0ab 100644 --- a/submodule.h +++ b/submodule.h @@ -41,8 +41,7 @@ int parse_submodule_update_strategy(const char *value, struct submodule_update_strategy *dst); const char *submodule_strategy_to_string(const struct submodule_update_strategy *s); void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *); -void show_submodule_summary(FILE *f, const char *path, - const char *line_prefix, +void show_submodule_summary(struct diff_options *o, const char *path, unsigned char one[20], unsigned char two[20], unsigned dirty_submodule, const char *meta, const char *del, const char *add, const char *reset); -- 2.10.0.21.g1da280f.dirty