Re: git-log --follow?
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));
/*