Merge branch 'jc/blame'
* jc/blame: blame: show "previous" information in --porcelain/--incremental format git-blame: refactor code to emit "porcelain format" output
This commit is contained in:
commit
e46f778968
107
builtin-blame.c
107
builtin-blame.c
@ -74,6 +74,7 @@ static unsigned blame_copy_score;
|
|||||||
*/
|
*/
|
||||||
struct origin {
|
struct origin {
|
||||||
int refcnt;
|
int refcnt;
|
||||||
|
struct origin *previous;
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
mmfile_t file;
|
mmfile_t file;
|
||||||
unsigned char blob_sha1[20];
|
unsigned char blob_sha1[20];
|
||||||
@ -115,6 +116,8 @@ static inline struct origin *origin_incref(struct origin *o)
|
|||||||
static void origin_decref(struct origin *o)
|
static void origin_decref(struct origin *o)
|
||||||
{
|
{
|
||||||
if (o && --o->refcnt <= 0) {
|
if (o && --o->refcnt <= 0) {
|
||||||
|
if (o->previous)
|
||||||
|
origin_decref(o->previous);
|
||||||
free(o->file.ptr);
|
free(o->file.ptr);
|
||||||
free(o);
|
free(o);
|
||||||
}
|
}
|
||||||
@ -1198,6 +1201,10 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt)
|
|||||||
struct origin *porigin = sg_origin[i];
|
struct origin *porigin = sg_origin[i];
|
||||||
if (!porigin)
|
if (!porigin)
|
||||||
continue;
|
continue;
|
||||||
|
if (!origin->previous) {
|
||||||
|
origin_incref(porigin);
|
||||||
|
origin->previous = porigin;
|
||||||
|
}
|
||||||
if (pass_blame_to_parent(sb, origin, porigin))
|
if (pass_blame_to_parent(sb, origin, porigin))
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
@ -1414,6 +1421,39 @@ static void write_filename_info(const char *path)
|
|||||||
write_name_quoted(path, stdout, '\n');
|
write_name_quoted(path, stdout, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Porcelain/Incremental format wants to show a lot of details per
|
||||||
|
* commit. Instead of repeating this every line, emit it only once,
|
||||||
|
* the first time each commit appears in the output.
|
||||||
|
*/
|
||||||
|
static int emit_one_suspect_detail(struct origin *suspect)
|
||||||
|
{
|
||||||
|
struct commit_info ci;
|
||||||
|
|
||||||
|
if (suspect->commit->object.flags & METAINFO_SHOWN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
suspect->commit->object.flags |= METAINFO_SHOWN;
|
||||||
|
get_commit_info(suspect->commit, &ci, 1);
|
||||||
|
printf("author %s\n", ci.author);
|
||||||
|
printf("author-mail %s\n", ci.author_mail);
|
||||||
|
printf("author-time %lu\n", ci.author_time);
|
||||||
|
printf("author-tz %s\n", ci.author_tz);
|
||||||
|
printf("committer %s\n", ci.committer);
|
||||||
|
printf("committer-mail %s\n", ci.committer_mail);
|
||||||
|
printf("committer-time %lu\n", ci.committer_time);
|
||||||
|
printf("committer-tz %s\n", ci.committer_tz);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The blame_entry is found to be guilty for the range. Mark it
|
* The blame_entry is found to be guilty for the range. Mark it
|
||||||
* as such, and show it in incremental output.
|
* as such, and show it in incremental output.
|
||||||
@ -1429,22 +1469,7 @@ static void found_guilty_entry(struct blame_entry *ent)
|
|||||||
printf("%s %d %d %d\n",
|
printf("%s %d %d %d\n",
|
||||||
sha1_to_hex(suspect->commit->object.sha1),
|
sha1_to_hex(suspect->commit->object.sha1),
|
||||||
ent->s_lno + 1, ent->lno + 1, ent->num_lines);
|
ent->s_lno + 1, ent->lno + 1, ent->num_lines);
|
||||||
if (!(suspect->commit->object.flags & METAINFO_SHOWN)) {
|
emit_one_suspect_detail(suspect);
|
||||||
struct commit_info ci;
|
|
||||||
suspect->commit->object.flags |= METAINFO_SHOWN;
|
|
||||||
get_commit_info(suspect->commit, &ci, 1);
|
|
||||||
printf("author %s\n", ci.author);
|
|
||||||
printf("author-mail %s\n", ci.author_mail);
|
|
||||||
printf("author-time %lu\n", ci.author_time);
|
|
||||||
printf("author-tz %s\n", ci.author_tz);
|
|
||||||
printf("committer %s\n", ci.committer);
|
|
||||||
printf("committer-mail %s\n", ci.committer_mail);
|
|
||||||
printf("committer-time %lu\n", ci.committer_time);
|
|
||||||
printf("committer-tz %s\n", ci.committer_tz);
|
|
||||||
printf("summary %s\n", ci.summary);
|
|
||||||
if (suspect->commit->object.flags & UNINTERESTING)
|
|
||||||
printf("boundary\n");
|
|
||||||
}
|
|
||||||
write_filename_info(suspect->path);
|
write_filename_info(suspect->path);
|
||||||
maybe_flush_or_die(stdout, "stdout");
|
maybe_flush_or_die(stdout, "stdout");
|
||||||
}
|
}
|
||||||
@ -1551,24 +1576,8 @@ static void emit_porcelain(struct scoreboard *sb, struct blame_entry *ent)
|
|||||||
ent->s_lno + 1,
|
ent->s_lno + 1,
|
||||||
ent->lno + 1,
|
ent->lno + 1,
|
||||||
ent->num_lines);
|
ent->num_lines);
|
||||||
if (!(suspect->commit->object.flags & METAINFO_SHOWN)) {
|
if (emit_one_suspect_detail(suspect) ||
|
||||||
struct commit_info ci;
|
(suspect->commit->object.flags & MORE_THAN_ONE_PATH))
|
||||||
suspect->commit->object.flags |= METAINFO_SHOWN;
|
|
||||||
get_commit_info(suspect->commit, &ci, 1);
|
|
||||||
printf("author %s\n", ci.author);
|
|
||||||
printf("author-mail %s\n", ci.author_mail);
|
|
||||||
printf("author-time %lu\n", ci.author_time);
|
|
||||||
printf("author-tz %s\n", ci.author_tz);
|
|
||||||
printf("committer %s\n", ci.committer);
|
|
||||||
printf("committer-mail %s\n", ci.committer_mail);
|
|
||||||
printf("committer-time %lu\n", ci.committer_time);
|
|
||||||
printf("committer-tz %s\n", ci.committer_tz);
|
|
||||||
write_filename_info(suspect->path);
|
|
||||||
printf("summary %s\n", ci.summary);
|
|
||||||
if (suspect->commit->object.flags & UNINTERESTING)
|
|
||||||
printf("boundary\n");
|
|
||||||
}
|
|
||||||
else if (suspect->commit->object.flags & MORE_THAN_ONE_PATH)
|
|
||||||
write_filename_info(suspect->path);
|
write_filename_info(suspect->path);
|
||||||
|
|
||||||
cp = nth_line(sb, ent->lno);
|
cp = nth_line(sb, ent->lno);
|
||||||
@ -1806,36 +1815,6 @@ static void sanity_check_refcnt(struct scoreboard *sb)
|
|||||||
baa = 1;
|
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) {
|
if (baa) {
|
||||||
int opt = 0160;
|
int opt = 0160;
|
||||||
find_alignment(sb, &opt);
|
find_alignment(sb, &opt);
|
||||||
|
Loading…
Reference in New Issue
Block a user