From dd2e794a214350711db46c4e08d9b19188a7d63a Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Mon, 19 Oct 2009 17:48:08 +0200 Subject: [PATCH 1/5] Refactor pretty_print_commit arguments into a struct pretty_print_commit() has a bunch of rarely-used arguments, and introducing more of them requires yet another update of all the call sites. Refactor most of them into a struct to make future extensions easier. The ones that stay "plain" arguments were chosen on the grounds that all callers put real arguments there, whereas some callers have 0/NULL for all arguments that were factored into the struct. We declare the struct 'const' to ensure none of the callers are bitten by the changed (no longer call-by-value) semantics. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- archive.c | 4 +++- builtin-branch.c | 3 ++- builtin-checkout.c | 3 ++- builtin-commit.c | 8 ++++++-- builtin-log.c | 3 ++- builtin-merge.c | 7 +++++-- builtin-rev-list.c | 7 ++++--- builtin-shortlog.c | 9 ++++++--- builtin-show-branch.c | 4 ++-- commit.h | 19 +++++++++++++------ log-tree.c | 24 +++++++++++++----------- pretty.c | 27 ++++++++++++++------------- 12 files changed, 72 insertions(+), 46 deletions(-) diff --git a/archive.c b/archive.c index 0cc79d2a24..55b273246e 100644 --- a/archive.c +++ b/archive.c @@ -31,6 +31,8 @@ static void format_subst(const struct commit *commit, { char *to_free = NULL; struct strbuf fmt = STRBUF_INIT; + struct pretty_print_context ctx = {0}; + ctx.date_mode = DATE_NORMAL; if (src == buf->buf) to_free = strbuf_detach(buf, NULL); @@ -48,7 +50,7 @@ static void format_subst(const struct commit *commit, strbuf_add(&fmt, b + 8, c - b - 8); strbuf_add(buf, src, b - src); - format_commit_message(commit, fmt.buf, buf, DATE_NORMAL); + format_commit_message(commit, fmt.buf, buf, &ctx); len -= c + 1 - src; src = c + 1; } diff --git a/builtin-branch.c b/builtin-branch.c index 9f57992062..05e876e285 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -387,8 +387,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, commit = item->commit; if (commit && !parse_commit(commit)) { + struct pretty_print_context ctx = {0}; pretty_print_commit(CMIT_FMT_ONELINE, commit, - &subject, 0, NULL, NULL, 0, 0); + &subject, &ctx); sub = subject.buf; } diff --git a/builtin-checkout.c b/builtin-checkout.c index d050c3789f..075a49f1a0 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -302,8 +302,9 @@ static void show_local_changes(struct object *head) static void describe_detached_head(char *msg, struct commit *commit) { struct strbuf sb = STRBUF_INIT; + struct pretty_print_context ctx = {0}; parse_commit(commit); - pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0); + pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx); fprintf(stderr, "%s %s... %s\n", msg, find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf); strbuf_release(&sb); diff --git a/builtin-commit.c b/builtin-commit.c index 200ffdaad4..13edeee575 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -684,8 +684,10 @@ static const char *find_author_by_nickname(const char *name) prepare_revision_walk(&revs); commit = get_revision(&revs); if (commit) { + struct pretty_print_context ctx = {0}; + ctx.date_mode = DATE_NORMAL; strbuf_release(&buf); - format_commit_message(commit, "%an <%ae>", &buf, DATE_NORMAL); + format_commit_message(commit, "%an <%ae>", &buf, &ctx); return strbuf_detach(&buf, NULL); } die("No existing author found with '%s'", name); @@ -942,8 +944,10 @@ static void print_summary(const char *prefix, const unsigned char *sha1) initial_commit ? " (root-commit)" : ""); if (!log_tree_commit(&rev, commit)) { + struct pretty_print_context ctx = {0}; struct strbuf buf = STRBUF_INIT; - format_commit_message(commit, format + 7, &buf, DATE_NORMAL); + ctx.date_mode = DATE_NORMAL; + format_commit_message(commit, format + 7, &buf, &ctx); printf("%s\n", buf.buf); strbuf_release(&buf); } diff --git a/builtin-log.c b/builtin-log.c index 25e21ed415..207a36178b 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -1304,8 +1304,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix) if (verbose) { struct strbuf buf = STRBUF_INIT; + struct pretty_print_context ctx = {0}; pretty_print_commit(CMIT_FMT_ONELINE, commit, - &buf, 0, NULL, NULL, 0, 0); + &buf, &ctx); printf("%c %s %s\n", sign, sha1_to_hex(commit->object.sha1), buf.buf); strbuf_release(&buf); diff --git a/builtin-merge.c b/builtin-merge.c index b6b84286b2..c69a3051f3 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -264,6 +264,7 @@ static void squash_message(void) struct strbuf out = STRBUF_INIT; struct commit_list *j; int fd; + struct pretty_print_context ctx = {0}; printf("Squash commit -- not updating HEAD\n"); fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666); @@ -285,13 +286,15 @@ static void squash_message(void) if (prepare_revision_walk(&rev)) die("revision walk setup failed"); + ctx.abbrev = rev.abbrev; + ctx.date_mode = rev.date_mode; + strbuf_addstr(&out, "Squashed commit of the following:\n"); while ((commit = get_revision(&rev)) != NULL) { strbuf_addch(&out, '\n'); strbuf_addf(&out, "commit %s\n", sha1_to_hex(commit->object.sha1)); - pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev, - NULL, NULL, rev.date_mode, 0); + pretty_print_commit(rev.commit_format, commit, &out, &ctx); } if (write(fd, out.buf, out.len) < 0) die_errno("Writing SQUASH_MSG"); diff --git a/builtin-rev-list.c b/builtin-rev-list.c index 4ba1c12e0b..42cc8d8872 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -96,9 +96,10 @@ static void show_commit(struct commit *commit, void *data) if (revs->verbose_header && commit->buffer) { struct strbuf buf = STRBUF_INIT; - pretty_print_commit(revs->commit_format, commit, - &buf, revs->abbrev, NULL, NULL, - revs->date_mode, 0); + struct pretty_print_context ctx = {0}; + ctx.abbrev = revs->abbrev; + ctx.date_mode = revs->date_mode; + pretty_print_commit(revs->commit_format, commit, &buf, &ctx); if (revs->graph) { if (buf.len) { if (revs->commit_format != CMIT_FMT_ONELINE) diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 4d4a3c82d6..8aa63c7857 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -158,9 +158,12 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit) sha1_to_hex(commit->object.sha1)); if (log->user_format) { struct strbuf buf = STRBUF_INIT; - - pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf, - DEFAULT_ABBREV, "", "", DATE_NORMAL, 0); + struct pretty_print_context ctx = {0}; + ctx.abbrev = DEFAULT_ABBREV; + ctx.subject = ""; + ctx.after_subject = ""; + ctx.date_mode = DATE_NORMAL; + pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf, &ctx); insert_one_record(log, author, buf.buf); strbuf_release(&buf); return; diff --git a/builtin-show-branch.c b/builtin-show-branch.c index be95930b78..9f13caa76d 100644 --- a/builtin-show-branch.c +++ b/builtin-show-branch.c @@ -293,8 +293,8 @@ static void show_one_commit(struct commit *commit, int no_name) struct commit_name *name = commit->util; if (commit->object.parsed) { - pretty_print_commit(CMIT_FMT_ONELINE, commit, - &pretty, 0, NULL, NULL, 0, 0); + struct pretty_print_context ctx = {0}; + pretty_print_commit(CMIT_FMT_ONELINE, commit, &pretty, &ctx); pretty_str = pretty.buf; } if (!prefixcmp(pretty_str, "[PATCH] ")) diff --git a/commit.h b/commit.h index f4fc5c5589..011766dee4 100644 --- a/commit.h +++ b/commit.h @@ -63,6 +63,15 @@ enum cmit_fmt { CMIT_FMT_UNSPECIFIED, }; +struct pretty_print_context +{ + int abbrev; + const char *subject; + const char *after_subject; + enum date_mode date_mode; + int need_8bit_cte; +}; + extern int non_ascii(int); extern int has_non_ascii(const char *text); struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */ @@ -71,12 +80,10 @@ extern char *reencode_commit_message(const struct commit *commit, extern void get_commit_format(const char *arg, struct rev_info *); extern void format_commit_message(const struct commit *commit, const void *format, struct strbuf *sb, - enum date_mode dmode); -extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*, - struct strbuf *, - int abbrev, const char *subject, - const char *after_subject, enum date_mode, - int need_8bit_cte); + const struct pretty_print_context *context); +extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, + struct strbuf *sb, + const struct pretty_print_context *context); void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb, const char *line, enum date_mode dmode, const char *encoding); diff --git a/log-tree.c b/log-tree.c index f7d54f2f1b..1675035d84 100644 --- a/log-tree.c +++ b/log-tree.c @@ -179,8 +179,10 @@ void get_patch_filename(struct commit *commit, int nr, const char *suffix, strbuf_addf(buf, commit ? "%04d-" : "%d", nr); if (commit) { int max_len = start_len + FORMAT_PATCH_NAME_MAX - suffix_len; + struct pretty_print_context ctx = {0}; + ctx.date_mode = DATE_NORMAL; - format_commit_message(commit, "%f", buf, DATE_NORMAL); + format_commit_message(commit, "%f", buf, &ctx); if (max_len < buf->len) strbuf_setlen(buf, max_len); strbuf_addstr(buf, suffix); @@ -277,10 +279,9 @@ void show_log(struct rev_info *opt) struct strbuf msgbuf = STRBUF_INIT; struct log_info *log = opt->loginfo; struct commit *commit = log->commit, *parent = log->parent; - int abbrev = opt->diffopt.abbrev; int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40; - const char *subject = NULL, *extra_headers = opt->extra_headers; - int need_8bit_cte = 0; + const char *extra_headers = opt->extra_headers; + struct pretty_print_context ctx = {0}; opt->loginfo = NULL; if (!opt->verbose_header) { @@ -347,8 +348,8 @@ void show_log(struct rev_info *opt) */ if (opt->commit_format == CMIT_FMT_EMAIL) { - log_write_email_headers(opt, commit, &subject, &extra_headers, - &need_8bit_cte); + log_write_email_headers(opt, commit, &ctx.subject, &extra_headers, + &ctx.need_8bit_cte); } else if (opt->commit_format != CMIT_FMT_USERFORMAT) { fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout); if (opt->commit_format != CMIT_FMT_ONELINE) @@ -405,11 +406,12 @@ void show_log(struct rev_info *opt) /* * And then the pretty-printed message itself */ - if (need_8bit_cte >= 0) - need_8bit_cte = has_non_ascii(opt->add_signoff); - pretty_print_commit(opt->commit_format, commit, &msgbuf, - abbrev, subject, extra_headers, opt->date_mode, - need_8bit_cte); + if (ctx.need_8bit_cte >= 0) + ctx.need_8bit_cte = has_non_ascii(opt->add_signoff); + ctx.date_mode = opt->date_mode; + ctx.abbrev = opt->diffopt.abbrev; + ctx.after_subject = extra_headers; + pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx); if (opt->add_signoff) append_signoff(&msgbuf, opt->add_signoff); diff --git a/pretty.c b/pretty.c index f5983f8baa..d6d57ebd23 100644 --- a/pretty.c +++ b/pretty.c @@ -442,7 +442,7 @@ struct chunk { struct format_commit_context { const struct commit *commit; - enum date_mode dmode; + const struct pretty_print_context *pretty_ctx; unsigned commit_header_parsed:1; unsigned commit_message_parsed:1; @@ -711,11 +711,11 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder, case 'a': /* author ... */ return format_person_part(sb, placeholder[1], msg + c->author.off, c->author.len, - c->dmode); + c->pretty_ctx->date_mode); case 'c': /* committer ... */ return format_person_part(sb, placeholder[1], msg + c->committer.off, c->committer.len, - c->dmode); + c->pretty_ctx->date_mode); case 'e': /* encoding */ strbuf_add(sb, msg + c->encoding.off, c->encoding.len); return 1; @@ -741,13 +741,13 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder, void format_commit_message(const struct commit *commit, const void *format, struct strbuf *sb, - enum date_mode dmode) + const struct pretty_print_context *pretty_ctx) { struct format_commit_context context; memset(&context, 0, sizeof(context)); context.commit = commit; - context.dmode = dmode; + context.pretty_ctx = pretty_ctx; strbuf_expand(sb, format, format_commit_item, &context); } @@ -900,18 +900,18 @@ char *reencode_commit_message(const struct commit *commit, const char **encoding } void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, - struct strbuf *sb, int abbrev, - const char *subject, const char *after_subject, - enum date_mode dmode, int need_8bit_cte) + struct strbuf *sb, + const struct pretty_print_context *context) { unsigned long beginning_of_body; int indent = 4; const char *msg = commit->buffer; char *reencoded; const char *encoding; + int need_8bit_cte = context->need_8bit_cte; if (fmt == CMIT_FMT_USERFORMAT) { - format_commit_message(commit, user_format, sb, dmode); + format_commit_message(commit, user_format, sb, context); return; } @@ -946,8 +946,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, } } - pp_header(fmt, abbrev, dmode, encoding, commit, &msg, sb); - if (fmt != CMIT_FMT_ONELINE && !subject) { + pp_header(fmt, context->abbrev, context->date_mode, encoding, + commit, &msg, sb); + if (fmt != CMIT_FMT_ONELINE && !context->subject) { strbuf_addch(sb, '\n'); } @@ -956,8 +957,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, /* These formats treat the title line specially. */ if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL) - pp_title_line(fmt, &msg, sb, subject, - after_subject, encoding, need_8bit_cte); + pp_title_line(fmt, &msg, sb, context->subject, + context->after_subject, encoding, need_8bit_cte); beginning_of_body = sb->len; if (fmt != CMIT_FMT_ONELINE) From 72b103fec7af967d295410c2fd3899bc6e8386e2 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Mon, 19 Oct 2009 17:48:09 +0200 Subject: [PATCH 2/5] reflog-walk: refactor the branch@{num} formatting We'll use the same output in an upcoming commit, so refactor its formatting (which was duplicated anyway) into a separate function. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- reflog-walk.c | 54 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/reflog-walk.c b/reflog-walk.c index 5623ea6b48..596bafebdd 100644 --- a/reflog-walk.c +++ b/reflog-walk.c @@ -241,36 +241,46 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit) commit->object.flags &= ~(ADDED | SEEN | SHOWN); } -void show_reflog_message(struct reflog_walk_info *info, int oneline, +void get_reflog_selector(struct strbuf *sb, + struct reflog_walk_info *reflog_info, + enum date_mode dmode) +{ + struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; + struct reflog_info *info; + + if (!commit_reflog) + return; + + strbuf_addf(sb, "%s@{", commit_reflog->reflogs->ref); + if (commit_reflog->flag || dmode) { + info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; + strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode)); + } else { + strbuf_addf(sb, "%d", commit_reflog->reflogs->nr + - 2 - commit_reflog->recno); + } + + strbuf_addch(sb, '}'); +} + +void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline, enum date_mode dmode) { - if (info && info->last_commit_reflog) { - struct commit_reflog *commit_reflog = info->last_commit_reflog; + if (reflog_info && reflog_info->last_commit_reflog) { + struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; struct reflog_info *info; + struct strbuf selector = STRBUF_INIT; info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; + get_reflog_selector(&selector, reflog_info, dmode); if (oneline) { - printf("%s@{", commit_reflog->reflogs->ref); - if (commit_reflog->flag || dmode) - printf("%s", show_date(info->timestamp, - info->tz, - dmode)); - else - printf("%d", commit_reflog->reflogs->nr - - 2 - commit_reflog->recno); - printf("}: %s", info->message); + printf("%s: %s", selector.buf, info->message); } else { - printf("Reflog: %s@{", commit_reflog->reflogs->ref); - if (commit_reflog->flag || dmode) - printf("%s", show_date(info->timestamp, - info->tz, - dmode)); - else - printf("%d", commit_reflog->reflogs->nr - - 2 - commit_reflog->recno); - printf("} (%s)\nReflog message: %s", - info->email, info->message); + printf("Reflog: %s (%s)\nReflog message: %s", + selector.buf, info->email, info->message); } + + strbuf_release(&selector); } } From 8f8f5476cd6542387d435c242752404cf144005f Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Mon, 19 Oct 2009 17:48:10 +0200 Subject: [PATCH 3/5] Introduce new pretty formats %g[sdD] for reflog information Add three new --pretty=format escapes: %gD long reflog descriptor (e.g. refs/stash@{0}) %gd short reflog descriptor (e.g. stash@{0}) %gs reflog message This is achieved by passing down the reflog info, if any, inside the pretty_print_context struct. We use the newly refactored get_reflog_selector(), and give it some extra functionality to extract a shortened ref. The shortening is cached inside the commit_reflogs struct; the only allocation of it happens in read_complete_reflog(), where it is initialised to 0. Also add another helper get_reflog_message() for the message extraction. Note that the --format="%h %gD: %gs" tests may not work in real repositories, as the --pretty formatter doesn't know to leave away the ": " on the last commit in an incomplete (because git-gc removed the old part) reflog. This equivalence is nevertheless the main goal of this patch. Thanks to Jeff King for reviews, the %gd testcase and documentation. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- Documentation/pretty-formats.txt | 9 ++++++++ commit.h | 1 + log-tree.c | 1 + pretty.c | 17 ++++++++++++++++ reflog-walk.c | 35 +++++++++++++++++++++++++++++--- reflog-walk.h | 8 ++++++++ t/t6006-rev-list-format.sh | 18 ++++++++++++++++ 7 files changed, 86 insertions(+), 3 deletions(-) diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index 2a845b1e57..38b9904791 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -123,6 +123,9 @@ The placeholders are: - '%s': subject - '%f': sanitized subject line, suitable for a filename - '%b': body +- '%gD': reflog selector, e.g., `refs/stash@\{1\}` +- '%gd': shortened reflog selector, e.g., `stash@\{1\}` +- '%gs': reflog subject - '%Cred': switch color to red - '%Cgreen': switch color to green - '%Cblue': switch color to blue @@ -132,6 +135,12 @@ The placeholders are: - '%n': newline - '%x00': print a byte from a hex code +NOTE: Some placeholders may depend on other options given to the +revision traversal engine. For example, the `%g*` reflog options will +insert an empty string unless we are traversing reflog entries (e.g., by +`git log -g`). The `%d` placeholder will use the "short" decoration +format if `--decorate` was not already provided on the command line. + * 'tformat:' + The 'tformat:' format works exactly like 'format:', except that it diff --git a/commit.h b/commit.h index 011766dee4..15cb64920c 100644 --- a/commit.h +++ b/commit.h @@ -70,6 +70,7 @@ struct pretty_print_context const char *after_subject; enum date_mode date_mode; int need_8bit_cte; + struct reflog_walk_info *reflog_info; }; extern int non_ascii(int); diff --git a/log-tree.c b/log-tree.c index 1675035d84..0fdf159f80 100644 --- a/log-tree.c +++ b/log-tree.c @@ -411,6 +411,7 @@ void show_log(struct rev_info *opt) ctx.date_mode = opt->date_mode; ctx.abbrev = opt->diffopt.abbrev; ctx.after_subject = extra_headers; + ctx.reflog_info = opt->reflog_info; pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx); if (opt->add_signoff) diff --git a/pretty.c b/pretty.c index d6d57ebd23..fc65fca58a 100644 --- a/pretty.c +++ b/pretty.c @@ -7,6 +7,7 @@ #include "mailmap.h" #include "log-tree.h" #include "color.h" +#include "reflog-walk.h" static char *user_format; @@ -701,6 +702,22 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder, case 'd': format_decoration(sb, commit); return 1; + case 'g': /* reflog info */ + switch(placeholder[1]) { + case 'd': /* reflog selector */ + case 'D': + if (c->pretty_ctx->reflog_info) + get_reflog_selector(sb, + c->pretty_ctx->reflog_info, + c->pretty_ctx->date_mode, + (placeholder[1] == 'd')); + return 2; + case 's': /* reflog message */ + if (c->pretty_ctx->reflog_info) + get_reflog_message(sb, c->pretty_ctx->reflog_info); + return 2; + } + return 0; /* unknown %g placeholder */ } /* For the rest we have to parse the commit header. */ diff --git a/reflog-walk.c b/reflog-walk.c index 596bafebdd..caba4f743f 100644 --- a/reflog-walk.c +++ b/reflog-walk.c @@ -8,6 +8,7 @@ struct complete_reflogs { char *ref; + const char *short_ref; struct reflog_info { unsigned char osha1[20], nsha1[20]; char *email; @@ -243,15 +244,26 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit) void get_reflog_selector(struct strbuf *sb, struct reflog_walk_info *reflog_info, - enum date_mode dmode) + enum date_mode dmode, + int shorten) { struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; struct reflog_info *info; + const char *printed_ref; if (!commit_reflog) return; - strbuf_addf(sb, "%s@{", commit_reflog->reflogs->ref); + if (shorten) { + if (!commit_reflog->reflogs->short_ref) + commit_reflog->reflogs->short_ref + = shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0); + printed_ref = commit_reflog->reflogs->short_ref; + } else { + printed_ref = commit_reflog->reflogs->ref; + } + + strbuf_addf(sb, "%s@{", printed_ref); if (commit_reflog->flag || dmode) { info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode)); @@ -263,6 +275,23 @@ void get_reflog_selector(struct strbuf *sb, strbuf_addch(sb, '}'); } +void get_reflog_message(struct strbuf *sb, + struct reflog_walk_info *reflog_info) +{ + struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; + struct reflog_info *info; + size_t len; + + if (!commit_reflog) + return; + + info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; + len = strlen(info->message); + if (len > 0) + len--; /* strip away trailing newline */ + strbuf_add(sb, info->message, len); +} + void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline, enum date_mode dmode) { @@ -272,7 +301,7 @@ void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline, struct strbuf selector = STRBUF_INIT; info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; - get_reflog_selector(&selector, reflog_info, dmode); + get_reflog_selector(&selector, reflog_info, dmode, 0); if (oneline) { printf("%s: %s", selector.buf, info->message); } diff --git a/reflog-walk.h b/reflog-walk.h index 74c90964bd..7bd2cd4c4e 100644 --- a/reflog-walk.h +++ b/reflog-walk.h @@ -3,6 +3,8 @@ #include "cache.h" +struct reflog_walk_info; + extern void init_reflog_walk(struct reflog_walk_info** info); extern int add_reflog_for_walk(struct reflog_walk_info *info, struct commit *commit, const char *name); @@ -10,5 +12,11 @@ extern void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit); extern void show_reflog_message(struct reflog_walk_info *info, int, enum date_mode); +extern void get_reflog_message(struct strbuf *sb, + struct reflog_walk_info *reflog_info); +extern void get_reflog_selector(struct strbuf *sb, + struct reflog_walk_info *reflog_info, + enum date_mode dmode, + int shorten); #endif diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index 59d1f6283b..7f61ab0e52 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -162,4 +162,22 @@ test_expect_success 'empty email' ' } ' +test_expect_success '"%h %gD: %gs" is same as git-reflog' ' + git reflog >expect && + git log -g --format="%h %gD: %gs" >actual && + test_cmp expect actual +' + +test_expect_success '"%h %gD: %gs" is same as git-reflog (with date)' ' + git reflog --date=raw >expect && + git log -g --format="%h %gD: %gs" --date=raw >actual && + test_cmp expect actual +' + +test_expect_success '%gd shortens ref name' ' + echo "master@{0}" >expect.gd-short && + git log -g -1 --format=%gd refs/heads/master >actual.gd-short && + test_cmp expect.gd-short actual.gd-short +' + test_done From 391c53bdcd7bbce366eaef7288afb948525ed3e8 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Mon, 19 Oct 2009 17:48:11 +0200 Subject: [PATCH 4/5] stash list: use new %g formats instead of sed With the new formats, we can rewrite 'git stash list' in terms of an appropriate pretty format, instead of hand-editing with sed. This has the advantage that it obeys the normal settings for git-log, notably the pager. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- git-stash.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/git-stash.sh b/git-stash.sh index 4febbbfa5d..f8847c1fc0 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -205,8 +205,7 @@ have_stash () { list_stash () { have_stash || return 0 - git log --no-color --pretty=oneline -g "$@" $ref_stash -- | - sed -n -e 's/^[.0-9a-f]* refs\///p' + git log --format="%gd: %gs" -g "$@" $ref_stash -- } show_stash () { From b7b10385a84c741a4fe219807c9511f69403640a Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Mon, 19 Oct 2009 17:48:12 +0200 Subject: [PATCH 5/5] stash list: drop the default limit of 10 stashes 'git stash list' had an undocumented limit of 10 stashes, unless other git-log arguments were specified. This surprised at least one user, but possibly served to cut the output below a screenful without using a pager. Since the last commit, 'git stash list' will fire up a pager according to the same rules as the 'git log' it calls, so we can drop the limit. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- Documentation/git-stash.txt | 3 +-- git-stash.sh | 5 ----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index fafe728f89..3f14b727b8 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -78,8 +78,7 @@ stash@{1}: On master: 9cc0589... Add git-stash ---------------------------------------------------------------- + The command takes options applicable to the 'git-log' -command to control what is shown and how. If no options are set, the -default is `-n 10`. See linkgit:git-log[1]. +command to control what is shown and how. See linkgit:git-log[1]. show []:: diff --git a/git-stash.sh b/git-stash.sh index f8847c1fc0..f796c2fe24 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -382,11 +382,6 @@ test -n "$seen_non_option" || set "save" "$@" case "$1" in list) shift - if test $# = 0 - then - set x -n 10 - shift - fi list_stash "$@" ;; show)