Improve "git log --graph" output of merges
cover Improve "git log --graph" output of merges
This series changes a couple of places that do not currently indent their output when being shown with a graph.
The first patch was already posted [1] and addresses the output of "git log --graph -c -p". Patch 2 is an independent fix I noticed while working on the later patches.
Patches 3-5 introduce a helper function and change existing sites using diff_options->output_prefix to use it, resulting in a net reduction by about 60 lines. There is no functional change here.
The final patch uses the helper introduced in patch 4 to make combined diffs should the output prefix before each line. This affects the output of "git log --graph --cc [-p|--raw]".
[1] http://article.gmane.org/gmane.comp.version-control.git/215630
John Keeping (6):
graph: output padding for merge subsequent parents
diff: write prefix to the correct file diff.c: make constant string arguments const
diff: add diff_line_prefix function
diff.c: use diff_line_prefix() where applicable combine-diff.c: teach combined diffs about line prefix
combine-diff.c | 47 +++++++++++++-------- diff.c | 131 +++++++++++++++------------------------------------------ diff.h | 3 ++ graph.c | 10 +++++ 4 files changed, 77 insertions(+), 114 deletions(-)
Signature · 1 line
1.8.1.2
PATCH 1/6 graph: output padding for merge subsequent parents
When showing merges in git-log, the same commit is shown once for each parent. Combined with "--graph" this results in graph_show_commit() being called once for each parent without graph_update() being called.
Currently graph_show_commit() does not print anything on subsequent invocations for the same commit (this was changed by commit 656197a - "graph.c: infinite loop in git whatchanged --graph -m" from the previous behaviour of looping infinitely).
Change this so that if the graph code believes it has already shown the commit it prints a single padding line.
--- graph.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
graph.c +10 -0
@@ -1227,6 +1227,16 @@ void graph_show_commit(struct git_graph *graph)if (!graph)return ; +/* +* When showing a diff of a merge against each of its parents, we +* are called once for each parent without graph_update having been +* called. In this case, simply output a single padding line. +*/ +if (graph_is_commit_finished (graph)) { +graph_show_padding (graph); + shown_commit_line =1 ; + } +while (!shown_commit_line && !graph_is_commit_finished (graph)) { shown_commit_line =graph_next_line (graph, &msgbuf);fwrite (msgbuf.buf,sizeof (char ), msgbuf.len, stdout);
Signature · 1 line
1.8.1.2
Re: [PATCH 1/6] graph: output padding for merge subsequent parents
[Moved from the thread where this was initially posted to reply to the series.]
Quoted 11 lines · Matthieu Moy
This works, but if we know we're not going to enter the while loop, it seams even easier to do this:
graph.c +1
-1@@ -1227,7 +1227,17 @@ void graph_show_commit(struct git_graph *graph)if (!graph)return ; -while (!shown_commit_line && !graph_is_commit_finished (graph)) { +/*
graph.c void graph_show_commit(struct git_graph *graph) · line 1240
Quoted 10 lines
graph.c +10
-0+* When showing a diff of a merge against each of its parents, we +* are called once for each parent without graph_update having been +* called. In this case, simply output a single padding line. +*/ +if (graph_is_commit_finished (graph)) { +graph_show_padding (graph); +return ; + } + +while (!shown_commit_line) {
This looks good to me. I'll amend locally and re-send in a few days after giving others a chance to comment.
John
PATCH 2/6 diff: write prefix to the correct file
In reply to John KeepingWrite the prefix for an output line to the same file as the actual content.
--- diff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff.c +1 -1
@@ -4485,7 +4485,7 @@ void diff_flush(struct diff_options *options)struct strbuf *msg =NULL ; msg = options->output_prefix (options, options->output_prefix_data); -fwrite (msg->buf, msg->len,1 , stdout); +fwrite (msg->buf, msg->len,1 , options->file); }putc (options->line_termination, options->file);if (options->stat_sep) {
Signature · 1 line
1.8.1.2
Quoted 11 lines · John Keeping
This series changes a couple of places that do not currently indent their output when being shown with a graph.
The first patch was already posted [1] and addresses the output of "git log --graph -c -p". Patch 2 is an independent fix I noticed while working on the later patches.
Patches 3-5 introduce a helper function and change existing sites using
diff_options->output_prefixto use it, resulting in a net reduction by about 60 lines. There is no functional change here.
Quoted 5 lines
The final patch uses the helper introduced in patch 4 to make combined diffs should the output prefix before each line. This affects the output of "git log --graph --cc [-p|--raw]".
[1] http://article.gmane.org/gmane.comp.version-control.git/215630
Overall direction looks sensible.
It is a bit scary that we are doing the the fifth one now, as opposed to catching this repetitiveness during the initial review of patch series that added the graph code to the diff codepath.
Thanks.
Quoted 13 lines
John Keeping (6):
graph: output padding for merge subsequent parents
diff: write prefix to the correct filediff.c: make constant string arguments const
diff: adddiff_line_prefixfunction
diff.c: usediff_line_prefix()where applicablecombine-diff.c: teach combined diffs about line prefixcombine-diff.c | 47 +++++++++++++-------- diff.c | 131 +++++++++++++++------------------------------------------ diff.h | 3 ++ graph.c | 10 +++++ 4 files changed, 77 insertions(+), 114 deletions(-)
PATCH 3/6 diff.c: make constant string arguments const
In reply to John Keeping--- diff.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff.c +4 -2
@@ -2123,7 +2123,8 @@ static unsigned char *deflate_it(char *data,return deflated; } -static void emit_binary_diff_body (FILE *file,mmfile_t *one,mmfile_t *two,char *prefix) +static void emit_binary_diff_body (FILE *file,mmfile_t *one,mmfile_t *two, +const char *prefix) {void *cp;void *delta;
@@ -2184,7 +2185,8 @@ static void emit_binary_diff_body(FILE *file, mmfile_t *one, mmfile_t *two, charfree (data); } -static void emit_binary_diff (FILE *file,mmfile_t *one,mmfile_t *two,char *prefix) +static void emit_binary_diff (FILE *file,mmfile_t *one,mmfile_t *two, +const char *prefix) {fprintf (file,"%sGIT binary patch\n" , prefix);emit_binary_diff_body (file, one, two, prefix);
Signature · 1 line
1.8.1.2
PATCH 4/6 diff: add diff_line_prefix function
In reply to John KeepingThis is a helper function to call the diff output_prefix function and return its value as a C string, allowing us to greatly simplify everywhere that needs to get the output prefix.
--- diff.c | 10 ++++++++++ diff.h | 3 +++ 2 files changed, 13 insertions(+)
diff.c +10 -0
@@ -1105,6 +1105,16 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix)return "" ; } +const char *diff_line_prefix (struct diff_options *opt) +{ +struct strbuf *msgbuf; +if (!opt->output_prefix) +return "" ; + + msgbuf = opt->output_prefix (opt, opt->output_prefix_data); +return msgbuf->buf; +} +static unsigned long sane_truncate_line (struct emit_callback *ecb,char *line,unsigned long len) {const char *cp;
diff.h +3 -0
@@ -174,6 +174,9 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix); diff_get_color((o)->use_color, ix) +const char *diff_line_prefix (struct diff_options *); + +extern const char mime_boundary_leader[];extern void diff_tree_setup_paths (const char **paths,struct diff_options *);
Signature · 1 line
1.8.1.2
PATCH 5/6 diff.c: use diff_line_prefix() where applicable
In reply to John Keeping--- diff.c | 115 ++++++++++++----------------------------------------------------- 1 file changed, 20 insertions(+), 95 deletions(-)
diff.c +20 -95
@@ -402,12 +402,7 @@ static void emit_line_0(struct diff_options *o, const char *set, const char *resint nofirst;FILE *file = o->file; -if (o->output_prefix) { -struct strbuf *msg =NULL ; - msg = o->output_prefix (o, o->output_prefix_data); -assert (msg); -fwrite (msg->buf, msg->len,1 , file); - } +fputs (diff_line_prefix (o), file);if (len ==0 ) { has_trailing_newline = (first =='\n' );
@@ -625,13 +620,7 @@ static void emit_rewrite_diff(const char *name_a,char *data_one, *data_two;size_t size_one, size_two;struct emit_callback ecbdata; -char *line_prefix ="" ; -struct strbuf *msgbuf; - -if (o && o->output_prefix) { - msgbuf = o->output_prefix (o, o->output_prefix_data); - line_prefix = msgbuf->buf; - } +const char *line_prefix =diff_line_prefix (o);if (diff_mnemonic_prefix &&DIFF_OPT_TST (o,REVERSE_DIFF )) { a_prefix = o->b_prefix;
@@ -827,18 +816,14 @@ static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len)int minus_first, minus_len, plus_first, plus_len;const char *minus_begin, *minus_end, *plus_begin, *plus_end;struct diff_options *opt = diff_words->opt; -struct strbuf *msgbuf; -char *line_prefix ="" ; +const char *line_prefix;if (line[0 ] !='@' ||parse_hunk_header (line, len, &minus_first, &minus_len, &plus_first, &plus_len))return ;assert (opt); -if (opt->output_prefix) { - msgbuf = opt->output_prefix (opt, opt->output_prefix_data); - line_prefix = msgbuf->buf; - } + line_prefix =diff_line_prefix (opt);/* POSIX requires that first be decremented by one if len == 0... */ if (minus_len) {
@@ -962,14 +947,10 @@ static void diff_words_show(struct diff_words_data *diff_words)struct diff_words_style *style = diff_words->style;struct diff_options *opt = diff_words->opt; -struct strbuf *msgbuf; -char *line_prefix ="" ; +const char *line_prefix;assert (opt); -if (opt->output_prefix) { - msgbuf = opt->output_prefix (opt, opt->output_prefix_data); - line_prefix = msgbuf->buf; - } + line_prefix =diff_line_prefix (opt);/* special case: only removal */ if (!diff_words->plus.text.size) {
@@ -1155,13 +1136,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)const char *plain =diff_get_color (ecbdata->color_diff,DIFF_PLAIN );const char *reset =diff_get_color (ecbdata->color_diff,DIFF_RESET );struct diff_options *o = ecbdata->opt; -char *line_prefix ="" ; -struct strbuf *msgbuf; - -if (o && o->output_prefix) { - msgbuf = o->output_prefix (o, o->output_prefix_data); - line_prefix = msgbuf->buf; - } +const char *line_prefix =diff_line_prefix (o);if (ecbdata->header) {fprintf (ecbdata->opt->file,"%s" , ecbdata->header->buf);
@@ -1485,16 +1460,11 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)const char *reset, *add_c, *del_c;const char *line_prefix ="" ;int extra_shown =0 ; -struct strbuf *msg =NULL ;if (data->nr ==0 )return ; -if (options->output_prefix) { - msg = options->output_prefix (options, options->output_prefix_data); - line_prefix = msg->buf; - } - + line_prefix =diff_line_prefix (options); count = options->stat_count ? options->stat_count : data->nr; reset =diff_get_color_opt (options,DIFF_RESET );
@@ -1746,12 +1716,7 @@ static void show_shortstats(struct diffstat_t *data, struct diff_options *option dels += deleted; } } -if (options->output_prefix) { -struct strbuf *msg =NULL ; - msg = options->output_prefix (options, - options->output_prefix_data); -fprintf (options->file,"%s" , msg->buf); - } +fprintf (options->file,"%s" ,diff_line_prefix (options));print_stat_summary (options->file, total_files, adds, dels); }
@@ -1765,12 +1730,7 @@ static void show_numstat(struct diffstat_t *data, struct diff_options *options)for (i =0 ; i < data->nr; i++) {struct diffstat_file *file = data->files[i]; -if (options->output_prefix) { -struct strbuf *msg =NULL ; - msg = options->output_prefix (options, - options->output_prefix_data); -fprintf (options->file,"%s" , msg->buf); - } +fprintf (options->file,"%s" ,diff_line_prefix (options));if (file->is_binary)fprintf (options->file,"-\t-\t" );
@@ -1812,13 +1772,7 @@ static long gather_dirstat(struct diff_options *opt, struct dirstat_dir *dir, {unsigned long this_dir =0 ;unsigned int sources =0 ; -const char *line_prefix ="" ; -struct strbuf *msg =NULL ; - -if (opt->output_prefix) { - msg = opt->output_prefix (opt, opt->output_prefix_data); - line_prefix = msg->buf; - } +const char *line_prefix =diff_line_prefix (opt);while (dir->nr) {struct dirstat_file *f = dir->files;
@@ -2068,15 +2022,10 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)const char *reset =diff_get_color (data->o->use_color,DIFF_RESET );const char *set =diff_get_color (data->o->use_color,DIFF_FILE_NEW );char *err; -char *line_prefix ="" ; -struct strbuf *msgbuf; +const char *line_prefix;assert (data->o); -if (data->o->output_prefix) { - msgbuf = data->o->output_prefix (data->o, - data->o->output_prefix_data); - line_prefix = msgbuf->buf; - } + line_prefix =diff_line_prefix (data->o);if (line[0 ] =='+' ) {unsigned bad;
@@ -2263,13 +2212,7 @@ static void builtin_diff(const char *name_a,struct userdiff_driver *textconv_one =NULL ;struct userdiff_driver *textconv_two =NULL ;struct strbuf header =STRBUF_INIT ; -struct strbuf *msgbuf; -char *line_prefix ="" ; - -if (o->output_prefix) { - msgbuf = o->output_prefix (o, o->output_prefix_data); - line_prefix = msgbuf->buf; - } +const char *line_prefix =diff_line_prefix (o); if (DIFF_OPT_TST(o, SUBMODULE_LOG) && (!one->mode || S_ISGITLINK(one->mode)) &&
@@ -2968,14 +2911,9 @@ static void fill_metainfo(struct strbuf *msg, {const char *set =diff_get_color (use_color,DIFF_METAINFO );const char *reset =diff_get_color (use_color,DIFF_RESET ); -struct strbuf *msgbuf; -char *line_prefix ="" ; +const char *line_prefix =diff_line_prefix (o); *must_show_header =1 ; -if (o->output_prefix) { - msgbuf = o->output_prefix (o, o->output_prefix_data); - line_prefix = msgbuf->buf; - }strbuf_init (msg,PATH_MAX *2 +300 );switch (p->status) {case DIFF_STATUS_COPIED :
@@ -3912,12 +3850,8 @@ static void diff_flush_raw(struct diff_filepair *p, struct diff_options *opt) {int line_termination = opt->line_termination;int inter_name_termination = line_termination ?'\t' :'\0' ; -if (opt->output_prefix) { -struct strbuf *msg =NULL ; - msg = opt->output_prefix (opt, opt->output_prefix_data); -fprintf (opt->file,"%s" , msg->buf); - } +fprintf (opt->file,"%s" ,diff_line_prefix (opt));if (!(opt->output_format &DIFF_FORMAT_NAME_STATUS )) {fprintf (opt->file,":%06o %06o %s " , p->one->mode, p->two->mode,diff_unique_abbrev (p->one->sha1, opt->abbrev));
@@ -4187,12 +4121,7 @@ static void show_rename_copy(FILE *file, const char *renamecopy, struct diff_filstatic void diff_summary (struct diff_options *opt,struct diff_filepair *p) {FILE *file = opt->file; -char *line_prefix ="" ; - -if (opt->output_prefix) { -struct strbuf *buf = opt->output_prefix (opt, opt->output_prefix_data); - line_prefix = buf->buf; - } +const char *line_prefix =diff_line_prefix (opt);switch (p->status) {case DIFF_STATUS_DELETED :
@@ -4493,13 +4422,9 @@ void diff_flush(struct diff_options *options)if (output_format &DIFF_FORMAT_PATCH ) {if (separator) { -if (options->output_prefix) { -struct strbuf *msg =NULL ; - msg = options->output_prefix (options, - options->output_prefix_data); -fwrite (msg->buf, msg->len,1 , options->file); - } -putc (options->line_termination, options->file); +fprintf (options->file,"%s%c" , +diff_line_prefix (options), + options->line_termination);if (options->stat_sep) {/* attach patch instead of inline */ fputs (options->stat_sep, options->file);
Signature · 1 line
1.8.1.2
PATCH 6/6 combine-diff.c: teach combined diffs about line prefix
In reply to John KeepingWhen running "git log --graph --cc -p" the diff output for merges is not indented by the graph structure, unlike the diffs of non-merge commits (added in commit 7be5761 - diff.c: Output the text graph padding before each diff line).
Fix this by teaching the combined diff code to output diff_line_prefix() before each line.
--- combine-diff.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-)
combine-diff.c +30 -17
@@ -526,7 +526,8 @@ static void show_line_to_eol(const char *line, int len, const char *reset) saw_cr_at_eol ? "\r" : ""); } -static void dump_sline (struct sline *sline,unsigned long cnt,int num_parent, +static void dump_sline (struct sline *sline,const char *line_prefix, +unsigned long cnt,int num_parent,int use_color,int result_deleted) {unsigned long mark = (1UL <<num_parent);
@@ -582,7 +583,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent, rlines -= null_context; } -fputs (c_frag, stdout); +printf ("%s%s" , line_prefix, c_frag);for (i =0 ; i <= num_parent; i++)putchar (combine_marker);for (i =0 ; i < num_parent; i++)show_parent_lno (sline, lno, hunk_end, i, null_context);
@@ -614,7 +615,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,struct sline *sl = &sline[lno++]; ll = (sl->flag & no_pre_delete) ?NULL : sl->lost_head;while (ll) { -fputs (c_old, stdout); +printf ("%s%s" , line_prefix, c_old);for (j =0 ; j < num_parent; j++) {if (ll->parent_map & (1UL <<j))putchar ('-' );
@@ -627,6 +628,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,if (cnt < lno)break ; p_mask =1 ; +fputs (line_prefix, stdout);if (!(sl->flag & (mark-1 ))) {/* * This sline was here to hang the
@@ -680,11 +682,13 @@ static void reuse_combine_diff(struct sline *sline, unsigned long cnt,static void dump_quoted_path (const char *head,const char *prefix,const char *path, +const char *line_prefix,const char *c_meta,const char *c_reset) {static struct strbuf buf =STRBUF_INIT ;strbuf_reset (&buf); +strbuf_addstr (&buf, line_prefix);strbuf_addstr (&buf, c_meta);strbuf_addstr (&buf, head);quote_two_c_style (&buf, prefix, path,0 );
@@ -696,6 +700,7 @@ static void show_combined_header(struct combine_diff_path *elem,int num_parent, int dense, struct rev_info *rev, + const char *line_prefix, int mode_differs, int show_file_header) {
@@ -714,8 +719,8 @@ static void show_combined_header(struct combine_diff_path *elem,show_log (rev);dump_quoted_path (dense ?"diff --cc " :"diff --combined " , -"" , elem->path, c_meta, c_reset); -printf ("%sindex " , c_meta); +"" , elem->path, line_prefix, c_meta, c_reset); +printf ("%s%sindex " , line_prefix, c_meta);for (i =0 ; i < num_parent; i++) { abb =find_unique_abbrev (elem->parent[i].sha1, abbrev);
@@ -734,11 +739,12 @@ static void show_combined_header(struct combine_diff_path *elem, DIFF_STATUS_ADDED) added =0 ;if (added) -printf ("%snew file mode %06o" , - c_meta, elem->mode); +printf ("%s%snew file mode %06o" , + line_prefix, c_meta, elem->mode);else {if (deleted) -printf ("%sdeleted file " , c_meta); +printf ("%s%sdeleted file " , + line_prefix, c_meta);printf ("mode " );for (i =0 ; i < num_parent; i++) { printf("%s%06o", i ? "," : "",
@@ -755,16 +761,16 @@ static void show_combined_header(struct combine_diff_path *elem,if (added)dump_quoted_path ("--- " ,"" ,"/dev/null" , - c_meta, c_reset); + line_prefix, c_meta, c_reset);else dump_quoted_path ("--- " , a_prefix, elem->path, - c_meta, c_reset); + line_prefix, c_meta, c_reset);if (deleted)dump_quoted_path ("+++ " ,"" ,"/dev/null" , - c_meta, c_reset); + line_prefix, c_meta, c_reset);else dump_quoted_path ("+++ " , b_prefix, elem->path, - c_meta, c_reset); + line_prefix, c_meta, c_reset); } static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
@@ -782,6 +788,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,struct userdiff_driver *userdiff;struct userdiff_driver *textconv =NULL ;int is_binary; +const char *line_prefix =diff_line_prefix (opt); context = opt->context; userdiff =userdiff_find_by_path (elem->path);
@@ -901,7 +908,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, }if (is_binary) {show_combined_header (elem, num_parent, dense, rev, - mode_differs,0 ); + line_prefix, mode_differs,0 );printf ("Binary files differ\n" );free (result);return ;
@@ -962,8 +969,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,if (show_hunks || mode_differs || working_tree_file) {show_combined_header (elem, num_parent, dense, rev, - mode_differs,1 ); -dump_sline (sline, cnt, num_parent, + line_prefix, mode_differs,1 ); +dump_sline (sline, line_prefix, cnt, num_parent, opt->use_color, result_deleted); }free (result);
@@ -990,6 +997,7 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct reint i, offset;const char *prefix;int line_termination, inter_name_termination; +const char *line_prefix =diff_line_prefix (opt); line_termination = opt->line_termination; inter_name_termination ='\t' ;
@@ -1000,6 +1008,7 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct reshow_log (rev);if (opt->output_format &DIFF_FORMAT_RAW ) { +printf ("%s" , line_prefix); offset =strlen (COLONS ) - num_parent;if (offset <0 ) offset =0 ;
@@ -1040,6 +1049,7 @@ void show_combined_diff(struct combine_diff_path *p, struct rev_info *rev) {struct diff_options *opt = &rev->diffopt; +if (!p->len)return ; if (opt->output_format & (DIFF_FORMAT_RAW |
@@ -1150,8 +1160,10 @@ void diff_tree_combined(const unsigned char *sha1,if (show_log_first && i ==0 ) {show_log (rev); +if (rev->verbose_header && opt->output_format) -putchar (opt->line_termination); +printf ("%s%c" ,diff_line_prefix (opt), + opt->line_termination); }diff_flush (&diffopts); }
@@ -1179,7 +1191,8 @@ void diff_tree_combined(const unsigned char *sha1,if (opt->output_format &DIFF_FORMAT_PATCH ) {if (needsep) -putchar (opt->line_termination); +printf ("%s%c" ,diff_line_prefix (opt), + opt->line_termination);for (p = paths; p; p = p->next) {if (p->len) show_patch_diff(p, num_parent, dense,
Signature · 1 line
1.8.1.2