diff options
author | Junio C Hamano <gitster@pobox.com> | 2008-06-04 22:58:40 -0700 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2008-10-12 13:21:51 -0700 |
commit | 96e117099c0e4f7d508eb071f60b6275038f6f37 (patch) | |
tree | e4879be8b4b1c6288a34842428e36657e75743ec | |
parent | 9991030c0c97285087e5da86cfdbaf143a8a74cb (diff) | |
download | git-96e117099c0e4f7d508eb071f60b6275038f6f37.tar.gz git-96e117099c0e4f7d508eb071f60b6275038f6f37.tar.xz |
blame: show "previous" information in --porcelain/--incremental format
When the final blame is laid for a line to a <commit, path> pair, it also
gives a "previous" information to --porcelain and --incremental output
format. It gives the parent commit of the blamed commit, _and_ a path in
that parent commit that corresponds to the blamed path --- in short, it is
the origin that would have been blamed (or passed blame through) for the
line _if_ the blamed commit did not change that line.
This unfortunately makes sanity checking of refcount quite complex, so I
ripped it out for now.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | builtin-blame.c | 42 |
1 files changed, 12 insertions, 30 deletions
diff --git a/builtin-blame.c b/builtin-blame.c index 163d2dc34..e38612059 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -73,6 +73,7 @@ static unsigned blame_copy_score; */ struct origin { int refcnt; + struct origin *previous; struct commit *commit; mmfile_t file; unsigned char blob_sha1[20]; @@ -114,6 +115,8 @@ static inline struct origin *origin_incref(struct origin *o) static void origin_decref(struct origin *o) { if (o && --o->refcnt <= 0) { + if (o->previous) + origin_decref(o->previous); free(o->file.ptr); free(o); } @@ -1292,6 +1295,10 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt) struct origin *porigin = sg_origin[i]; if (!porigin) continue; + if (!origin->previous) { + origin_incref(porigin); + origin->previous = porigin; + } if (pass_blame_to_parent(sb, origin, porigin)) goto finish; } @@ -1515,6 +1522,11 @@ static int emit_one_suspect_detail(struct origin *suspect) printf("summary %s\n", ci.summary); if (suspect->commit->object.flags & UNINTERESTING) printf("boundary\n"); + if (suspect->previous) { + struct origin *prev = suspect->previous; + printf("previous %s ", sha1_to_hex(prev->commit->object.sha1)); + write_name_quoted(prev->path, stdout, '\n'); + } return 1; } @@ -1878,36 +1890,6 @@ static void sanity_check_refcnt(struct scoreboard *sb) baa = 1; } } - for (ent = sb->ent; ent; ent = ent->next) { - /* Mark the ones that haven't been checked */ - if (0 < ent->suspect->refcnt) - ent->suspect->refcnt = -ent->suspect->refcnt; - } - for (ent = sb->ent; ent; ent = ent->next) { - /* - * ... then pick each and see if they have the the - * correct refcnt. - */ - int found; - struct blame_entry *e; - struct origin *suspect = ent->suspect; - - if (0 < suspect->refcnt) - continue; - suspect->refcnt = -suspect->refcnt; /* Unmark */ - for (found = 0, e = sb->ent; e; e = e->next) { - if (e->suspect != suspect) - continue; - found++; - } - if (suspect->refcnt != found) { - fprintf(stderr, "%s in %s has refcnt %d, not %d\n", - ent->suspect->path, - sha1_to_hex(ent->suspect->commit->object.sha1), - ent->suspect->refcnt, found); - baa = 2; - } - } if (baa) { int opt = 0160; find_alignment(sb, &opt); |