On Thu, 12 Jul 2007, Junio C Hamano wrote: > > I think this is just a testament that "following renames" is not > as useful in a real project as people seem to believe, not a > real complaint. Yeah. That said, what you wanted would have actually worked with my original strange patch to "git blame", and in particular that also would allow you to get a "log" for certain lines in the file. So something like git blame -C -Lx,y --log may still make sense to give people. Here's a new version of that patch (I've long since lost the original one, plus it probably wouldn't apply anyway, but it was easy to re-generate). It doesn't set up the revs thing nicely, so trying to add "-p" or "--stat" etc doesn't really get you what you'd want, and "--decorate" doesn't work since it doesn't call "cmd_log_init". So this certainly has some room for improvement, but my point is that "git blame" actually knows all this, and in many ways does a better job than "git log" (but a very *different* job!!). So "git log" gives you the log for a (set of) pathname(s), while with this patch, "git blame --log" gives you the log for the commits that can be *blamed* for the current state of that pathname! Two very different things, but both are valid, and interesting things to do, I think. And I really think it's worth doing, if only because it's so simple, and fits so well with the whole "git blame" structure! Linus --- diff --git a/builtin-blame.c b/builtin-blame.c index 0519339..8de06d3 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -18,6 +18,7 @@ #include "cache-tree.h" #include "path-list.h" #include "mailmap.h" +#include "log-tree.h" static char blame_usage[] = "git-blame [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--contents <filename>] [--incremental] [commit] [--] file\n" @@ -34,6 +35,7 @@ static char blame_usage[] = " -L n,m Process only line range n,m, counting from 1\n" " -M, -C Find line movements within and across files\n" " --incremental Show blame entries as we find them, incrementally\n" +" --log Show blame entries as we find them in 'git log' style\n" " --contents file Use <file>'s contents as the final image\n" " -S revs-file Use revisions from revs-file instead of calling git-rev-list\n"; @@ -45,6 +47,7 @@ static int max_score_digits; static int show_root; static int blank_boundary; static int incremental; +static int blame_log; static int cmd_is_annotate; static int xdl_opts = XDF_NEED_MINIMAL; static struct path_list mailmap; @@ -1431,11 +1434,22 @@ static void write_filename_info(const char *path) * The blame_entry is found to be guilty for the range. Mark it * as such, and show it in incremental output. */ -static void found_guilty_entry(struct blame_entry *ent) +static void found_guilty_entry(struct blame_entry *ent, struct rev_info *rev) { if (ent->guilty) return; ent->guilty = 1; + if (blame_log) { + struct origin *suspect = ent->suspect; + struct commit *commit = suspect->commit; + + if (commit->object.flags & METAINFO_SHOWN) + return; + commit->object.flags |= METAINFO_SHOWN; + log_tree_commit(rev, commit); + maybe_flush_or_die(stdout, "stdout"); + return; + } if (incremental) { struct origin *suspect = ent->suspect; @@ -1505,7 +1519,7 @@ static void assign_blame(struct scoreboard *sb, struct rev_info *revs, int opt) /* Take responsibility for the remaining entries */ for (ent = sb->ent; ent; ent = ent->next) if (same_suspect(ent->suspect, suspect)) - found_guilty_entry(ent); + found_guilty_entry(ent, revs); origin_decref(suspect); if (DEBUG) /* sanity */ @@ -2204,6 +2218,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix) } else if (!strcmp("--incremental", arg)) incremental = 1; + else if (!strcmp("--log", arg)) + save_commit_buffer = incremental = blame_log = 1; else if (!strcmp("--score-debug", arg)) output_option |= OUTPUT_SHOW_SCORE; else if (!strcmp("-f", arg) || @@ -2224,7 +2240,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) argv[unk++] = arg; } - if (!incremental) + if (blame_log || !incremental) setup_pager(); if (!blame_move_score) @@ -2324,7 +2340,14 @@ int cmd_blame(int argc, const char **argv, const char *prefix) argv[unk] = NULL; init_revisions(&revs, NULL); + + /* Maybe we should call "cmd_log_init()" here instead? */ + revs.always_show_header = 1; + revs.commit_format = CMIT_FMT_DEFAULT; + revs.verbose_header = 1; + revs.abbrev = DEFAULT_ABBREV; setup_revisions(unk, argv, &revs, NULL); + memset(&sb, 0, sizeof(sb)); /* - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html