/* * 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 (unless the * user has specifically asked for us to repeat). */ static int emit_one_suspect_detail(struct blame_origin *suspect, int repeat) { struct commit_info ci; if (!repeat && (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.buf); printf("author-mail %s\n", ci.author_mail.buf); printf("author-time %"PRItime"\n", ci.author_time); printf("author-tz %s\n", ci.author_tz.buf); printf("committer %s\n", ci.committer.buf); printf("committer-mail %s\n", ci.committer_mail.buf); printf("committer-time %"PRItime"\n", ci.committer_time); printf("committer-tz %s\n", ci.committer_tz.buf); printf("summary %s\n", ci.summary.buf); if (suspect->commit->object.flags & UNINTERESTING) printf("boundary\n"); commit_info_destroy(&ci); return 1; }
/* * How many columns do we need to show line numbers, authors, * and filenames? */ static void find_alignment(struct blame_scoreboard *sb, int *option) { int longest_src_lines = 0; int longest_dst_lines = 0; unsigned largest_score = 0; struct blame_entry *e; int compute_auto_abbrev = (abbrev < 0); int auto_abbrev = DEFAULT_ABBREV; for (e = sb->ent; e; e = e->next) { struct blame_origin *suspect = e->suspect; int num; if (compute_auto_abbrev) auto_abbrev = update_auto_abbrev(auto_abbrev, suspect); if (strcmp(suspect->path, sb->path)) *option |= OUTPUT_SHOW_NAME; num = strlen(suspect->path); if (longest_file < num) longest_file = num; if (!(suspect->commit->object.flags & METAINFO_SHOWN)) { struct commit_info ci; suspect->commit->object.flags |= METAINFO_SHOWN; get_commit_info(suspect->commit, &ci, 1); if (*option & OUTPUT_SHOW_EMAIL) num = utf8_strwidth(ci.author_mail.buf); else num = utf8_strwidth(ci.author.buf); if (longest_author < num) longest_author = num; commit_info_destroy(&ci); } num = e->s_lno + e->num_lines; if (longest_src_lines < num) longest_src_lines = num; num = e->lno + e->num_lines; if (longest_dst_lines < num) longest_dst_lines = num; if (largest_score < blame_entry_score(sb, e)) largest_score = blame_entry_score(sb, e); } max_orig_digits = decimal_width(longest_src_lines); max_digits = decimal_width(longest_dst_lines); max_score_digits = decimal_width(largest_score); if (compute_auto_abbrev) /* one more abbrev length is needed for the boundary commit */ abbrev = auto_abbrev + 1; }
void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit) { struct commit_info *commit_info = get_commit_info(commit, &info->reflogs, 0); struct commit_reflog *commit_reflog; struct object *logobj; struct reflog_info *reflog; info->last_commit_reflog = NULL; if (!commit_info) return; commit_reflog = commit_info->util; if (commit_reflog->recno < 0) { commit->parents = NULL; return; } info->last_commit_reflog = commit_reflog; do { reflog = &commit_reflog->reflogs->items[commit_reflog->recno]; commit_reflog->recno--; logobj = parse_object(&reflog->ooid); } while (commit_reflog->recno && (logobj && logobj->type != OBJ_COMMIT)); if (!logobj && commit_reflog->recno >= 0 && is_null_oid(&reflog->ooid)) { /* a root commit, but there are still more entries to show */ reflog = &commit_reflog->reflogs->items[commit_reflog->recno]; logobj = parse_object(&reflog->noid); } if (!logobj || logobj->type != OBJ_COMMIT) { commit_info->commit = NULL; commit->parents = NULL; return; } commit_info->commit = (struct commit *)logobj; commit->parents = xcalloc(1, sizeof(struct commit_list)); commit->parents->item = commit_info->commit; }
static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int opt) { int cnt; const char *cp; struct blame_origin *suspect = ent->suspect; struct commit_info ci; char hex[GIT_MAX_HEXSZ + 1]; int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP); get_commit_info(suspect->commit, &ci, 1); oid_to_hex_r(hex, &suspect->commit->object.oid); cp = blame_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 (blank_boundary) memset(hex, ' ', length); else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) { length--; putchar('^'); } } printf("%.*s", length, 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, format_time(ci.author_time, ci.author_tz.buf, show_raw_time), ent->lno + 1 + cnt); } else { if (opt & OUTPUT_SHOW_SCORE) printf(" %*d %02d", max_score_digits, ent->score, 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); if (!(opt & OUTPUT_NO_AUTHOR)) { const char *name; int pad; if (opt & OUTPUT_SHOW_EMAIL) name = ci.author_mail.buf; else name = ci.author.buf; pad = longest_author - utf8_strwidth(name); printf(" (%s%*s %10s", name, pad, "", format_time(ci.author_time, ci.author_tz.buf, show_raw_time)); } printf(" %*d) ", max_digits, ent->lno + 1 + cnt); } do { ch = *cp++; putchar(ch); } while (ch != '\n' && cp < sb->final_buf + sb->final_buf_size); } if (sb->final_buf_size && cp[-1] != '\n') putchar('\n'); commit_info_destroy(&ci); }