Developers of the world, rejoice! :-)
Junio, Pranit (and whoever is paying attention to the conversation
that was being held about --tips), here's a draft of what I meant when
I was talking about the option of "aggregating" blame output. I'm not
considering _all_ cases yet, just would like for people to give it a
quick test and tell me if they think it's worth "polishing" it for
inclusion into mainline git.
The output would look like this:
$ ./git blame -L 1,19 -t --aggregate builtin/blame.c
Blaming lines: 0% (19/2974), done.
cee7f245dc builtin-pickaxe.c (Junio C Hamano 1161298804 -0700)
1) /*
31653c1abc builtin-blame.c (Eugene Letuchy 1235170271 -0800)
2) * Blame
cee7f245dc builtin-pickaxe.c (Junio C Hamano 1161298804 -0700)
3) *
7e6ac6e439 builtin/blame.c (David Kastrup 1398470209 +0200)
4) * Copyright (c) 2006, 2014 by its authors
5) * See COPYING for licensing conditions
cee7f245dc builtin-pickaxe.c (Junio C Hamano 1161298804 -0700)
6) */
7)
8) #include "cache.h"
fb58c8d507 builtin/blame.c (Michael Haggerty 1434981785 +0200)
9) #include "refs.h"
cee7f245dc builtin-pickaxe.c (Junio C Hamano 1161298804 -0700)
10) #include "builtin.h"
11) #include "blob.h"
12) #include "commit.h"
13) #include "tag.h"
14) #include "tree-walk.h"
15) #include "diff.h"
16) #include "diffcore.h"
17) #include "revision.h"
717d1462ba builtin-blame.c (Linus Torvalds 1169976846 -0800)
18) #include "quote.h"
cee7f245dc builtin-pickaxe.c (Junio C Hamano 1161298804 -0700)
19) #include "xdiff-interface.h"
It can be seen that options like -t still work in aggregation.
In relation to the previous conversation about "tips", I think a
better name could be "hints" and it could be added on top of the
aggregation.
On Mon, Jan 23, 2017 at 8:10 PM, Edmundo Carmona Antoranz
<[email protected]> wrote:
> ---
> builtin/blame.c | 78
> +++++++++++++++++++++++++++++++++++++--------------------
> 1 file changed, 51 insertions(+), 27 deletions(-)
>
> diff --git a/builtin/blame.c b/builtin/blame.c
> index 126b8c9e5..9e8403303 100644
> --- a/builtin/blame.c
> +++ b/builtin/blame.c
> @@ -1884,6 +1884,7 @@ static const char *format_time(unsigned long time,
> const char *tz_str,
> #define OUTPUT_NO_AUTHOR 0200
> #define OUTPUT_SHOW_EMAIL 0400
> #define OUTPUT_LINE_PORCELAIN 01000
> +#define OUTPUT_AGGREGATE 02000
>
> static void emit_porcelain_details(struct origin *suspect, int repeat)
> {
> @@ -1931,43 +1932,36 @@ static void emit_porcelain(struct scoreboard *sb,
> struct blame_entry *ent,
> putchar('\n');
> }
>
> -static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int
> opt)
> +/**
> + * Print information about the revision.
> + * This information can be used in either aggregated output
> + * or prepending each line of the content of the file being blamed
> + */
> +static void print_revision_info(char* revision_hex, int revision_length,
> struct blame_entry* ent,
> + struct commit* commit, struct commit_info ci, int opt, int
> show_raw_time)
> {
> - int cnt;
> - const char *cp;
> - struct origin *suspect = ent->suspect;
> - struct commit_info ci;
> - char hex[GIT_SHA1_HEXSZ + 1];
> - int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);
> -
> - get_commit_info(suspect->commit, &ci, 1);
> - sha1_to_hex_r(hex, suspect->commit->object.oid.hash);
> -
> - cp = nth_line(sb, ent->lno);
> - for (cnt = 0; cnt < ent->num_lines; cnt++) {
> - char ch;
> - int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? GIT_SHA1_HEXSZ
> : abbrev;
> -
> - if (suspect->commit->object.flags & UNINTERESTING) {
> + if (opt & OUTPUT_AGGREGATE)
> + printf("\t");
> + int length = revision_length;
> + if (commit->object.flags & UNINTERESTING) {
> if (blank_boundary)
> - memset(hex, ' ', length);
> + memset(revision_hex, ' ', length);
> else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) {
> length--;
> putchar('^');
> }
> }
>
> - printf("%.*s", length, hex);
> + printf("%.*s", length, revision_hex);
> if (opt & OUTPUT_ANNOTATE_COMPAT) {
> const char *name;
> if (opt & OUTPUT_SHOW_EMAIL)
> name = ci.author_mail.buf;
> else
> name = ci.author.buf;
> - printf("\t(%10s\t%10s\t%d)", name,
> + printf("\t(%10s\t%10s\t", name,
> format_time(ci.author_time, ci.author_tz.buf,
> - show_raw_time),
> - ent->lno + 1 + cnt);
> + show_raw_time));
> } else {
> if (opt & OUTPUT_SHOW_SCORE)
> printf(" %*d %02d",
> @@ -1975,11 +1969,7 @@ static void emit_other(struct scoreboard *sb, struct
> blame_entry *ent, int opt)
> ent->suspect->refcnt);
> if (opt & OUTPUT_SHOW_NAME)
> printf(" %-*.*s", longest_file, longest_file,
> - suspect->path);
> - if (opt & OUTPUT_SHOW_NUMBER)
> - printf(" %*d", max_orig_digits,
> - ent->s_lno + 1 + cnt);
> -
> + ent->suspect->path);
> if (!(opt & OUTPUT_NO_AUTHOR)) {
> const char *name;
> int pad;
> @@ -1994,9 +1984,42 @@ static void emit_other(struct scoreboard *sb, struct
> blame_entry *ent, int opt)
> ci.author_tz.buf,
> show_raw_time));
> }
> + }
> + if (opt & OUTPUT_AGGREGATE)
> + printf(")\n");
> +}
> +
> +static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int
> opt)
> +{
> + int cnt;
> + const char *cp;
> + struct origin *suspect = ent->suspect;
> + struct commit_info ci;
> + char hex[GIT_SHA1_HEXSZ + 1];
> + int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);
> + int revision_length = (opt & OUTPUT_LONG_OBJECT_NAME) ?
> GIT_SHA1_HEXSZ : abbrev;
> +
> + get_commit_info(suspect->commit, &ci, 1);
> + sha1_to_hex_r(hex, suspect->commit->object.oid.hash);
> +
> + if (opt & OUTPUT_AGGREGATE)
> + print_revision_info(hex, revision_length, ent,
> suspect->commit, ci, opt, show_raw_time);
> +
> + cp = nth_line(sb, ent->lno);
> + for (cnt = 0; cnt < ent->num_lines; cnt++) {
> + if (!(opt & OUTPUT_AGGREGATE))
> + print_revision_info(hex, revision_length, ent,
> suspect->commit, ci, opt, show_raw_time);
> + if (opt & OUTPUT_ANNOTATE_COMPAT) {
> + printf("%*d) ",
> + max_digits, ent->lno + 1 + cnt);
> + } else {
> + if (opt & OUTPUT_SHOW_NUMBER)
> + printf(" %*d ", max_orig_digits,
> + ent->s_lno + 1 + cnt);
> printf(" %*d) ",
> max_digits, ent->lno + 1 + cnt);
> }
> + char ch;
> do {
> ch = *cp++;
> putchar(ch);
> @@ -2609,6 +2632,7 @@ int cmd_blame(int argc, const char **argv, const char
> *prefix)
> { OPTION_CALLBACK, 'C', NULL, &opt, N_("score"), N_("Find
> line copies within and across files"), PARSE_OPT_OPTARG, blame_copy_callback
> },
> { OPTION_CALLBACK, 'M', NULL, &opt, N_("score"), N_("Find
> line movements within and across files"), PARSE_OPT_OPTARG,
> blame_move_callback },
> OPT_STRING_LIST('L', NULL, &range_list, N_("n,m"),
> N_("Process only line range n,m, counting from 1")),
> + OPT_BIT(0, "aggregate", &output_option, N_("Aggregate
> output"), OUTPUT_AGGREGATE),
> OPT__ABBREV(&abbrev),
> OPT_END()
> };
> --
> 2.11.0.rc1
>