{"thread":{"id":"21254","subject":"[PATCH v2 2/5] reflog-walk: refactor the branch@{num} formatting","startedAt":"2009-10-15T22:41:43Z","lastAt":"2009-10-19T15:48:12Z","messageCount":31,"participants":["Thomas Rast","Jeff King","Jakub Narebski","Junio C Hamano","Nanako Shiraishi"],"isPatch":true,"patchVersion":2,"patchTotal":5},"messages":[{"id":"125118","messageId":"cover.1255645570.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"20091014050645.GD31810@coredump.intra.peff.net","subject":"[PATCH v2 0/5] Pretty formats for reflog data","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-15T22:41:43Z","receivedAt":"2009-10-15T22:41:43Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Jeff King wrote:\n> Maybe a better solution would be a \"short name\" variant for pretty\n> format specifiers. We already have %(refname) and %(refname:short) [...]\n> The tricky part would be deciding on a syntax. This seems to come up a\n> fair bit.\n\nOk, I settled for %g[dDs] for now to save on letters.  I'm saving the\nsyntax question for a later series while we discuss this one ;-)\n\nI think going for %(...) wouldn't be too bad since we already have\nthat in for-each-ref, and it can be backwards compatible.  So we would\nhave different sets of short and long specifiers, e.g.\n\n  %ae = %(authoremail)\n  %aE = %(authoremail:mailmap)\n\nWe can then pass arguments via some yet-to-be decided syntax, say,\n%(body:indent(10)).\n\nOther changes in this version include:\n\n* I followed your struct suggestion, which is the new 1/5.\n\n* Since the shortening can be handled by %gd, the old 5/5 (change from\n  refs/stash to only stash) is no longer needed.\n\n* I fixed the warning that Junio found (and finally found the right\n  combination of -W flags, though I cannot compile with -Werror myself\n  because of *other* warnings...)\n\nI also added tests and docs to the main patch (now 3/5).\n\nThomas Rast (5):\n  Refactor pretty_print_commit arguments into a struct\n  reflog-walk: refactor the branch@{num} formatting\n  Introduce new pretty formats %g[sdD] for reflog information\n  stash list: use new %g formats instead of sed\n  stash list: drop the default limit of 10 stashes\n\n Documentation/pretty-formats.txt |    3 +\n builtin-branch.c                 |    3 +-\n builtin-checkout.c               |    3 +-\n builtin-log.c                    |    3 +-\n builtin-merge.c                  |    7 ++-\n builtin-rev-list.c               |    7 ++-\n builtin-shortlog.c               |    9 +++-\n builtin-show-branch.c            |    4 +-\n commit.h                         |   20 ++++++---\n git-stash.sh                     |    8 +---\n log-tree.c                       |   21 +++++----\n pretty.c                         |   44 ++++++++++++++------\n reflog-walk.c                    |   85 ++++++++++++++++++++++++++++----------\n reflog-walk.h                    |    8 ++++\n t/t1411-reflog-show.sh           |   12 +++++\n 15 files changed, 166 insertions(+), 71 deletions(-)\n"},{"id":"125117","messageId":"9d3d0f0a6126afc86689138adf58ac7a12c43858.1255645570.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255645570.git.trast@student.ethz.ch","subject":"[PATCH v2 1/5] Refactor pretty_print_commit arguments into a struct","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-15T22:41:44Z","receivedAt":"2009-10-15T22:41:44Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"pretty_print_commit() has a bunch of rarely-used arguments, and\nintroducing more of them requires yet another update of all the call\nsites.  Refactor most of them into a struct to make future extensions\neasier.\n\nThe ones that stay \"plain\" arguments were chosen on the grounds that\nall callers put real arguments there, whereas some callers have 0/NULL\nfor all arguments that were factored into the struct.\n\nWe declare the struct 'const' to ensure none of the callers are bitten\nby the changed (no longer call-by-value) semantics.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n builtin-branch.c      |    3 ++-\n builtin-checkout.c    |    3 ++-\n builtin-log.c         |    3 ++-\n builtin-merge.c       |    7 +++++--\n builtin-rev-list.c    |    7 ++++---\n builtin-shortlog.c    |    9 ++++++---\n builtin-show-branch.c |    4 ++--\n commit.h              |   19 +++++++++++++------\n log-tree.c            |   20 ++++++++++----------\n pretty.c              |   27 ++++++++++++++-------------\n 10 files changed, 60 insertions(+), 42 deletions(-)\n\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex 9f57992..05e876e 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -387,8 +387,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,\n \n \t\tcommit = item->commit;\n \t\tif (commit && !parse_commit(commit)) {\n+\t\t\tstruct pretty_print_context ctx = {0};\n \t\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t\t\t    &subject, 0, NULL, NULL, 0, 0);\n+\t\t\t\t\t    &subject, &ctx);\n \t\t\tsub = subject.buf;\n \t\t}\n \ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex d050c37..075a49f 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -302,8 +302,9 @@ static void show_local_changes(struct object *head)\n static void describe_detached_head(char *msg, struct commit *commit)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n+\tstruct pretty_print_context ctx = {0};\n \tparse_commit(commit);\n-\tpretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);\n+\tpretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx);\n \tfprintf(stderr, \"%s %s... %s\\n\", msg,\n \t\tfind_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);\n \tstrbuf_release(&sb);\ndiff --git a/builtin-log.c b/builtin-log.c\nindex 25e21ed..207a361 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -1304,8 +1304,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)\n \n \t\tif (verbose) {\n \t\t\tstruct strbuf buf = STRBUF_INIT;\n+\t\t\tstruct pretty_print_context ctx = {0};\n \t\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t                    &buf, 0, NULL, NULL, 0, 0);\n+\t\t\t\t\t    &buf, &ctx);\n \t\t\tprintf(\"%c %s %s\\n\", sign,\n \t\t\t       sha1_to_hex(commit->object.sha1), buf.buf);\n \t\t\tstrbuf_release(&buf);\ndiff --git a/builtin-merge.c b/builtin-merge.c\nindex b6b8428..c69a305 100644\n--- a/builtin-merge.c\n+++ b/builtin-merge.c\n@@ -264,6 +264,7 @@ static void squash_message(void)\n \tstruct strbuf out = STRBUF_INIT;\n \tstruct commit_list *j;\n \tint fd;\n+\tstruct pretty_print_context ctx = {0};\n \n \tprintf(\"Squash commit -- not updating HEAD\\n\");\n \tfd = open(git_path(\"SQUASH_MSG\"), O_WRONLY | O_CREAT, 0666);\n@@ -285,13 +286,15 @@ static void squash_message(void)\n \tif (prepare_revision_walk(&rev))\n \t\tdie(\"revision walk setup failed\");\n \n+\tctx.abbrev = rev.abbrev;\n+\tctx.date_mode = rev.date_mode;\n+\n \tstrbuf_addstr(&out, \"Squashed commit of the following:\\n\");\n \twhile ((commit = get_revision(&rev)) != NULL) {\n \t\tstrbuf_addch(&out, '\\n');\n \t\tstrbuf_addf(&out, \"commit %s\\n\",\n \t\t\tsha1_to_hex(commit->object.sha1));\n-\t\tpretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,\n-\t\t\tNULL, NULL, rev.date_mode, 0);\n+\t\tpretty_print_commit(rev.commit_format, commit, &out, &ctx);\n \t}\n \tif (write(fd, out.buf, out.len) < 0)\n \t\tdie_errno(\"Writing SQUASH_MSG\");\ndiff --git a/builtin-rev-list.c b/builtin-rev-list.c\nindex 4ba1c12..42cc8d8 100644\n--- a/builtin-rev-list.c\n+++ b/builtin-rev-list.c\n@@ -96,9 +96,10 @@ static void show_commit(struct commit *commit, void *data)\n \n \tif (revs->verbose_header && commit->buffer) {\n \t\tstruct strbuf buf = STRBUF_INIT;\n-\t\tpretty_print_commit(revs->commit_format, commit,\n-\t\t\t\t    &buf, revs->abbrev, NULL, NULL,\n-\t\t\t\t    revs->date_mode, 0);\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tctx.abbrev = revs->abbrev;\n+\t\tctx.date_mode = revs->date_mode;\n+\t\tpretty_print_commit(revs->commit_format, commit, &buf, &ctx);\n \t\tif (revs->graph) {\n \t\t\tif (buf.len) {\n \t\t\t\tif (revs->commit_format != CMIT_FMT_ONELINE)\ndiff --git a/builtin-shortlog.c b/builtin-shortlog.c\nindex 4d4a3c8..8aa63c7 100644\n--- a/builtin-shortlog.c\n+++ b/builtin-shortlog.c\n@@ -158,9 +158,12 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)\n \t\t    sha1_to_hex(commit->object.sha1));\n \tif (log->user_format) {\n \t\tstruct strbuf buf = STRBUF_INIT;\n-\n-\t\tpretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf,\n-\t\t\tDEFAULT_ABBREV, \"\", \"\", DATE_NORMAL, 0);\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tctx.abbrev = DEFAULT_ABBREV;\n+\t\tctx.subject = \"\";\n+\t\tctx.after_subject = \"\";\n+\t\tctx.date_mode = DATE_NORMAL;\n+\t\tpretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf, &ctx);\n \t\tinsert_one_record(log, author, buf.buf);\n \t\tstrbuf_release(&buf);\n \t\treturn;\ndiff --git a/builtin-show-branch.c b/builtin-show-branch.c\nindex be95930..9f13caa 100644\n--- a/builtin-show-branch.c\n+++ b/builtin-show-branch.c\n@@ -293,8 +293,8 @@ static void show_one_commit(struct commit *commit, int no_name)\n \tstruct commit_name *name = commit->util;\n \n \tif (commit->object.parsed) {\n-\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t\t    &pretty, 0, NULL, NULL, 0, 0);\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit, &pretty, &ctx);\n \t\tpretty_str = pretty.buf;\n \t}\n \tif (!prefixcmp(pretty_str, \"[PATCH] \"))\ndiff --git a/commit.h b/commit.h\nindex f4fc5c5..011766d 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -63,6 +63,15 @@ enum cmit_fmt {\n \tCMIT_FMT_UNSPECIFIED,\n };\n \n+struct pretty_print_context\n+{\n+\tint abbrev;\n+\tconst char *subject;\n+\tconst char *after_subject;\n+\tenum date_mode date_mode;\n+\tint need_8bit_cte;\n+};\n+\n extern int non_ascii(int);\n extern int has_non_ascii(const char *text);\n struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */\n@@ -71,12 +80,10 @@ enum cmit_fmt {\n extern void get_commit_format(const char *arg, struct rev_info *);\n extern void format_commit_message(const struct commit *commit,\n \t\t\t\t  const void *format, struct strbuf *sb,\n-\t\t\t\t  enum date_mode dmode);\n-extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,\n-                                struct strbuf *,\n-                                int abbrev, const char *subject,\n-                                const char *after_subject, enum date_mode,\n-\t\t\t\tint need_8bit_cte);\n+\t\t\t\t  const struct pretty_print_context *context);\n+extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n+\t\t\t\tstruct strbuf *sb,\n+\t\t\t\tconst struct pretty_print_context *context);\n void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,\n \t\t   const char *line, enum date_mode dmode,\n \t\t   const char *encoding);\ndiff --git a/log-tree.c b/log-tree.c\nindex f7d54f2..f57487f 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -277,10 +277,9 @@ void show_log(struct rev_info *opt)\n \tstruct strbuf msgbuf = STRBUF_INIT;\n \tstruct log_info *log = opt->loginfo;\n \tstruct commit *commit = log->commit, *parent = log->parent;\n-\tint abbrev = opt->diffopt.abbrev;\n \tint abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;\n-\tconst char *subject = NULL, *extra_headers = opt->extra_headers;\n-\tint need_8bit_cte = 0;\n+\tconst char *extra_headers = opt->extra_headers;\n+\tstruct pretty_print_context ctx = {0};\n \n \topt->loginfo = NULL;\n \tif (!opt->verbose_header) {\n@@ -347,8 +346,8 @@ void show_log(struct rev_info *opt)\n \t */\n \n \tif (opt->commit_format == CMIT_FMT_EMAIL) {\n-\t\tlog_write_email_headers(opt, commit, &subject, &extra_headers,\n-\t\t\t\t\t&need_8bit_cte);\n+\t\tlog_write_email_headers(opt, commit, &ctx.subject, &extra_headers,\n+\t\t\t\t\t&ctx.need_8bit_cte);\n \t} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {\n \t\tfputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);\n \t\tif (opt->commit_format != CMIT_FMT_ONELINE)\n@@ -405,11 +404,12 @@ void show_log(struct rev_info *opt)\n \t/*\n \t * And then the pretty-printed message itself\n \t */\n-\tif (need_8bit_cte >= 0)\n-\t\tneed_8bit_cte = has_non_ascii(opt->add_signoff);\n-\tpretty_print_commit(opt->commit_format, commit, &msgbuf,\n-\t\t\t    abbrev, subject, extra_headers, opt->date_mode,\n-\t\t\t    need_8bit_cte);\n+\tif (ctx.need_8bit_cte >= 0)\n+\t\tctx.need_8bit_cte = has_non_ascii(opt->add_signoff);\n+\tctx.date_mode = opt->date_mode;\n+\tctx.abbrev = opt->diffopt.abbrev;\n+\tctx.after_subject = extra_headers;\n+\tpretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);\n \n \tif (opt->add_signoff)\n \t\tappend_signoff(&msgbuf, opt->add_signoff);\ndiff --git a/pretty.c b/pretty.c\nindex f5983f8..d6d57eb 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -442,7 +442,7 @@ struct chunk {\n \n struct format_commit_context {\n \tconst struct commit *commit;\n-\tenum date_mode dmode;\n+\tconst struct pretty_print_context *pretty_ctx;\n \tunsigned commit_header_parsed:1;\n \tunsigned commit_message_parsed:1;\n \n@@ -711,11 +711,11 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,\n \tcase 'a':\t/* author ... */\n \t\treturn format_person_part(sb, placeholder[1],\n \t\t\t\t   msg + c->author.off, c->author.len,\n-\t\t\t\t   c->dmode);\n+\t\t\t\t   c->pretty_ctx->date_mode);\n \tcase 'c':\t/* committer ... */\n \t\treturn format_person_part(sb, placeholder[1],\n \t\t\t\t   msg + c->committer.off, c->committer.len,\n-\t\t\t\t   c->dmode);\n+\t\t\t\t   c->pretty_ctx->date_mode);\n \tcase 'e':\t/* encoding */\n \t\tstrbuf_add(sb, msg + c->encoding.off, c->encoding.len);\n \t\treturn 1;\n@@ -741,13 +741,13 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,\n \n void format_commit_message(const struct commit *commit,\n \t\t\t   const void *format, struct strbuf *sb,\n-\t\t\t   enum date_mode dmode)\n+\t\t\t   const struct pretty_print_context *pretty_ctx)\n {\n \tstruct format_commit_context context;\n \n \tmemset(&context, 0, sizeof(context));\n \tcontext.commit = commit;\n-\tcontext.dmode = dmode;\n+\tcontext.pretty_ctx = pretty_ctx;\n \tstrbuf_expand(sb, format, format_commit_item, &context);\n }\n \n@@ -900,18 +900,18 @@ void pp_remainder(enum cmit_fmt fmt,\n }\n \n void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n-\t\t\t struct strbuf *sb, int abbrev,\n-\t\t\t const char *subject, const char *after_subject,\n-\t\t\t enum date_mode dmode, int need_8bit_cte)\n+\t\t\t struct strbuf *sb,\n+\t\t\t const struct pretty_print_context *context)\n {\n \tunsigned long beginning_of_body;\n \tint indent = 4;\n \tconst char *msg = commit->buffer;\n \tchar *reencoded;\n \tconst char *encoding;\n+\tint need_8bit_cte = context->need_8bit_cte;\n \n \tif (fmt == CMIT_FMT_USERFORMAT) {\n-\t\tformat_commit_message(commit, user_format, sb, dmode);\n+\t\tformat_commit_message(commit, user_format, sb, context);\n \t\treturn;\n \t}\n \n@@ -946,8 +946,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n \t\t}\n \t}\n \n-\tpp_header(fmt, abbrev, dmode, encoding, commit, &msg, sb);\n-\tif (fmt != CMIT_FMT_ONELINE && !subject) {\n+\tpp_header(fmt, context->abbrev, context->date_mode, encoding,\n+\t\t  commit, &msg, sb);\n+\tif (fmt != CMIT_FMT_ONELINE && !context->subject) {\n \t\tstrbuf_addch(sb, '\\n');\n \t}\n \n@@ -956,8 +957,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n \n \t/* These formats treat the title line specially. */\n \tif (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)\n-\t\tpp_title_line(fmt, &msg, sb, subject,\n-\t\t\t      after_subject, encoding, need_8bit_cte);\n+\t\tpp_title_line(fmt, &msg, sb, context->subject,\n+\t\t\t      context->after_subject, encoding, need_8bit_cte);\n \n \tbeginning_of_body = sb->len;\n \tif (fmt != CMIT_FMT_ONELINE)\n-- \n1.6.5.18.g9f87a.dirty\n"},{"id":"125114","messageId":"6dab88e2a1624ae37dbc0c8fd86e4ea486c809a6.1255645570.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255645570.git.trast@student.ethz.ch","subject":"[PATCH v2 2/5] reflog-walk: refactor the branch@{num} formatting","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-15T22:41:45Z","receivedAt":"2009-10-15T22:41:45Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"We'll use the same output in an upcoming commit, so refactor its\nformatting (which was duplicated anyway) into a separate function.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n reflog-walk.c |   54 ++++++++++++++++++++++++++++++++----------------------\n 1 files changed, 32 insertions(+), 22 deletions(-)\n\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 5623ea6..596bafe 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -241,36 +241,46 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)\n \tcommit->object.flags &= ~(ADDED | SEEN | SHOWN);\n }\n \n-void show_reflog_message(struct reflog_walk_info *info, int oneline,\n+void get_reflog_selector(struct strbuf *sb,\n+\t\t\t struct reflog_walk_info *reflog_info,\n+\t\t\t enum date_mode dmode)\n+{\n+\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n+\tstruct reflog_info *info;\n+\n+\tif (!commit_reflog)\n+\t\treturn;\n+\n+\tstrbuf_addf(sb, \"%s@{\", commit_reflog->reflogs->ref);\n+\tif (commit_reflog->flag || dmode) {\n+\t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\t\tstrbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));\n+\t} else {\n+\t\tstrbuf_addf(sb, \"%d\", commit_reflog->reflogs->nr\n+\t\t\t    - 2 - commit_reflog->recno);\n+\t}\n+\n+\tstrbuf_addch(sb, '}');\n+}\n+\n+void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \tenum date_mode dmode)\n {\n-\tif (info && info->last_commit_reflog) {\n-\t\tstruct commit_reflog *commit_reflog = info->last_commit_reflog;\n+\tif (reflog_info && reflog_info->last_commit_reflog) {\n+\t\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n \t\tstruct reflog_info *info;\n+\t\tstruct strbuf selector = STRBUF_INIT;\n \n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\t\tget_reflog_selector(&selector, reflog_info, dmode);\n \t\tif (oneline) {\n-\t\t\tprintf(\"%s@{\", commit_reflog->reflogs->ref);\n-\t\t\tif (commit_reflog->flag || dmode)\n-\t\t\t\tprintf(\"%s\", show_date(info->timestamp,\n-\t\t\t\t\t\t       info->tz,\n-\t\t\t\t\t\t       dmode));\n-\t\t\telse\n-\t\t\t\tprintf(\"%d\", commit_reflog->reflogs->nr\n-\t\t\t\t       - 2 - commit_reflog->recno);\n-\t\t\tprintf(\"}: %s\", info->message);\n+\t\t\tprintf(\"%s: %s\", selector.buf, info->message);\n \t\t}\n \t\telse {\n-\t\t\tprintf(\"Reflog: %s@{\", commit_reflog->reflogs->ref);\n-\t\t\tif (commit_reflog->flag || dmode)\n-\t\t\t\tprintf(\"%s\", show_date(info->timestamp,\n-\t\t\t\t\t\t\tinfo->tz,\n-\t\t\t\t\t\t\tdmode));\n-\t\t\telse\n-\t\t\t\tprintf(\"%d\", commit_reflog->reflogs->nr\n-\t\t\t\t       - 2 - commit_reflog->recno);\n-\t\t\tprintf(\"} (%s)\\nReflog message: %s\",\n-\t\t\t       info->email, info->message);\n+\t\t\tprintf(\"Reflog: %s (%s)\\nReflog message: %s\",\n+\t\t\t       selector.buf, info->email, info->message);\n \t\t}\n+\n+\t\tstrbuf_release(&selector);\n \t}\n }\n-- \n1.6.5.18.g9f87a.dirty\n"},{"id":"125116","messageId":"012c71c4eab143691bc5e2d62b421f8c84effa0e.1255645570.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255645570.git.trast@student.ethz.ch","subject":"[PATCH v2 3/5] Introduce new pretty formats %g[sdD] for reflog information","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-15T22:41:46Z","receivedAt":"2009-10-15T22:41:46Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Add three new --pretty=format escapes:\n\n  %gD  long  reflog descriptor (e.g. refs/stash@{0})\n  %gd  short reflog descriptor (e.g. stash@{0})\n  %gs  reflog message\n\nThis is achieved by passing down the reflog info, if any, inside the\npretty_print_context struct.\n\nWe use the newly refactored get_reflog_selector(), and give it some\nextra functionality to extract a shortened ref.  The shortening has a\nvery simple 1-element cache, since it will usually be called with the\nsame ref every time.  Add another helper get_reflog_message() for the\nmessage extraction.\n\nNote that the --format=\"%h %gD: %gs\" tests may not work in real\nrepositories, as the --pretty formatter doesn't know to leave away the\n\": \" on the last commit in an incomplete (because git-gc removed the\nold part) reflog.  This equivalence is nevertheless the main goal of\nthis patch.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n Documentation/pretty-formats.txt |    3 +++\n commit.h                         |    1 +\n log-tree.c                       |    1 +\n pretty.c                         |   17 +++++++++++++++++\n reflog-walk.c                    |   37 ++++++++++++++++++++++++++++++++++---\n reflog-walk.h                    |    8 ++++++++\n t/t1411-reflog-show.sh           |   12 ++++++++++++\n 7 files changed, 76 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 2a845b1..6359272 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -123,6 +123,9 @@ The placeholders are:\n - '%s': subject\n - '%f': sanitized subject line, suitable for a filename\n - '%b': body\n+- '%gD': reflog selector, e.g., `refs/stash@{1}`\n+- '%gd': shortened reflog selector, e.g., `stash@{1}`\n+- '%gs': reflog subject\n - '%Cred': switch color to red\n - '%Cgreen': switch color to green\n - '%Cblue': switch color to blue\ndiff --git a/commit.h b/commit.h\nindex 011766d..15cb649 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -70,6 +70,7 @@ struct pretty_print_context\n \tconst char *after_subject;\n \tenum date_mode date_mode;\n \tint need_8bit_cte;\n+\tstruct reflog_walk_info *reflog_info;\n };\n \n extern int non_ascii(int);\ndiff --git a/log-tree.c b/log-tree.c\nindex f57487f..8e782fc 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -409,6 +409,7 @@ void show_log(struct rev_info *opt)\n \tctx.date_mode = opt->date_mode;\n \tctx.abbrev = opt->diffopt.abbrev;\n \tctx.after_subject = extra_headers;\n+\tctx.reflog_info = opt->reflog_info;\n \tpretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);\n \n \tif (opt->add_signoff)\ndiff --git a/pretty.c b/pretty.c\nindex d6d57eb..fc65fca 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -7,6 +7,7 @@\n #include \"mailmap.h\"\n #include \"log-tree.h\"\n #include \"color.h\"\n+#include \"reflog-walk.h\"\n \n static char *user_format;\n \n@@ -701,6 +702,22 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,\n \tcase 'd':\n \t\tformat_decoration(sb, commit);\n \t\treturn 1;\n+\tcase 'g':\t\t/* reflog info */\n+\t\tswitch(placeholder[1]) {\n+\t\tcase 'd':\t/* reflog selector */\n+\t\tcase 'D':\n+\t\t\tif (c->pretty_ctx->reflog_info)\n+\t\t\t\tget_reflog_selector(sb,\n+\t\t\t\t\t\t    c->pretty_ctx->reflog_info,\n+\t\t\t\t\t\t    c->pretty_ctx->date_mode,\n+\t\t\t\t\t\t    (placeholder[1] == 'd'));\n+\t\t\treturn 2;\n+\t\tcase 's':\t/* reflog message */\n+\t\t\tif (c->pretty_ctx->reflog_info)\n+\t\t\t\tget_reflog_message(sb, c->pretty_ctx->reflog_info);\n+\t\t\treturn 2;\n+\t\t}\n+\t\treturn 0;\t/* unknown %g placeholder */\n \t}\n \n \t/* For the rest we have to parse the commit header. */\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 596bafe..6c6867b 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -243,15 +243,29 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)\n \n void get_reflog_selector(struct strbuf *sb,\n \t\t\t struct reflog_walk_info *reflog_info,\n-\t\t\t enum date_mode dmode)\n+\t\t\t enum date_mode dmode,\n+\t\t\t int shorten)\n {\n \tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n \tstruct reflog_info *info;\n+\tstatic const char *last_ref = NULL;\n+\tstatic char *last_short_ref = NULL;\n+\tconst char *printed_ref;\n \n \tif (!commit_reflog)\n \t\treturn;\n \n-\tstrbuf_addf(sb, \"%s@{\", commit_reflog->reflogs->ref);\n+\tif (shorten) {\n+\t\tif (last_ref != commit_reflog->reflogs->ref) {\n+\t\t\tfree(last_short_ref);\n+\t\t\tlast_short_ref = shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);\n+\t\t}\n+\t\tprinted_ref = last_short_ref;\n+\t} else {\n+\t\tprinted_ref = commit_reflog->reflogs->ref;\n+\t}\n+\n+\tstrbuf_addf(sb, \"%s@{\", printed_ref);\n \tif (commit_reflog->flag || dmode) {\n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n \t\tstrbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));\n@@ -263,6 +277,23 @@ void get_reflog_selector(struct strbuf *sb,\n \tstrbuf_addch(sb, '}');\n }\n \n+void get_reflog_message(struct strbuf *sb,\n+\t\t\tstruct reflog_walk_info *reflog_info)\n+{\n+\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n+\tstruct reflog_info *info;\n+\tsize_t len;\n+\n+\tif (!commit_reflog)\n+\t\treturn;\n+\n+\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\tlen = strlen(info->message);\n+\tif (len > 0)\n+\t\tlen--; /* strip away trailing newline */\n+\tstrbuf_add(sb, info->message, len);\n+}\n+\n void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \tenum date_mode dmode)\n {\n@@ -272,7 +303,7 @@ void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \t\tstruct strbuf selector = STRBUF_INIT;\n \n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n-\t\tget_reflog_selector(&selector, reflog_info, dmode);\n+\t\tget_reflog_selector(&selector, reflog_info, dmode, 0);\n \t\tif (oneline) {\n \t\t\tprintf(\"%s: %s\", selector.buf, info->message);\n \t\t}\ndiff --git a/reflog-walk.h b/reflog-walk.h\nindex 74c9096..7bd2cd4 100644\n--- a/reflog-walk.h\n+++ b/reflog-walk.h\n@@ -3,6 +3,8 @@\n \n #include \"cache.h\"\n \n+struct reflog_walk_info;\n+\n extern void init_reflog_walk(struct reflog_walk_info** info);\n extern int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\tstruct commit *commit, const char *name);\n@@ -10,5 +12,11 @@ extern void fake_reflog_parent(struct reflog_walk_info *info,\n \t\tstruct commit *commit);\n extern void show_reflog_message(struct reflog_walk_info *info, int,\n \t\tenum date_mode);\n+extern void get_reflog_message(struct strbuf *sb,\n+\t\tstruct reflog_walk_info *reflog_info);\n+extern void get_reflog_selector(struct strbuf *sb,\n+\t\tstruct reflog_walk_info *reflog_info,\n+\t\tenum date_mode dmode,\n+\t\tint shorten);\n \n #endif\ndiff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh\nindex c18ed8e..cb8d0fd 100755\n--- a/t/t1411-reflog-show.sh\n+++ b/t/t1411-reflog-show.sh\n@@ -64,4 +64,16 @@ test_expect_success 'using --date= shows reflog date (oneline)' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success '--format=\"%h %gD: %gs\" is same as git-reflog' '\n+\tgit reflog >expect &&\n+\tgit log -g --format=\"%h %gD: %gs\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--format=\"%h %gD: %gs\" is same as git-reflog (with date)' '\n+\tgit reflog --date=raw >expect &&\n+\tgit log -g --format=\"%h %gD: %gs\" --date=raw >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n1.6.5.18.g9f87a.dirty\n"},{"id":"125115","messageId":"2d36cdc7b3b71ea9fd40e50cce1acfaeaed48a69.1255645570.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255645570.git.trast@student.ethz.ch","subject":"[PATCH v2 4/5] stash list: use new %g formats instead of sed","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-15T22:41:47Z","receivedAt":"2009-10-15T22:41:47Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"With the new formats, we can rewrite 'git stash list' in terms of an\nappropriate pretty format, instead of hand-editing with sed.  This has\nthe advantage that it obeys the normal settings for git-log, notably\nthe pager.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n git-stash.sh |    3 +--\n 1 files changed, 1 insertions(+), 2 deletions(-)\n\ndiff --git a/git-stash.sh b/git-stash.sh\nindex 4febbbf..f8847c1 100755\n--- a/git-stash.sh\n+++ b/git-stash.sh\n@@ -205,8 +205,7 @@ have_stash () {\n \n list_stash () {\n \thave_stash || return 0\n-\tgit log --no-color --pretty=oneline -g \"$@\" $ref_stash -- |\n-\tsed -n -e 's/^[.0-9a-f]* refs\\///p'\n+\tgit log --format=\"%gd: %gs\" -g \"$@\" $ref_stash --\n }\n \n show_stash () {\n-- \n1.6.5.18.g9f87a.dirty\n"},{"id":"125119","messageId":"08377f64e00bec26e69f88c4c1d6769b9f366935.1255645570.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255645570.git.trast@student.ethz.ch","subject":"[PATCH v2 5/5] stash list: drop the default limit of 10 stashes","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-15T22:41:48Z","receivedAt":"2009-10-15T22:41:48Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"'git stash list' had an undocumented limit of 10 stashes, unless other\ngit-log arguments were specified.  This surprised at least one user,\nbut possibly served to cut the output below a screenful without using\na pager.\n\nSince the last commit, 'git stash list' will fire up a pager according\nto the same rules as the 'git log' it calls, so we can drop the limit.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n git-stash.sh |    5 -----\n 1 files changed, 0 insertions(+), 5 deletions(-)\n\ndiff --git a/git-stash.sh b/git-stash.sh\nindex f8847c1..f796c2f 100755\n--- a/git-stash.sh\n+++ b/git-stash.sh\n@@ -382,11 +382,6 @@ test -n \"$seen_non_option\" || set \"save\" \"$@\"\n case \"$1\" in\n list)\n \tshift\n-\tif test $# = 0\n-\tthen\n-\t\tset x -n 10\n-\t\tshift\n-\tfi\n \tlist_stash \"$@\"\n \t;;\n show)\n-- \n1.6.5.18.g9f87a.dirty\n"},{"id":"125138","messageId":"20091016052003.GA10629@coredump.intra.peff.net","threadId":"21254","inReplyTo":"cover.1255645570.git.trast@student.ethz.ch","subject":"Re: [PATCH v2 0/5] Pretty formats for reflog data","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-16T05:20:03Z","receivedAt":"2009-10-16T05:20:03Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Oct 16, 2009 at 12:41:43AM +0200, Thomas Rast wrote:\n\n> Jeff King wrote:\n> > Maybe a better solution would be a \"short name\" variant for pretty\n> > format specifiers. We already have %(refname) and %(refname:short) [...]\n> > The tricky part would be deciding on a syntax. This seems to come up a\n> > fair bit.\n> \n> Ok, I settled for %g[dDs] for now to save on letters.  I'm saving the\n> syntax question for a later series while we discuss this one ;-)\n\n:) That is probably sensible. Your %g[dD] doesn't support selecting\nbetween the numbered version and the \"date\" version, which is something\nwe might want, but certainly it is no worse than the status quo (and\ndoing something like that probably _would_ want an extended syntax, as\nyou now have two orthogonal arguments: shorten and date/numbered).\n\n> I think going for %(...) wouldn't be too bad since we already have\n> that in for-each-ref, and it can be backwards compatible.  So we would\n> have different sets of short and long specifiers, e.g.\n> \n>   %ae = %(authoremail)\n>   %aE = %(authoremail:mailmap)\n> \n> We can then pass arguments via some yet-to-be decided syntax, say,\n> %(body:indent(10)).\n\nThat seems reasonable to me, though if we can limit ourselves to one\nargument per specifier (I suspect most specifiers would simply be\nboolean, but a few may take numbers or strings), then something like\n%(body:indent=10) might be a little more readable.\n\nIt would also be nice to have some sort of conditional inclusion, which\ncould deal with your extra \": \" in patch 3. Either something like:\n\n  %(reflog:short)%(reflog:+: )\n\nor even\n\n  %(reflog:short:prefix=\\: )\n\nand note that allowing arbitrary arguments means we get to deal with\nquoting.\n\nBut that is all for another potential series.\n\n> Other changes in this version include:\n> \n> * I followed your struct suggestion, which is the new 1/5.\n\nThanks. It looks like it didn't turn out to be too invasive, and I think\nsome of the callsites are a bit more readable.\n\n> * I fixed the warning that Junio found (and finally found the right\n>   combination of -W flags, though I cannot compile with -Werror myself\n>   because of *other* warnings...)\n\nI always compile with -Wall -Werror (including testing your series);\nwhat warnings are you getting?\n\n> Thomas Rast (5):\n>   Refactor pretty_print_commit arguments into a struct\n>   reflog-walk: refactor the branch@{num} formatting\n>   Introduce new pretty formats %g[sdD] for reflog information\n>   stash list: use new %g formats instead of sed\n>   stash list: drop the default limit of 10 stashes\n\nThanks, this series looks really good to me. I have a few comments on\npatch 3 which I'll send separately.\n\n-Peff\n"},{"id":"125139","messageId":"20091016053230.GB10629@coredump.intra.peff.net","threadId":"21254","inReplyTo":"012c71c4eab143691bc5e2d62b421f8c84effa0e.1255645570.git.trast@student.ethz.ch","subject":"Re: [PATCH v2 3/5] Introduce new pretty formats %g[sdD] for reflog information","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-16T05:32:30Z","receivedAt":"2009-10-16T05:32:30Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Oct 16, 2009 at 12:41:46AM +0200, Thomas Rast wrote:\n\n> Note that the --format=\"%h %gD: %gs\" tests may not work in real\n> repositories, as the --pretty formatter doesn't know to leave away the\n> \": \" on the last commit in an incomplete (because git-gc removed the\n> old part) reflog.  This equivalence is nevertheless the main goal of\n> this patch.\n\nYeah, I see what you are talking about in my git.git repo. I am tempted\nto suggest cutting it out of both formats, as it is somewhat confusing,\nbut it does actually convey a slight bit of information (even if\ninformation that is extremely unlikely to be of use).\n\nI am also fine with leaving it, and if we one day invent the\n\"conditionally include the ': '\" syntax, using it then.\n\n> diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\n> index 2a845b1..6359272 100644\n> --- a/Documentation/pretty-formats.txt\n> +++ b/Documentation/pretty-formats.txt\n> @@ -123,6 +123,9 @@ The placeholders are:\n>  - '%s': subject\n>  - '%f': sanitized subject line, suitable for a filename\n>  - '%b': body\n> +- '%gD': reflog selector, e.g., `refs/stash@{1}`\n> +- '%gd': shortened reflog selector, e.g., `stash@{1}`\n> +- '%gs': reflog subject\n>  - '%Cred': switch color to red\n>  - '%Cgreen': switch color to green\n>  - '%Cblue': switch color to blue\n\nShould we give a note that these do nothing if \"-g\" was not given?\n\n> +\tif (shorten) {\n> +\t\tif (last_ref != commit_reflog->reflogs->ref) {\n> +\t\t\tfree(last_short_ref);\n> +\t\t\tlast_short_ref = shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);\n> +\t\t}\n> +\t\tprinted_ref = last_short_ref;\n\nClever. I hadn't considered caching, but you are right that\nshorten_unambiguous_ref is a bit heavyweight to be calling for every\nentry.\n\n> diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh\n> index c18ed8e..cb8d0fd 100755\n> --- a/t/t1411-reflog-show.sh\n> +++ b/t/t1411-reflog-show.sh\n> @@ -64,4 +64,16 @@ test_expect_success 'using --date= shows reflog date (oneline)' '\n>  \ttest_cmp expect actual\n>  '\n>  \n> +test_expect_success '--format=\"%h %gD: %gs\" is same as git-reflog' '\n> +\tgit reflog >expect &&\n> +\tgit log -g --format=\"%h %gD: %gs\" >actual &&\n> +\ttest_cmp expect actual\n> +'\n> +\n> +test_expect_success '--format=\"%h %gD: %gs\" is same as git-reflog (with date)' '\n> +\tgit reflog --date=raw >expect &&\n> +\tgit log -g --format=\"%h %gD: %gs\" --date=raw >actual &&\n> +\ttest_cmp expect actual\n> +'\n\nA test for '%gd' would be nice. A squashable one is below. I am tempted\nto test all three forms in t6006, since the intent of that script is to\ntest all format specifiers. However, those tests would be somewhat\nredundant with your t1411 tests.\n\n---\ndiff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh\nindex 59d1f62..d1f2476 100755\n--- a/t/t6006-rev-list-format.sh\n+++ b/t/t6006-rev-list-format.sh\n@@ -162,4 +162,10 @@ test_expect_success 'empty email' '\n \t}\n '\n \n+test_expect_success '%gd shortens ref name' '\n+\techo \"master@{0}\" >expect.gd-short &&\n+\tgit log -g -1 --format=%gd refs/heads/master >actual.gd-short &&\n+\ttest_cmp expect.gd-short actual.gd-short\n+'\n+\n test_done\n"},{"id":"125150","messageId":"200910161050.32378.trast@student.ethz.ch","threadId":"21254","inReplyTo":"20091016053230.GB10629@coredump.intra.peff.net","subject":"Re: [PATCH v2 3/5] Introduce new pretty formats %g[sdD] for reflog information","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-16T08:50:30Z","receivedAt":"2009-10-16T08:50:30Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Jeff King wrote:\n> > +\tif (shorten) {\n> > +\t\tif (last_ref != commit_reflog->reflogs->ref) {\n> > +\t\t\tfree(last_short_ref);\n> > +\t\t\tlast_short_ref = shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);\n> > +\t\t}\n> > +\t\tprinted_ref = last_short_ref;\n> \n> Clever. I hadn't considered caching, but you are right that\n> shorten_unambiguous_ref is a bit heavyweight to be calling for every\n> entry.\n\nI had a slightly better idea today: We can just put an extra member\ninto the complete_reflogs struct, i.e., a short_ref to go along with\nthe ref.  It'll take a bit of auditing to verify that all allocations\nare zeroed, but since the struct is local to the file that shouldn't\nbe so hard.\n\n> A test for '%gd' would be nice. A squashable one is below. I am tempted\n> to test all three forms in t6006, since the intent of that script is to\n> test all format specifiers. However, those tests would be somewhat\n> redundant with your t1411 tests.\n\nAh, yeah, I looked for \"reflog\" instead of something about pretty, so\nI ended up with t1411.  t6006 is a better fit.  Thanks for the extra\ntest!\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"125151","messageId":"m37huvg1a8.fsf@localhost.localdomain","threadId":"21254","inReplyTo":"20091016052003.GA10629@coredump.intra.peff.net","subject":"Re: [PATCH v2 0/5] Pretty formats for reflog data","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-10-16T09:00:45Z","receivedAt":"2009-10-16T09:00:45Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Fri, Oct 16, 2009 at 12:41:43AM +0200, Thomas Rast wrote:\n\n> > I think going for %(...) wouldn't be too bad since we already have\n> > that in for-each-ref, and it can be backwards compatible.  So we would\n> > have different sets of short and long specifiers, e.g.\n> > \n> >   %ae = %(authoremail)\n> >   %aE = %(authoremail:mailmap)\n> > \n> > We can then pass arguments via some yet-to-be decided syntax, say,\n> > %(body:indent(10)).\n> \n> That seems reasonable to me, though if we can limit ourselves to one\n> argument per specifier (I suspect most specifiers would simply be\n> boolean, but a few may take numbers or strings), then something like\n> %(body:indent=10) might be a little more readable.\n> \n> It would also be nice to have some sort of conditional inclusion, which\n> could deal with your extra \": \" in patch 3. Either something like:\n> \n>   %(reflog:short)%(reflog:+: )\n> \n> or even\n> \n>   %(reflog:short:prefix=\\: )\n> \n> and note that allowing arbitrary arguments means we get to deal with\n> quoting.\n> \n> But that is all for another potential series.\n\nOr we could go the whole nine miles, and implement some subset of\nadvanced shell syntax, \n\n  %(parameter:-word)\n  %(parameter:=word)\n  %(parameter:?word)\n  %(parameter:+word)\n\nRPM spec syntax, \n\n  %(?parameter)      # expand if exists\n  %(!?parameter)     # expand if does not exists\n  %(?parameter:literal)\n  %(!?parameter:literal)\n\nor RPM queryformat\n\n  %10(parameter)\n  %-30(parameter)\n\n  [    %(messagebody)\\n]   # messagebody is list of lines\n  [%(=param) %(list)\\n]    # param is not a list; repeat it\n\n  %|parameter?{present}:{missing}|\n\n  %(parameter:date)\n  %(parameter:shescape)\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"125171","messageId":"cover.1255701207.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"20091016053230.GB10629@coredump.intra.peff.net","subject":"[PATCH v3 0/5] Pretty formats for reflog data","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-16T14:20:32Z","receivedAt":"2009-10-16T14:20:32Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Next round :-)\n\nI only changed 3/5, as per your comments:\n\nJeff King wrote:\n> On Fri, Oct 16, 2009 at 12:41:46AM +0200, Thomas Rast wrote:\n> > +- '%gD': reflog selector, e.g., `refs/stash@{1}`\n> > +- '%gd': shortened reflog selector, e.g., `stash@{1}`\n> > +- '%gs': reflog subject\n> \n> Should we give a note that these do nothing if \"-g\" was not given?\n\nI tried for some time, but all attempts at interrupting the lists\nended up terminating it again, so that the %g family list would not\nline up with the rest of the parameters.  Having the note there would\nbe nice, but I think keeping the list together optically is more\nimportant.  However, AFAICS it really is the first character that only\nworks with certain options (%m makes little sense without A...B, but\nstill expands to >).\n\nLooking at it did make me notice that @{1} is invalid asciidoc and\nneeds to be spelled @\\{1\\} though :-)\n\n> A test for '%gd' would be nice. A squashable one is below. I am tempted\n> to test all three forms in t6006, since the intent of that script is to\n> test all format specifiers. However, those tests would be somewhat\n> redundant with your t1411 tests.\n\nI added yours and moved my tests to t6006 too, as indicated in the\nother mail.\n\nI also changed the caching, as outlined earlier:\n\nI wrote:\n> I had a slightly better idea today: We can just put an extra member\n> into the complete_reflogs struct, i.e., a short_ref to go along with\n> the ref.  It'll take a bit of auditing to verify that all allocations\n> are zeroed, but since the struct is local to the file that shouldn't\n> be so hard.\n\nThere's in fact only a single allocation (with xcalloc).\n\n\nThomas Rast (5):\n  Refactor pretty_print_commit arguments into a struct\n  reflog-walk: refactor the branch@{num} formatting\n  Introduce new pretty formats %g[sdD] for reflog information\n  stash list: use new %g formats instead of sed\n  stash list: drop the default limit of 10 stashes\n\n Documentation/pretty-formats.txt |    3 +\n builtin-branch.c                 |    3 +-\n builtin-checkout.c               |    3 +-\n builtin-log.c                    |    3 +-\n builtin-merge.c                  |    7 ++-\n builtin-rev-list.c               |    7 ++-\n builtin-shortlog.c               |    9 +++-\n builtin-show-branch.c            |    4 +-\n commit.h                         |   20 ++++++---\n git-stash.sh                     |    8 +---\n log-tree.c                       |   21 +++++-----\n pretty.c                         |   44 ++++++++++++++------\n reflog-walk.c                    |   83 ++++++++++++++++++++++++++++----------\n reflog-walk.h                    |    8 ++++\n t/t6006-rev-list-format.sh       |   18 ++++++++\n 15 files changed, 170 insertions(+), 71 deletions(-)\n"},{"id":"125173","messageId":"9d3d0f0a6126afc86689138adf58ac7a12c43858.1255701207.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255701207.git.trast@student.ethz.ch","subject":"[PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-16T14:20:33Z","receivedAt":"2009-10-16T14:20:33Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"pretty_print_commit() has a bunch of rarely-used arguments, and\nintroducing more of them requires yet another update of all the call\nsites.  Refactor most of them into a struct to make future extensions\neasier.\n\nThe ones that stay \"plain\" arguments were chosen on the grounds that\nall callers put real arguments there, whereas some callers have 0/NULL\nfor all arguments that were factored into the struct.\n\nWe declare the struct 'const' to ensure none of the callers are bitten\nby the changed (no longer call-by-value) semantics.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n builtin-branch.c      |    3 ++-\n builtin-checkout.c    |    3 ++-\n builtin-log.c         |    3 ++-\n builtin-merge.c       |    7 +++++--\n builtin-rev-list.c    |    7 ++++---\n builtin-shortlog.c    |    9 ++++++---\n builtin-show-branch.c |    4 ++--\n commit.h              |   19 +++++++++++++------\n log-tree.c            |   20 ++++++++++----------\n pretty.c              |   27 ++++++++++++++-------------\n 10 files changed, 60 insertions(+), 42 deletions(-)\n\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex 9f57992..05e876e 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -387,8 +387,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,\n \n \t\tcommit = item->commit;\n \t\tif (commit && !parse_commit(commit)) {\n+\t\t\tstruct pretty_print_context ctx = {0};\n \t\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t\t\t    &subject, 0, NULL, NULL, 0, 0);\n+\t\t\t\t\t    &subject, &ctx);\n \t\t\tsub = subject.buf;\n \t\t}\n \ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex d050c37..075a49f 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -302,8 +302,9 @@ static void show_local_changes(struct object *head)\n static void describe_detached_head(char *msg, struct commit *commit)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n+\tstruct pretty_print_context ctx = {0};\n \tparse_commit(commit);\n-\tpretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);\n+\tpretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx);\n \tfprintf(stderr, \"%s %s... %s\\n\", msg,\n \t\tfind_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);\n \tstrbuf_release(&sb);\ndiff --git a/builtin-log.c b/builtin-log.c\nindex 25e21ed..207a361 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -1304,8 +1304,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)\n \n \t\tif (verbose) {\n \t\t\tstruct strbuf buf = STRBUF_INIT;\n+\t\t\tstruct pretty_print_context ctx = {0};\n \t\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t                    &buf, 0, NULL, NULL, 0, 0);\n+\t\t\t\t\t    &buf, &ctx);\n \t\t\tprintf(\"%c %s %s\\n\", sign,\n \t\t\t       sha1_to_hex(commit->object.sha1), buf.buf);\n \t\t\tstrbuf_release(&buf);\ndiff --git a/builtin-merge.c b/builtin-merge.c\nindex b6b8428..c69a305 100644\n--- a/builtin-merge.c\n+++ b/builtin-merge.c\n@@ -264,6 +264,7 @@ static void squash_message(void)\n \tstruct strbuf out = STRBUF_INIT;\n \tstruct commit_list *j;\n \tint fd;\n+\tstruct pretty_print_context ctx = {0};\n \n \tprintf(\"Squash commit -- not updating HEAD\\n\");\n \tfd = open(git_path(\"SQUASH_MSG\"), O_WRONLY | O_CREAT, 0666);\n@@ -285,13 +286,15 @@ static void squash_message(void)\n \tif (prepare_revision_walk(&rev))\n \t\tdie(\"revision walk setup failed\");\n \n+\tctx.abbrev = rev.abbrev;\n+\tctx.date_mode = rev.date_mode;\n+\n \tstrbuf_addstr(&out, \"Squashed commit of the following:\\n\");\n \twhile ((commit = get_revision(&rev)) != NULL) {\n \t\tstrbuf_addch(&out, '\\n');\n \t\tstrbuf_addf(&out, \"commit %s\\n\",\n \t\t\tsha1_to_hex(commit->object.sha1));\n-\t\tpretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,\n-\t\t\tNULL, NULL, rev.date_mode, 0);\n+\t\tpretty_print_commit(rev.commit_format, commit, &out, &ctx);\n \t}\n \tif (write(fd, out.buf, out.len) < 0)\n \t\tdie_errno(\"Writing SQUASH_MSG\");\ndiff --git a/builtin-rev-list.c b/builtin-rev-list.c\nindex 4ba1c12..42cc8d8 100644\n--- a/builtin-rev-list.c\n+++ b/builtin-rev-list.c\n@@ -96,9 +96,10 @@ static void show_commit(struct commit *commit, void *data)\n \n \tif (revs->verbose_header && commit->buffer) {\n \t\tstruct strbuf buf = STRBUF_INIT;\n-\t\tpretty_print_commit(revs->commit_format, commit,\n-\t\t\t\t    &buf, revs->abbrev, NULL, NULL,\n-\t\t\t\t    revs->date_mode, 0);\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tctx.abbrev = revs->abbrev;\n+\t\tctx.date_mode = revs->date_mode;\n+\t\tpretty_print_commit(revs->commit_format, commit, &buf, &ctx);\n \t\tif (revs->graph) {\n \t\t\tif (buf.len) {\n \t\t\t\tif (revs->commit_format != CMIT_FMT_ONELINE)\ndiff --git a/builtin-shortlog.c b/builtin-shortlog.c\nindex 4d4a3c8..8aa63c7 100644\n--- a/builtin-shortlog.c\n+++ b/builtin-shortlog.c\n@@ -158,9 +158,12 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)\n \t\t    sha1_to_hex(commit->object.sha1));\n \tif (log->user_format) {\n \t\tstruct strbuf buf = STRBUF_INIT;\n-\n-\t\tpretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf,\n-\t\t\tDEFAULT_ABBREV, \"\", \"\", DATE_NORMAL, 0);\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tctx.abbrev = DEFAULT_ABBREV;\n+\t\tctx.subject = \"\";\n+\t\tctx.after_subject = \"\";\n+\t\tctx.date_mode = DATE_NORMAL;\n+\t\tpretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf, &ctx);\n \t\tinsert_one_record(log, author, buf.buf);\n \t\tstrbuf_release(&buf);\n \t\treturn;\ndiff --git a/builtin-show-branch.c b/builtin-show-branch.c\nindex be95930..9f13caa 100644\n--- a/builtin-show-branch.c\n+++ b/builtin-show-branch.c\n@@ -293,8 +293,8 @@ static void show_one_commit(struct commit *commit, int no_name)\n \tstruct commit_name *name = commit->util;\n \n \tif (commit->object.parsed) {\n-\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t\t    &pretty, 0, NULL, NULL, 0, 0);\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit, &pretty, &ctx);\n \t\tpretty_str = pretty.buf;\n \t}\n \tif (!prefixcmp(pretty_str, \"[PATCH] \"))\ndiff --git a/commit.h b/commit.h\nindex f4fc5c5..011766d 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -63,6 +63,15 @@ enum cmit_fmt {\n \tCMIT_FMT_UNSPECIFIED,\n };\n \n+struct pretty_print_context\n+{\n+\tint abbrev;\n+\tconst char *subject;\n+\tconst char *after_subject;\n+\tenum date_mode date_mode;\n+\tint need_8bit_cte;\n+};\n+\n extern int non_ascii(int);\n extern int has_non_ascii(const char *text);\n struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */\n@@ -71,12 +80,10 @@ enum cmit_fmt {\n extern void get_commit_format(const char *arg, struct rev_info *);\n extern void format_commit_message(const struct commit *commit,\n \t\t\t\t  const void *format, struct strbuf *sb,\n-\t\t\t\t  enum date_mode dmode);\n-extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,\n-                                struct strbuf *,\n-                                int abbrev, const char *subject,\n-                                const char *after_subject, enum date_mode,\n-\t\t\t\tint need_8bit_cte);\n+\t\t\t\t  const struct pretty_print_context *context);\n+extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n+\t\t\t\tstruct strbuf *sb,\n+\t\t\t\tconst struct pretty_print_context *context);\n void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,\n \t\t   const char *line, enum date_mode dmode,\n \t\t   const char *encoding);\ndiff --git a/log-tree.c b/log-tree.c\nindex f7d54f2..f57487f 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -277,10 +277,9 @@ void show_log(struct rev_info *opt)\n \tstruct strbuf msgbuf = STRBUF_INIT;\n \tstruct log_info *log = opt->loginfo;\n \tstruct commit *commit = log->commit, *parent = log->parent;\n-\tint abbrev = opt->diffopt.abbrev;\n \tint abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;\n-\tconst char *subject = NULL, *extra_headers = opt->extra_headers;\n-\tint need_8bit_cte = 0;\n+\tconst char *extra_headers = opt->extra_headers;\n+\tstruct pretty_print_context ctx = {0};\n \n \topt->loginfo = NULL;\n \tif (!opt->verbose_header) {\n@@ -347,8 +346,8 @@ void show_log(struct rev_info *opt)\n \t */\n \n \tif (opt->commit_format == CMIT_FMT_EMAIL) {\n-\t\tlog_write_email_headers(opt, commit, &subject, &extra_headers,\n-\t\t\t\t\t&need_8bit_cte);\n+\t\tlog_write_email_headers(opt, commit, &ctx.subject, &extra_headers,\n+\t\t\t\t\t&ctx.need_8bit_cte);\n \t} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {\n \t\tfputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);\n \t\tif (opt->commit_format != CMIT_FMT_ONELINE)\n@@ -405,11 +404,12 @@ void show_log(struct rev_info *opt)\n \t/*\n \t * And then the pretty-printed message itself\n \t */\n-\tif (need_8bit_cte >= 0)\n-\t\tneed_8bit_cte = has_non_ascii(opt->add_signoff);\n-\tpretty_print_commit(opt->commit_format, commit, &msgbuf,\n-\t\t\t    abbrev, subject, extra_headers, opt->date_mode,\n-\t\t\t    need_8bit_cte);\n+\tif (ctx.need_8bit_cte >= 0)\n+\t\tctx.need_8bit_cte = has_non_ascii(opt->add_signoff);\n+\tctx.date_mode = opt->date_mode;\n+\tctx.abbrev = opt->diffopt.abbrev;\n+\tctx.after_subject = extra_headers;\n+\tpretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);\n \n \tif (opt->add_signoff)\n \t\tappend_signoff(&msgbuf, opt->add_signoff);\ndiff --git a/pretty.c b/pretty.c\nindex f5983f8..d6d57eb 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -442,7 +442,7 @@ struct chunk {\n \n struct format_commit_context {\n \tconst struct commit *commit;\n-\tenum date_mode dmode;\n+\tconst struct pretty_print_context *pretty_ctx;\n \tunsigned commit_header_parsed:1;\n \tunsigned commit_message_parsed:1;\n \n@@ -711,11 +711,11 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,\n \tcase 'a':\t/* author ... */\n \t\treturn format_person_part(sb, placeholder[1],\n \t\t\t\t   msg + c->author.off, c->author.len,\n-\t\t\t\t   c->dmode);\n+\t\t\t\t   c->pretty_ctx->date_mode);\n \tcase 'c':\t/* committer ... */\n \t\treturn format_person_part(sb, placeholder[1],\n \t\t\t\t   msg + c->committer.off, c->committer.len,\n-\t\t\t\t   c->dmode);\n+\t\t\t\t   c->pretty_ctx->date_mode);\n \tcase 'e':\t/* encoding */\n \t\tstrbuf_add(sb, msg + c->encoding.off, c->encoding.len);\n \t\treturn 1;\n@@ -741,13 +741,13 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,\n \n void format_commit_message(const struct commit *commit,\n \t\t\t   const void *format, struct strbuf *sb,\n-\t\t\t   enum date_mode dmode)\n+\t\t\t   const struct pretty_print_context *pretty_ctx)\n {\n \tstruct format_commit_context context;\n \n \tmemset(&context, 0, sizeof(context));\n \tcontext.commit = commit;\n-\tcontext.dmode = dmode;\n+\tcontext.pretty_ctx = pretty_ctx;\n \tstrbuf_expand(sb, format, format_commit_item, &context);\n }\n \n@@ -900,18 +900,18 @@ void pp_remainder(enum cmit_fmt fmt,\n }\n \n void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n-\t\t\t struct strbuf *sb, int abbrev,\n-\t\t\t const char *subject, const char *after_subject,\n-\t\t\t enum date_mode dmode, int need_8bit_cte)\n+\t\t\t struct strbuf *sb,\n+\t\t\t const struct pretty_print_context *context)\n {\n \tunsigned long beginning_of_body;\n \tint indent = 4;\n \tconst char *msg = commit->buffer;\n \tchar *reencoded;\n \tconst char *encoding;\n+\tint need_8bit_cte = context->need_8bit_cte;\n \n \tif (fmt == CMIT_FMT_USERFORMAT) {\n-\t\tformat_commit_message(commit, user_format, sb, dmode);\n+\t\tformat_commit_message(commit, user_format, sb, context);\n \t\treturn;\n \t}\n \n@@ -946,8 +946,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n \t\t}\n \t}\n \n-\tpp_header(fmt, abbrev, dmode, encoding, commit, &msg, sb);\n-\tif (fmt != CMIT_FMT_ONELINE && !subject) {\n+\tpp_header(fmt, context->abbrev, context->date_mode, encoding,\n+\t\t  commit, &msg, sb);\n+\tif (fmt != CMIT_FMT_ONELINE && !context->subject) {\n \t\tstrbuf_addch(sb, '\\n');\n \t}\n \n@@ -956,8 +957,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n \n \t/* These formats treat the title line specially. */\n \tif (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)\n-\t\tpp_title_line(fmt, &msg, sb, subject,\n-\t\t\t      after_subject, encoding, need_8bit_cte);\n+\t\tpp_title_line(fmt, &msg, sb, context->subject,\n+\t\t\t      context->after_subject, encoding, need_8bit_cte);\n \n \tbeginning_of_body = sb->len;\n \tif (fmt != CMIT_FMT_ONELINE)\n-- \n1.6.5.116.gfe4b9\n"},{"id":"125174","messageId":"6dab88e2a1624ae37dbc0c8fd86e4ea486c809a6.1255701207.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255701207.git.trast@student.ethz.ch","subject":"[PATCH v3 2/5] reflog-walk: refactor the branch@{num} formatting","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-16T14:20:34Z","receivedAt":"2009-10-16T14:20:34Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"We'll use the same output in an upcoming commit, so refactor its\nformatting (which was duplicated anyway) into a separate function.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n reflog-walk.c |   54 ++++++++++++++++++++++++++++++++----------------------\n 1 files changed, 32 insertions(+), 22 deletions(-)\n\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 5623ea6..596bafe 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -241,36 +241,46 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)\n \tcommit->object.flags &= ~(ADDED | SEEN | SHOWN);\n }\n \n-void show_reflog_message(struct reflog_walk_info *info, int oneline,\n+void get_reflog_selector(struct strbuf *sb,\n+\t\t\t struct reflog_walk_info *reflog_info,\n+\t\t\t enum date_mode dmode)\n+{\n+\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n+\tstruct reflog_info *info;\n+\n+\tif (!commit_reflog)\n+\t\treturn;\n+\n+\tstrbuf_addf(sb, \"%s@{\", commit_reflog->reflogs->ref);\n+\tif (commit_reflog->flag || dmode) {\n+\t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\t\tstrbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));\n+\t} else {\n+\t\tstrbuf_addf(sb, \"%d\", commit_reflog->reflogs->nr\n+\t\t\t    - 2 - commit_reflog->recno);\n+\t}\n+\n+\tstrbuf_addch(sb, '}');\n+}\n+\n+void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \tenum date_mode dmode)\n {\n-\tif (info && info->last_commit_reflog) {\n-\t\tstruct commit_reflog *commit_reflog = info->last_commit_reflog;\n+\tif (reflog_info && reflog_info->last_commit_reflog) {\n+\t\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n \t\tstruct reflog_info *info;\n+\t\tstruct strbuf selector = STRBUF_INIT;\n \n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\t\tget_reflog_selector(&selector, reflog_info, dmode);\n \t\tif (oneline) {\n-\t\t\tprintf(\"%s@{\", commit_reflog->reflogs->ref);\n-\t\t\tif (commit_reflog->flag || dmode)\n-\t\t\t\tprintf(\"%s\", show_date(info->timestamp,\n-\t\t\t\t\t\t       info->tz,\n-\t\t\t\t\t\t       dmode));\n-\t\t\telse\n-\t\t\t\tprintf(\"%d\", commit_reflog->reflogs->nr\n-\t\t\t\t       - 2 - commit_reflog->recno);\n-\t\t\tprintf(\"}: %s\", info->message);\n+\t\t\tprintf(\"%s: %s\", selector.buf, info->message);\n \t\t}\n \t\telse {\n-\t\t\tprintf(\"Reflog: %s@{\", commit_reflog->reflogs->ref);\n-\t\t\tif (commit_reflog->flag || dmode)\n-\t\t\t\tprintf(\"%s\", show_date(info->timestamp,\n-\t\t\t\t\t\t\tinfo->tz,\n-\t\t\t\t\t\t\tdmode));\n-\t\t\telse\n-\t\t\t\tprintf(\"%d\", commit_reflog->reflogs->nr\n-\t\t\t\t       - 2 - commit_reflog->recno);\n-\t\t\tprintf(\"} (%s)\\nReflog message: %s\",\n-\t\t\t       info->email, info->message);\n+\t\t\tprintf(\"Reflog: %s (%s)\\nReflog message: %s\",\n+\t\t\t       selector.buf, info->email, info->message);\n \t\t}\n+\n+\t\tstrbuf_release(&selector);\n \t}\n }\n-- \n1.6.5.116.gfe4b9\n"},{"id":"125175","messageId":"8a5b3a586d437f02e2a75edd2786636b605522a7.1255701207.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255701207.git.trast@student.ethz.ch","subject":"[PATCH v3 3/5] Introduce new pretty formats %g[sdD] for reflog information","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-16T14:20:35Z","receivedAt":"2009-10-16T14:20:35Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Add three new --pretty=format escapes:\n\n  %gD  long  reflog descriptor (e.g. refs/stash@{0})\n  %gd  short reflog descriptor (e.g. stash@{0})\n  %gs  reflog message\n\nThis is achieved by passing down the reflog info, if any, inside the\npretty_print_context struct.\n\nWe use the newly refactored get_reflog_selector(), and give it some\nextra functionality to extract a shortened ref.  The shortening is\ncached inside the commit_reflogs struct; the only allocation of it\nhappens in read_complete_reflog(), where it is initialised to 0.  Also\nadd another helper get_reflog_message() for the message extraction.\n\nNote that the --format=\"%h %gD: %gs\" tests may not work in real\nrepositories, as the --pretty formatter doesn't know to leave away the\n\": \" on the last commit in an incomplete (because git-gc removed the\nold part) reflog.  This equivalence is nevertheless the main goal of\nthis patch.\n\nThanks to Jeff King for reviews and the %gd testcase.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n Documentation/pretty-formats.txt |    3 +++\n commit.h                         |    1 +\n log-tree.c                       |    1 +\n pretty.c                         |   17 +++++++++++++++++\n reflog-walk.c                    |   35 ++++++++++++++++++++++++++++++++---\n reflog-walk.h                    |    8 ++++++++\n t/t6006-rev-list-format.sh       |   18 ++++++++++++++++++\n 7 files changed, 80 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 2a845b1..cc0ea56 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -123,6 +123,9 @@ The placeholders are:\n - '%s': subject\n - '%f': sanitized subject line, suitable for a filename\n - '%b': body\n+- '%gD': reflog selector, e.g., `refs/stash@\\{1\\}`\n+- '%gd': shortened reflog selector, e.g., `stash@\\{1\\}`\n+- '%gs': reflog subject\n - '%Cred': switch color to red\n - '%Cgreen': switch color to green\n - '%Cblue': switch color to blue\ndiff --git a/commit.h b/commit.h\nindex 011766d..15cb649 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -70,6 +70,7 @@ struct pretty_print_context\n \tconst char *after_subject;\n \tenum date_mode date_mode;\n \tint need_8bit_cte;\n+\tstruct reflog_walk_info *reflog_info;\n };\n \n extern int non_ascii(int);\ndiff --git a/log-tree.c b/log-tree.c\nindex f57487f..8e782fc 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -409,6 +409,7 @@ void show_log(struct rev_info *opt)\n \tctx.date_mode = opt->date_mode;\n \tctx.abbrev = opt->diffopt.abbrev;\n \tctx.after_subject = extra_headers;\n+\tctx.reflog_info = opt->reflog_info;\n \tpretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);\n \n \tif (opt->add_signoff)\ndiff --git a/pretty.c b/pretty.c\nindex d6d57eb..fc65fca 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -7,6 +7,7 @@\n #include \"mailmap.h\"\n #include \"log-tree.h\"\n #include \"color.h\"\n+#include \"reflog-walk.h\"\n \n static char *user_format;\n \n@@ -701,6 +702,22 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,\n \tcase 'd':\n \t\tformat_decoration(sb, commit);\n \t\treturn 1;\n+\tcase 'g':\t\t/* reflog info */\n+\t\tswitch(placeholder[1]) {\n+\t\tcase 'd':\t/* reflog selector */\n+\t\tcase 'D':\n+\t\t\tif (c->pretty_ctx->reflog_info)\n+\t\t\t\tget_reflog_selector(sb,\n+\t\t\t\t\t\t    c->pretty_ctx->reflog_info,\n+\t\t\t\t\t\t    c->pretty_ctx->date_mode,\n+\t\t\t\t\t\t    (placeholder[1] == 'd'));\n+\t\t\treturn 2;\n+\t\tcase 's':\t/* reflog message */\n+\t\t\tif (c->pretty_ctx->reflog_info)\n+\t\t\t\tget_reflog_message(sb, c->pretty_ctx->reflog_info);\n+\t\t\treturn 2;\n+\t\t}\n+\t\treturn 0;\t/* unknown %g placeholder */\n \t}\n \n \t/* For the rest we have to parse the commit header. */\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 596bafe..caba4f7 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -8,6 +8,7 @@\n \n struct complete_reflogs {\n \tchar *ref;\n+\tconst char *short_ref;\n \tstruct reflog_info {\n \t\tunsigned char osha1[20], nsha1[20];\n \t\tchar *email;\n@@ -243,15 +244,26 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)\n \n void get_reflog_selector(struct strbuf *sb,\n \t\t\t struct reflog_walk_info *reflog_info,\n-\t\t\t enum date_mode dmode)\n+\t\t\t enum date_mode dmode,\n+\t\t\t int shorten)\n {\n \tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n \tstruct reflog_info *info;\n+\tconst char *printed_ref;\n \n \tif (!commit_reflog)\n \t\treturn;\n \n-\tstrbuf_addf(sb, \"%s@{\", commit_reflog->reflogs->ref);\n+\tif (shorten) {\n+\t\tif (!commit_reflog->reflogs->short_ref)\n+\t\t\tcommit_reflog->reflogs->short_ref\n+\t\t\t\t= shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);\n+\t\tprinted_ref = commit_reflog->reflogs->short_ref;\n+\t} else {\n+\t\tprinted_ref = commit_reflog->reflogs->ref;\n+\t}\n+\n+\tstrbuf_addf(sb, \"%s@{\", printed_ref);\n \tif (commit_reflog->flag || dmode) {\n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n \t\tstrbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));\n@@ -263,6 +275,23 @@ void get_reflog_selector(struct strbuf *sb,\n \tstrbuf_addch(sb, '}');\n }\n \n+void get_reflog_message(struct strbuf *sb,\n+\t\t\tstruct reflog_walk_info *reflog_info)\n+{\n+\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n+\tstruct reflog_info *info;\n+\tsize_t len;\n+\n+\tif (!commit_reflog)\n+\t\treturn;\n+\n+\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\tlen = strlen(info->message);\n+\tif (len > 0)\n+\t\tlen--; /* strip away trailing newline */\n+\tstrbuf_add(sb, info->message, len);\n+}\n+\n void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \tenum date_mode dmode)\n {\n@@ -272,7 +301,7 @@ void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \t\tstruct strbuf selector = STRBUF_INIT;\n \n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n-\t\tget_reflog_selector(&selector, reflog_info, dmode);\n+\t\tget_reflog_selector(&selector, reflog_info, dmode, 0);\n \t\tif (oneline) {\n \t\t\tprintf(\"%s: %s\", selector.buf, info->message);\n \t\t}\ndiff --git a/reflog-walk.h b/reflog-walk.h\nindex 74c9096..7bd2cd4 100644\n--- a/reflog-walk.h\n+++ b/reflog-walk.h\n@@ -3,6 +3,8 @@\n \n #include \"cache.h\"\n \n+struct reflog_walk_info;\n+\n extern void init_reflog_walk(struct reflog_walk_info** info);\n extern int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\tstruct commit *commit, const char *name);\n@@ -10,5 +12,11 @@ extern void fake_reflog_parent(struct reflog_walk_info *info,\n \t\tstruct commit *commit);\n extern void show_reflog_message(struct reflog_walk_info *info, int,\n \t\tenum date_mode);\n+extern void get_reflog_message(struct strbuf *sb,\n+\t\tstruct reflog_walk_info *reflog_info);\n+extern void get_reflog_selector(struct strbuf *sb,\n+\t\tstruct reflog_walk_info *reflog_info,\n+\t\tenum date_mode dmode,\n+\t\tint shorten);\n \n #endif\ndiff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh\nindex 59d1f62..7f61ab0 100755\n--- a/t/t6006-rev-list-format.sh\n+++ b/t/t6006-rev-list-format.sh\n@@ -162,4 +162,22 @@ test_expect_success 'empty email' '\n \t}\n '\n \n+test_expect_success '\"%h %gD: %gs\" is same as git-reflog' '\n+\tgit reflog >expect &&\n+\tgit log -g --format=\"%h %gD: %gs\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '\"%h %gD: %gs\" is same as git-reflog (with date)' '\n+\tgit reflog --date=raw >expect &&\n+\tgit log -g --format=\"%h %gD: %gs\" --date=raw >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '%gd shortens ref name' '\n+\techo \"master@{0}\" >expect.gd-short &&\n+\tgit log -g -1 --format=%gd refs/heads/master >actual.gd-short &&\n+\ttest_cmp expect.gd-short actual.gd-short\n+'\n+\n test_done\n-- \n1.6.5.116.gfe4b9\n"},{"id":"125179","messageId":"1d2a75bdb94691839f4a8ce0d1712d2bac6e405d.1255701207.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255701207.git.trast@student.ethz.ch","subject":"[PATCH v3 4/5] stash list: use new %g formats instead of sed","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-16T14:20:36Z","receivedAt":"2009-10-16T14:20:36Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"With the new formats, we can rewrite 'git stash list' in terms of an\nappropriate pretty format, instead of hand-editing with sed.  This has\nthe advantage that it obeys the normal settings for git-log, notably\nthe pager.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n git-stash.sh |    3 +--\n 1 files changed, 1 insertions(+), 2 deletions(-)\n\ndiff --git a/git-stash.sh b/git-stash.sh\nindex 4febbbf..f8847c1 100755\n--- a/git-stash.sh\n+++ b/git-stash.sh\n@@ -205,8 +205,7 @@ have_stash () {\n \n list_stash () {\n \thave_stash || return 0\n-\tgit log --no-color --pretty=oneline -g \"$@\" $ref_stash -- |\n-\tsed -n -e 's/^[.0-9a-f]* refs\\///p'\n+\tgit log --format=\"%gd: %gs\" -g \"$@\" $ref_stash --\n }\n \n show_stash () {\n-- \n1.6.5.116.gfe4b9\n"},{"id":"125176","messageId":"df4f4840d182cec33c279ce4008d707521dd4c01.1255701207.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255701207.git.trast@student.ethz.ch","subject":"[PATCH v3 5/5] stash list: drop the default limit of 10 stashes","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-16T14:20:37Z","receivedAt":"2009-10-16T14:20:37Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"'git stash list' had an undocumented limit of 10 stashes, unless other\ngit-log arguments were specified.  This surprised at least one user,\nbut possibly served to cut the output below a screenful without using\na pager.\n\nSince the last commit, 'git stash list' will fire up a pager according\nto the same rules as the 'git log' it calls, so we can drop the limit.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n git-stash.sh |    5 -----\n 1 files changed, 0 insertions(+), 5 deletions(-)\n\ndiff --git a/git-stash.sh b/git-stash.sh\nindex f8847c1..f796c2f 100755\n--- a/git-stash.sh\n+++ b/git-stash.sh\n@@ -382,11 +382,6 @@ test -n \"$seen_non_option\" || set \"save\" \"$@\"\n case \"$1\" in\n list)\n \tshift\n-\tif test $# = 0\n-\tthen\n-\t\tset x -n 10\n-\t\tshift\n-\tfi\n \tlist_stash \"$@\"\n \t;;\n show)\n-- \n1.6.5.116.gfe4b9\n"},{"id":"125224","messageId":"7vws2uonby.fsf@alter.siamese.dyndns.org","threadId":"21254","inReplyTo":"cover.1255701207.git.trast@student.ethz.ch","subject":"Re: [PATCH v3 0/5] Pretty formats for reflog data","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-17T00:50:41Z","receivedAt":"2009-10-17T00:50:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> Next round :-)\n\nVery nicely done; I like it.\n\nThanks.\n"},{"id":"125225","messageId":"20091017011801.GA31443@coredump.intra.peff.net","threadId":"21254","inReplyTo":"cover.1255701207.git.trast@student.ethz.ch","subject":"Re: [PATCH v3 0/5] Pretty formats for reflog data","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-17T01:18:01Z","receivedAt":"2009-10-17T01:18:01Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Oct 16, 2009 at 04:20:32PM +0200, Thomas Rast wrote:\n\n> I tried for some time, but all attempts at interrupting the lists\n> ended up terminating it again, so that the %g family list would not\n> line up with the rest of the parameters.  Having the note there would\n> be nice, but I think keeping the list together optically is more\n> important.  However, AFAICS it really is the first character that only\n> works with certain options (%m makes little sense without A...B, but\n> still expands to >).\n\nAnother example is \"%d\", but there we load decorations on the fly the\nfirst time it is used. I don't think that's a good idea here, since\nusing \"%gd\" shouldn't automatically imply \"-g\", which drastically\nchanges the nature of the command.\n\nThe \"%m\" behavior does what I would expect. If you haven't done any\nlimiting, then there can be no \"left\" or \"boundary\" entries.\n\nI am tempted to do a note like the one below, but maybe the behavior is\nobvious enough to users that it isn't necessary.\n\n> Looking at it did make me notice that @{1} is invalid asciidoc and\n> needs to be spelled @\\{1\\} though :-)\n\nThanks. I am often very guilty of not actually building documentation\nwhen reviewing patches, because it is so tedious to build and examine.\n\n---\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 6359272..43192af 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -135,6 +135,12 @@ The placeholders are:\n - '%n': newline\n - '%x00': print a byte from a hex code\n \n+NOTE: Some placeholders may depend on other options given to the\n+revision traversal engine. For example, the `%g*` reflog options will\n+insert an empty string unless we are traversing reflog entries (e.g., by\n+`git log -g`). The `%d` placeholder will use the \"short\" decoration\n+format if `--decorate` was not already provided on the command line.\n+\n * 'tformat:'\n +\n The 'tformat:' format works exactly like 'format:', except that it\n"},{"id":"125238","messageId":"e0ab6923eb4057bcbc8e97980dad5e4a37e53067.1255790816.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"8a5b3a586d437f02e2a75edd2786636b605522a7.1255701207.git.trast@student.ethz.ch","subject":"[PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-17T14:48:11Z","receivedAt":"2009-10-17T14:48:11Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Add three new --pretty=format escapes:\n\n  %gD  long  reflog descriptor (e.g. refs/stash@{0})\n  %gd  short reflog descriptor (e.g. stash@{0})\n  %gs  reflog message\n\nThis is achieved by passing down the reflog info, if any, inside the\npretty_print_context struct.\n\nWe use the newly refactored get_reflog_selector(), and give it some\nextra functionality to extract a shortened ref.  The shortening is\ncached inside the commit_reflogs struct; the only allocation of it\nhappens in read_complete_reflog(), where it is initialised to 0.  Also\nadd another helper get_reflog_message() for the message extraction.\n\nNote that the --format=\"%h %gD: %gs\" tests may not work in real\nrepositories, as the --pretty formatter doesn't know to leave away the\n\": \" on the last commit in an incomplete (because git-gc removed the\nold part) reflog.  This equivalence is nevertheless the main goal of\nthis patch.\n\nThanks to Jeff King for reviews, the %gd testcase and documentation.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n\nI wrote:\n> [Tacking this on the corresponding v3 patch, but the text below is\n> from <20091017011801.GA31443@coredump.intra.peff.net>.]\n\nThis sadly backfired, as I forgot to snip out the in-reply-to in the\nmail itself and git-send-email apparently trusted that more.  Sorry\nfor the confusion.\n\nJeff King wrote:\n> I am tempted to do a note like the one below, but maybe the behavior is\n> obvious enough to users that it isn't necessary.\n[...]\n> +NOTE: Some placeholders may depend on other options given to the\n> +revision traversal engine. For example, the `%g*` reflog options will\n> +insert an empty string unless we are traversing reflog entries (e.g., by\n> +`git log -g`). The `%d` placeholder will use the \"short\" decoration\n> +format if `--decorate` was not already provided on the command line.\n\nSure.  I figured it was obvious enough, but since you already went to\nthe lengths of documenting the exact behaviour of %d, I squashed it\nand adjusted the acknowledgement in the commit message accordingly.\n\n Documentation/pretty-formats.txt |    9 +++++++++\n commit.h                         |    1 +\n log-tree.c                       |    1 +\n pretty.c                         |   17 +++++++++++++++++\n reflog-walk.c                    |   35 ++++++++++++++++++++++++++++++++---\n reflog-walk.h                    |    8 ++++++++\n t/t6006-rev-list-format.sh       |   18 ++++++++++++++++++\n 7 files changed, 86 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 2a845b1..38b9904 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -123,6 +123,9 @@ The placeholders are:\n - '%s': subject\n - '%f': sanitized subject line, suitable for a filename\n - '%b': body\n+- '%gD': reflog selector, e.g., `refs/stash@\\{1\\}`\n+- '%gd': shortened reflog selector, e.g., `stash@\\{1\\}`\n+- '%gs': reflog subject\n - '%Cred': switch color to red\n - '%Cgreen': switch color to green\n - '%Cblue': switch color to blue\n@@ -132,6 +135,12 @@ The placeholders are:\n - '%n': newline\n - '%x00': print a byte from a hex code\n \n+NOTE: Some placeholders may depend on other options given to the\n+revision traversal engine. For example, the `%g*` reflog options will\n+insert an empty string unless we are traversing reflog entries (e.g., by\n+`git log -g`). The `%d` placeholder will use the \"short\" decoration\n+format if `--decorate` was not already provided on the command line.\n+\n * 'tformat:'\n +\n The 'tformat:' format works exactly like 'format:', except that it\ndiff --git a/commit.h b/commit.h\nindex 011766d..15cb649 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -70,6 +70,7 @@ struct pretty_print_context\n \tconst char *after_subject;\n \tenum date_mode date_mode;\n \tint need_8bit_cte;\n+\tstruct reflog_walk_info *reflog_info;\n };\n \n extern int non_ascii(int);\ndiff --git a/log-tree.c b/log-tree.c\nindex f57487f..8e782fc 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -409,6 +409,7 @@ void show_log(struct rev_info *opt)\n \tctx.date_mode = opt->date_mode;\n \tctx.abbrev = opt->diffopt.abbrev;\n \tctx.after_subject = extra_headers;\n+\tctx.reflog_info = opt->reflog_info;\n \tpretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);\n \n \tif (opt->add_signoff)\ndiff --git a/pretty.c b/pretty.c\nindex d6d57eb..fc65fca 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -7,6 +7,7 @@\n #include \"mailmap.h\"\n #include \"log-tree.h\"\n #include \"color.h\"\n+#include \"reflog-walk.h\"\n \n static char *user_format;\n \n@@ -701,6 +702,22 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,\n \tcase 'd':\n \t\tformat_decoration(sb, commit);\n \t\treturn 1;\n+\tcase 'g':\t\t/* reflog info */\n+\t\tswitch(placeholder[1]) {\n+\t\tcase 'd':\t/* reflog selector */\n+\t\tcase 'D':\n+\t\t\tif (c->pretty_ctx->reflog_info)\n+\t\t\t\tget_reflog_selector(sb,\n+\t\t\t\t\t\t    c->pretty_ctx->reflog_info,\n+\t\t\t\t\t\t    c->pretty_ctx->date_mode,\n+\t\t\t\t\t\t    (placeholder[1] == 'd'));\n+\t\t\treturn 2;\n+\t\tcase 's':\t/* reflog message */\n+\t\t\tif (c->pretty_ctx->reflog_info)\n+\t\t\t\tget_reflog_message(sb, c->pretty_ctx->reflog_info);\n+\t\t\treturn 2;\n+\t\t}\n+\t\treturn 0;\t/* unknown %g placeholder */\n \t}\n \n \t/* For the rest we have to parse the commit header. */\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 596bafe..caba4f7 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -8,6 +8,7 @@\n \n struct complete_reflogs {\n \tchar *ref;\n+\tconst char *short_ref;\n \tstruct reflog_info {\n \t\tunsigned char osha1[20], nsha1[20];\n \t\tchar *email;\n@@ -243,15 +244,26 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)\n \n void get_reflog_selector(struct strbuf *sb,\n \t\t\t struct reflog_walk_info *reflog_info,\n-\t\t\t enum date_mode dmode)\n+\t\t\t enum date_mode dmode,\n+\t\t\t int shorten)\n {\n \tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n \tstruct reflog_info *info;\n+\tconst char *printed_ref;\n \n \tif (!commit_reflog)\n \t\treturn;\n \n-\tstrbuf_addf(sb, \"%s@{\", commit_reflog->reflogs->ref);\n+\tif (shorten) {\n+\t\tif (!commit_reflog->reflogs->short_ref)\n+\t\t\tcommit_reflog->reflogs->short_ref\n+\t\t\t\t= shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);\n+\t\tprinted_ref = commit_reflog->reflogs->short_ref;\n+\t} else {\n+\t\tprinted_ref = commit_reflog->reflogs->ref;\n+\t}\n+\n+\tstrbuf_addf(sb, \"%s@{\", printed_ref);\n \tif (commit_reflog->flag || dmode) {\n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n \t\tstrbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));\n@@ -263,6 +275,23 @@ void get_reflog_selector(struct strbuf *sb,\n \tstrbuf_addch(sb, '}');\n }\n \n+void get_reflog_message(struct strbuf *sb,\n+\t\t\tstruct reflog_walk_info *reflog_info)\n+{\n+\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n+\tstruct reflog_info *info;\n+\tsize_t len;\n+\n+\tif (!commit_reflog)\n+\t\treturn;\n+\n+\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\tlen = strlen(info->message);\n+\tif (len > 0)\n+\t\tlen--; /* strip away trailing newline */\n+\tstrbuf_add(sb, info->message, len);\n+}\n+\n void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \tenum date_mode dmode)\n {\n@@ -272,7 +301,7 @@ void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \t\tstruct strbuf selector = STRBUF_INIT;\n \n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n-\t\tget_reflog_selector(&selector, reflog_info, dmode);\n+\t\tget_reflog_selector(&selector, reflog_info, dmode, 0);\n \t\tif (oneline) {\n \t\t\tprintf(\"%s: %s\", selector.buf, info->message);\n \t\t}\ndiff --git a/reflog-walk.h b/reflog-walk.h\nindex 74c9096..7bd2cd4 100644\n--- a/reflog-walk.h\n+++ b/reflog-walk.h\n@@ -3,6 +3,8 @@\n \n #include \"cache.h\"\n \n+struct reflog_walk_info;\n+\n extern void init_reflog_walk(struct reflog_walk_info** info);\n extern int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\tstruct commit *commit, const char *name);\n@@ -10,5 +12,11 @@ extern void fake_reflog_parent(struct reflog_walk_info *info,\n \t\tstruct commit *commit);\n extern void show_reflog_message(struct reflog_walk_info *info, int,\n \t\tenum date_mode);\n+extern void get_reflog_message(struct strbuf *sb,\n+\t\tstruct reflog_walk_info *reflog_info);\n+extern void get_reflog_selector(struct strbuf *sb,\n+\t\tstruct reflog_walk_info *reflog_info,\n+\t\tenum date_mode dmode,\n+\t\tint shorten);\n \n #endif\ndiff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh\nindex 59d1f62..7f61ab0 100755\n--- a/t/t6006-rev-list-format.sh\n+++ b/t/t6006-rev-list-format.sh\n@@ -162,4 +162,22 @@ test_expect_success 'empty email' '\n \t}\n '\n \n+test_expect_success '\"%h %gD: %gs\" is same as git-reflog' '\n+\tgit reflog >expect &&\n+\tgit log -g --format=\"%h %gD: %gs\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '\"%h %gD: %gs\" is same as git-reflog (with date)' '\n+\tgit reflog --date=raw >expect &&\n+\tgit log -g --format=\"%h %gD: %gs\" --date=raw >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '%gd shortens ref name' '\n+\techo \"master@{0}\" >expect.gd-short &&\n+\tgit log -g -1 --format=%gd refs/heads/master >actual.gd-short &&\n+\ttest_cmp expect.gd-short actual.gd-short\n+'\n+\n test_done\n-- \n1.6.5.116.g4aaa3\n"},{"id":"125240","messageId":"m3y6nadpu2.fsf@localhost.localdomain","threadId":"21254","inReplyTo":"e0ab6923eb4057bcbc8e97980dad5e4a37e53067.1255790816.git.trast@student.ethz.ch","subject":"Re: [PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-10-17T15:06:13Z","receivedAt":"2009-10-17T15:06:13Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> Note that the --format=\"%h %gD: %gs\" tests may not work in real\n> repositories, as the --pretty formatter doesn't know to leave away the\n> \": \" on the last commit in an incomplete (because git-gc removed the\n> old part) reflog.  This equivalence is nevertheless the main goal of\n> this patch.\n\nPerhaps just-introduced grouping syntax would help there?  You could\nfor example write\n\n  --format=\"%h%[all() %gD: %gs%]\"\n\nwhich would expand nested group if _all_ placeholders within it have\nexpansion.  Perhaps %[ ... %], or %[? ... %], or %[* ... %] could be\nshorter versions...\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"125247","messageId":"7vljja7xy8.fsf@alter.siamese.dyndns.org","threadId":"21254","inReplyTo":"9d3d0f0a6126afc86689138adf58ac7a12c43858.1255701207.git.trast@student.ethz.ch","subject":"Re: [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-17T17:05:35Z","receivedAt":"2009-10-17T17:05:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> pretty_print_commit() has a bunch of rarely-used arguments, and\n> introducing more of them requires yet another update of all the call\n> sites.  Refactor most of them into a struct to make future extensions\n> easier.\n>\n> The ones that stay \"plain\" arguments were chosen on the grounds that\n> all callers put real arguments there, whereas some callers have 0/NULL\n> for all arguments that were factored into the struct.\n>\n> We declare the struct 'const' to ensure none of the callers are bitten\n> by the changed (no longer call-by-value) semantics.\n>\n> Signed-off-by: Thomas Rast <trast@student.ethz.ch>\n\nGood idea, a slightly sloppy/careless execution.\n\nThe existing calls to format_commit_message() often take DATE_NORMAL to\nits \"enum date_mode dmode\" argument, and you replaced it with a pointer to\na struct.  DATE_NORMAL happens to be \"0\" and the compiler does not catch\ncalls you forgot to convert in this patch.\n"},{"id":"125266","messageId":"20091018071829.GA7748@coredump.intra.peff.net","threadId":"21254","inReplyTo":"e0ab6923eb4057bcbc8e97980dad5e4a37e53067.1255790816.git.trast@student.ethz.ch","subject":"Re: [PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-18T07:18:29Z","receivedAt":"2009-10-18T07:18:29Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Oct 17, 2009 at 04:48:11PM +0200, Thomas Rast wrote:\n\n> > +NOTE: Some placeholders may depend on other options given to the\n> > +revision traversal engine. For example, the `%g*` reflog options will\n> > +insert an empty string unless we are traversing reflog entries (e.g., by\n> > +`git log -g`). The `%d` placeholder will use the \"short\" decoration\n> > +format if `--decorate` was not already provided on the command line.\n> \n> Sure.  I figured it was obvious enough, but since you already went to\n> the lengths of documenting the exact behaviour of %d, I squashed it\n> and adjusted the acknowledgement in the commit message accordingly.\n\nIf the consensus (or Junio's decision when applying) is that we don't\nneed it, I don't mind if my suggestion is scrapped (or reworded).\n\n-Peff\n"},{"id":"125272","messageId":"20091018193443.6117@nanako3.lavabit.com","threadId":"21254","inReplyTo":"20091018071829.GA7748@coredump.intra.peff.net","subject":"Re: [PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information","fromName":"Nanako Shiraishi","fromEmail":"nanako3@lavabit.com","sentAt":"2009-10-18T10:34:43Z","receivedAt":"2009-10-18T10:34:43Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Quoting Jeff King <peff@peff.net>\n\n> On Sat, Oct 17, 2009 at 04:48:11PM +0200, Thomas Rast wrote:\n>\n>> > +NOTE: Some placeholders may depend on other options given to the\n>> > +revision traversal engine. For example, the `%g*` reflog options will\n>> > +insert an empty string unless we are traversing reflog entries (e.g., by\n>> > +`git log -g`). The `%d` placeholder will use the \"short\" decoration\n>> > +format if `--decorate` was not already provided on the command line.\n>> \n>> Sure.  I figured it was obvious enough, but since you already went to\n>> the lengths of documenting the exact behaviour of %d, I squashed it\n>> and adjusted the acknowledgement in the commit message accordingly.\n>\n> If the consensus (or Junio's decision when applying) is that we don't\n> need it, I don't mind if my suggestion is scrapped (or reworded).\n\nI think your clarification is a good addition.\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n"},{"id":"125288","messageId":"200910182051.20461.trast@student.ethz.ch","threadId":"21254","inReplyTo":"7vljja7xy8.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-18T18:51:16Z","receivedAt":"2009-10-18T18:51:16Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano wrote:\n> The existing calls to format_commit_message() often take DATE_NORMAL to\n> its \"enum date_mode dmode\" argument, and you replaced it with a pointer to\n> a struct.  DATE_NORMAL happens to be \"0\" and the compiler does not catch\n> calls you forgot to convert in this patch.\n\nHmph, that's embarrassing.  Apparently I was way too focused on\npretty_print_commit...\n\nI can devise a test that would have detected this.  Should I include\nit in the reroll, or is that something we do not guard against?\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"125298","messageId":"7vaazonwtr.fsf@alter.siamese.dyndns.org","threadId":"21254","inReplyTo":"200910182051.20461.trast@student.ethz.ch","subject":"Re: [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-18T22:47:44Z","receivedAt":"2009-10-18T22:47:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> Junio C Hamano wrote:\n>> The existing calls to format_commit_message() often take DATE_NORMAL to\n>> its \"enum date_mode dmode\" argument, and you replaced it with a pointer to\n>> a struct.  DATE_NORMAL happens to be \"0\" and the compiler does not catch\n>> calls you forgot to convert in this patch.\n>\n> Hmph, that's embarrassing.  Apparently I was way too focused on\n> pretty_print_commit...\n\nThis is nothing to be embarrassed about.  I did not notice it when I\nqueued the series either, and I noticed it only when I tried to look at\ninteractions with js/diff-verbose-submodule topic(the other series does\nnot hardcode the style to be DATE_NORMAL).\n\nOne solution to help the compiler catch this kind of semantic crash upon\nmerging or applying code based on the old format_commit_message() would\nhave been to change its function signature (or even the name), so that it\nwould not go unnoticed that DATE_NORMAL that happens to be \"0\" is silently\ninterpreted as (void *)0 == NULL.\n"},{"id":"125391","messageId":"cover.1255966426.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"7vaazonwtr.fsf@alter.siamese.dyndns.org","subject":"[PATCH v4 0/5] Pretty formats for reflog data","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-19T15:48:07Z","receivedAt":"2009-10-19T15:48:07Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano wrote:\n> \n> One solution to help the compiler catch this kind of semantic crash upon\n> merging or applying code based on the old format_commit_message() would\n> have been to change its function signature (or even the name), so that it\n> would not go unnoticed that DATE_NORMAL that happens to be \"0\" is silently\n> interpreted as (void *)0 == NULL.\n\nIndeed, that would have been a good idea.  (I still don't fully see\nthe use of allowing an enum value as a pointer, but apparently the\nstandard's that way.)\n\nI fixed the calls to format_commit_message(), but without changing the\nfunction signature compared to the last patch.  I also decided not to\nput in the test case; the easiest I could come up with was the\nfollowing:\n\n-- 8< --\ndiff --git i/t/t5001-archive-attr.sh w/t/t5001-archive-attr.sh\nindex 426b319..0950527 100755\n--- i/t/t5001-archive-attr.sh\n+++ w/t/t5001-archive-attr.sh\n@@ -4,7 +4,7 @@ test_description='git archive attribute tests'\n \n . ./test-lib.sh\n \n-SUBSTFORMAT=%H%n\n+SUBSTFORMAT=%H%ad%n\n \n test_expect_exists() {\n \ttest_expect_success \" $1 exists\" \"test -e $1\"\n-- >8 --\n\nwhich immediately fails most tests in the file because of segfaults\nwith the buggy series.  However, it still wouldn't catch other broken\ncallers, if there were any, so I left it out.\n\nCompared to v3, I also rebased the series on current master, which\nconflicted with 7f98ebc (format_commit_message(): fix function\nsignature, 2009-10-15) so you now need that commit to apply it.\n\nFinally, I squashed a revert of 0a0c342 (git-stash documentation:\nmention default options for 'list', 2009-10-12) into 5/5 since there\nare no more default options after my patch.\n\n\nThomas Rast (5):\n  Refactor pretty_print_commit arguments into a struct\n  reflog-walk: refactor the branch@{num} formatting\n  Introduce new pretty formats %g[sdD] for reflog information\n  stash list: use new %g formats instead of sed\n  stash list: drop the default limit of 10 stashes\n\n Documentation/git-stash.txt      |    3 +-\n Documentation/pretty-formats.txt |    9 ++++\n archive.c                        |    4 +-\n builtin-branch.c                 |    3 +-\n builtin-checkout.c               |    3 +-\n builtin-commit.c                 |    8 +++-\n builtin-log.c                    |    3 +-\n builtin-merge.c                  |    7 ++-\n builtin-rev-list.c               |    7 ++-\n builtin-shortlog.c               |    9 +++-\n builtin-show-branch.c            |    4 +-\n commit.h                         |   20 ++++++---\n git-stash.sh                     |    8 +---\n log-tree.c                       |   25 ++++++-----\n pretty.c                         |   44 ++++++++++++++------\n reflog-walk.c                    |   83 ++++++++++++++++++++++++++++----------\n reflog-walk.h                    |    8 ++++\n t/t6006-rev-list-format.sh       |   18 ++++++++\n 18 files changed, 189 insertions(+), 77 deletions(-)\n"},{"id":"125395","messageId":"4fc7837bce359b8de8dc2e4f8ce3d41e05627427.1255966426.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255966426.git.trast@student.ethz.ch","subject":"[PATCH v4 1/5] Refactor pretty_print_commit arguments into a struct","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-19T15:48:08Z","receivedAt":"2009-10-19T15:48:08Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"pretty_print_commit() has a bunch of rarely-used arguments, and\nintroducing more of them requires yet another update of all the call\nsites.  Refactor most of them into a struct to make future extensions\neasier.\n\nThe ones that stay \"plain\" arguments were chosen on the grounds that\nall callers put real arguments there, whereas some callers have 0/NULL\nfor all arguments that were factored into the struct.\n\nWe declare the struct 'const' to ensure none of the callers are bitten\nby the changed (no longer call-by-value) semantics.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n archive.c             |    4 +++-\n builtin-branch.c      |    3 ++-\n builtin-checkout.c    |    3 ++-\n builtin-commit.c      |    8 ++++++--\n builtin-log.c         |    3 ++-\n builtin-merge.c       |    7 +++++--\n builtin-rev-list.c    |    7 ++++---\n builtin-shortlog.c    |    9 ++++++---\n builtin-show-branch.c |    4 ++--\n commit.h              |   19 +++++++++++++------\n log-tree.c            |   24 +++++++++++++-----------\n pretty.c              |   27 ++++++++++++++-------------\n 12 files changed, 72 insertions(+), 46 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 0cc79d2..55b2732 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -31,6 +31,8 @@ static void format_subst(const struct commit *commit,\n {\n \tchar *to_free = NULL;\n \tstruct strbuf fmt = STRBUF_INIT;\n+\tstruct pretty_print_context ctx = {0};\n+\tctx.date_mode = DATE_NORMAL;\n \n \tif (src == buf->buf)\n \t\tto_free = strbuf_detach(buf, NULL);\n@@ -48,7 +50,7 @@ static void format_subst(const struct commit *commit,\n \t\tstrbuf_add(&fmt, b + 8, c - b - 8);\n \n \t\tstrbuf_add(buf, src, b - src);\n-\t\tformat_commit_message(commit, fmt.buf, buf, DATE_NORMAL);\n+\t\tformat_commit_message(commit, fmt.buf, buf, &ctx);\n \t\tlen -= c + 1 - src;\n \t\tsrc  = c + 1;\n \t}\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex 9f57992..05e876e 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -387,8 +387,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,\n \n \t\tcommit = item->commit;\n \t\tif (commit && !parse_commit(commit)) {\n+\t\t\tstruct pretty_print_context ctx = {0};\n \t\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t\t\t    &subject, 0, NULL, NULL, 0, 0);\n+\t\t\t\t\t    &subject, &ctx);\n \t\t\tsub = subject.buf;\n \t\t}\n \ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex d050c37..075a49f 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -302,8 +302,9 @@ static void show_local_changes(struct object *head)\n static void describe_detached_head(char *msg, struct commit *commit)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n+\tstruct pretty_print_context ctx = {0};\n \tparse_commit(commit);\n-\tpretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);\n+\tpretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx);\n \tfprintf(stderr, \"%s %s... %s\\n\", msg,\n \t\tfind_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);\n \tstrbuf_release(&sb);\ndiff --git a/builtin-commit.c b/builtin-commit.c\nindex 200ffda..ac173f9 100644\n--- a/builtin-commit.c\n+++ b/builtin-commit.c\n@@ -684,8 +684,10 @@ static int message_is_empty(struct strbuf *sb)\n \tprepare_revision_walk(&revs);\n \tcommit = get_revision(&revs);\n \tif (commit) {\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tctx.date_mode = DATE_NORMAL;\n \t\tstrbuf_release(&buf);\n-\t\tformat_commit_message(commit, \"%an <%ae>\", &buf, DATE_NORMAL);\n+\t\tformat_commit_message(commit, \"%an <%ae>\", &buf, &ctx);\n \t\treturn strbuf_detach(&buf, NULL);\n \t}\n \tdie(\"No existing author found with '%s'\", name);\n@@ -942,8 +944,10 @@ static void print_summary(const char *prefix, const unsigned char *sha1)\n \t\tinitial_commit ? \" (root-commit)\" : \"\");\n \n \tif (!log_tree_commit(&rev, commit)) {\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tctx.date_mode = DATE_NORMAL;\n \t\tstruct strbuf buf = STRBUF_INIT;\n-\t\tformat_commit_message(commit, format + 7, &buf, DATE_NORMAL);\n+\t\tformat_commit_message(commit, format + 7, &buf, &ctx);\n \t\tprintf(\"%s\\n\", buf.buf);\n \t\tstrbuf_release(&buf);\n \t}\ndiff --git a/builtin-log.c b/builtin-log.c\nindex 25e21ed..207a361 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -1304,8 +1304,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)\n \n \t\tif (verbose) {\n \t\t\tstruct strbuf buf = STRBUF_INIT;\n+\t\t\tstruct pretty_print_context ctx = {0};\n \t\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t                    &buf, 0, NULL, NULL, 0, 0);\n+\t\t\t\t\t    &buf, &ctx);\n \t\t\tprintf(\"%c %s %s\\n\", sign,\n \t\t\t       sha1_to_hex(commit->object.sha1), buf.buf);\n \t\t\tstrbuf_release(&buf);\ndiff --git a/builtin-merge.c b/builtin-merge.c\nindex b6b8428..c69a305 100644\n--- a/builtin-merge.c\n+++ b/builtin-merge.c\n@@ -264,6 +264,7 @@ static void squash_message(void)\n \tstruct strbuf out = STRBUF_INIT;\n \tstruct commit_list *j;\n \tint fd;\n+\tstruct pretty_print_context ctx = {0};\n \n \tprintf(\"Squash commit -- not updating HEAD\\n\");\n \tfd = open(git_path(\"SQUASH_MSG\"), O_WRONLY | O_CREAT, 0666);\n@@ -285,13 +286,15 @@ static void squash_message(void)\n \tif (prepare_revision_walk(&rev))\n \t\tdie(\"revision walk setup failed\");\n \n+\tctx.abbrev = rev.abbrev;\n+\tctx.date_mode = rev.date_mode;\n+\n \tstrbuf_addstr(&out, \"Squashed commit of the following:\\n\");\n \twhile ((commit = get_revision(&rev)) != NULL) {\n \t\tstrbuf_addch(&out, '\\n');\n \t\tstrbuf_addf(&out, \"commit %s\\n\",\n \t\t\tsha1_to_hex(commit->object.sha1));\n-\t\tpretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,\n-\t\t\tNULL, NULL, rev.date_mode, 0);\n+\t\tpretty_print_commit(rev.commit_format, commit, &out, &ctx);\n \t}\n \tif (write(fd, out.buf, out.len) < 0)\n \t\tdie_errno(\"Writing SQUASH_MSG\");\ndiff --git a/builtin-rev-list.c b/builtin-rev-list.c\nindex 4ba1c12..42cc8d8 100644\n--- a/builtin-rev-list.c\n+++ b/builtin-rev-list.c\n@@ -96,9 +96,10 @@ static void show_commit(struct commit *commit, void *data)\n \n \tif (revs->verbose_header && commit->buffer) {\n \t\tstruct strbuf buf = STRBUF_INIT;\n-\t\tpretty_print_commit(revs->commit_format, commit,\n-\t\t\t\t    &buf, revs->abbrev, NULL, NULL,\n-\t\t\t\t    revs->date_mode, 0);\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tctx.abbrev = revs->abbrev;\n+\t\tctx.date_mode = revs->date_mode;\n+\t\tpretty_print_commit(revs->commit_format, commit, &buf, &ctx);\n \t\tif (revs->graph) {\n \t\t\tif (buf.len) {\n \t\t\t\tif (revs->commit_format != CMIT_FMT_ONELINE)\ndiff --git a/builtin-shortlog.c b/builtin-shortlog.c\nindex 4d4a3c8..8aa63c7 100644\n--- a/builtin-shortlog.c\n+++ b/builtin-shortlog.c\n@@ -158,9 +158,12 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)\n \t\t    sha1_to_hex(commit->object.sha1));\n \tif (log->user_format) {\n \t\tstruct strbuf buf = STRBUF_INIT;\n-\n-\t\tpretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf,\n-\t\t\tDEFAULT_ABBREV, \"\", \"\", DATE_NORMAL, 0);\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tctx.abbrev = DEFAULT_ABBREV;\n+\t\tctx.subject = \"\";\n+\t\tctx.after_subject = \"\";\n+\t\tctx.date_mode = DATE_NORMAL;\n+\t\tpretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf, &ctx);\n \t\tinsert_one_record(log, author, buf.buf);\n \t\tstrbuf_release(&buf);\n \t\treturn;\ndiff --git a/builtin-show-branch.c b/builtin-show-branch.c\nindex be95930..9f13caa 100644\n--- a/builtin-show-branch.c\n+++ b/builtin-show-branch.c\n@@ -293,8 +293,8 @@ static void show_one_commit(struct commit *commit, int no_name)\n \tstruct commit_name *name = commit->util;\n \n \tif (commit->object.parsed) {\n-\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t\t    &pretty, 0, NULL, NULL, 0, 0);\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit, &pretty, &ctx);\n \t\tpretty_str = pretty.buf;\n \t}\n \tif (!prefixcmp(pretty_str, \"[PATCH] \"))\ndiff --git a/commit.h b/commit.h\nindex 95f981a..084cf55 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -63,6 +63,15 @@ enum cmit_fmt {\n \tCMIT_FMT_UNSPECIFIED,\n };\n \n+struct pretty_print_context\n+{\n+\tint abbrev;\n+\tconst char *subject;\n+\tconst char *after_subject;\n+\tenum date_mode date_mode;\n+\tint need_8bit_cte;\n+};\n+\n extern int non_ascii(int);\n extern int has_non_ascii(const char *text);\n struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */\n@@ -71,12 +80,10 @@ enum cmit_fmt {\n extern void get_commit_format(const char *arg, struct rev_info *);\n extern void format_commit_message(const struct commit *commit,\n \t\t\t\t  const char *format, struct strbuf *sb,\n-\t\t\t\t  enum date_mode dmode);\n-extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,\n-                                struct strbuf *,\n-                                int abbrev, const char *subject,\n-                                const char *after_subject, enum date_mode,\n-\t\t\t\tint need_8bit_cte);\n+\t\t\t\t  const struct pretty_print_context *context);\n+extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n+\t\t\t\tstruct strbuf *sb,\n+\t\t\t\tconst struct pretty_print_context *context);\n void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,\n \t\t   const char *line, enum date_mode dmode,\n \t\t   const char *encoding);\ndiff --git a/log-tree.c b/log-tree.c\nindex f7d54f2..1675035 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -179,8 +179,10 @@ void get_patch_filename(struct commit *commit, int nr, const char *suffix,\n \tstrbuf_addf(buf, commit ? \"%04d-\" : \"%d\", nr);\n \tif (commit) {\n \t\tint max_len = start_len + FORMAT_PATCH_NAME_MAX - suffix_len;\n+\t\tstruct pretty_print_context ctx = {0};\n+\t\tctx.date_mode = DATE_NORMAL;\n \n-\t\tformat_commit_message(commit, \"%f\", buf, DATE_NORMAL);\n+\t\tformat_commit_message(commit, \"%f\", buf, &ctx);\n \t\tif (max_len < buf->len)\n \t\t\tstrbuf_setlen(buf, max_len);\n \t\tstrbuf_addstr(buf, suffix);\n@@ -277,10 +279,9 @@ void show_log(struct rev_info *opt)\n \tstruct strbuf msgbuf = STRBUF_INIT;\n \tstruct log_info *log = opt->loginfo;\n \tstruct commit *commit = log->commit, *parent = log->parent;\n-\tint abbrev = opt->diffopt.abbrev;\n \tint abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;\n-\tconst char *subject = NULL, *extra_headers = opt->extra_headers;\n-\tint need_8bit_cte = 0;\n+\tconst char *extra_headers = opt->extra_headers;\n+\tstruct pretty_print_context ctx = {0};\n \n \topt->loginfo = NULL;\n \tif (!opt->verbose_header) {\n@@ -347,8 +348,8 @@ void show_log(struct rev_info *opt)\n \t */\n \n \tif (opt->commit_format == CMIT_FMT_EMAIL) {\n-\t\tlog_write_email_headers(opt, commit, &subject, &extra_headers,\n-\t\t\t\t\t&need_8bit_cte);\n+\t\tlog_write_email_headers(opt, commit, &ctx.subject, &extra_headers,\n+\t\t\t\t\t&ctx.need_8bit_cte);\n \t} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {\n \t\tfputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);\n \t\tif (opt->commit_format != CMIT_FMT_ONELINE)\n@@ -405,11 +406,12 @@ void show_log(struct rev_info *opt)\n \t/*\n \t * And then the pretty-printed message itself\n \t */\n-\tif (need_8bit_cte >= 0)\n-\t\tneed_8bit_cte = has_non_ascii(opt->add_signoff);\n-\tpretty_print_commit(opt->commit_format, commit, &msgbuf,\n-\t\t\t    abbrev, subject, extra_headers, opt->date_mode,\n-\t\t\t    need_8bit_cte);\n+\tif (ctx.need_8bit_cte >= 0)\n+\t\tctx.need_8bit_cte = has_non_ascii(opt->add_signoff);\n+\tctx.date_mode = opt->date_mode;\n+\tctx.abbrev = opt->diffopt.abbrev;\n+\tctx.after_subject = extra_headers;\n+\tpretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);\n \n \tif (opt->add_signoff)\n \t\tappend_signoff(&msgbuf, opt->add_signoff);\ndiff --git a/pretty.c b/pretty.c\nindex 587101f..37ad6eb 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -442,7 +442,7 @@ struct chunk {\n \n struct format_commit_context {\n \tconst struct commit *commit;\n-\tenum date_mode dmode;\n+\tconst struct pretty_print_context *pretty_ctx;\n \tunsigned commit_header_parsed:1;\n \tunsigned commit_message_parsed:1;\n \n@@ -711,11 +711,11 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,\n \tcase 'a':\t/* author ... */\n \t\treturn format_person_part(sb, placeholder[1],\n \t\t\t\t   msg + c->author.off, c->author.len,\n-\t\t\t\t   c->dmode);\n+\t\t\t\t   c->pretty_ctx->date_mode);\n \tcase 'c':\t/* committer ... */\n \t\treturn format_person_part(sb, placeholder[1],\n \t\t\t\t   msg + c->committer.off, c->committer.len,\n-\t\t\t\t   c->dmode);\n+\t\t\t\t   c->pretty_ctx->date_mode);\n \tcase 'e':\t/* encoding */\n \t\tstrbuf_add(sb, msg + c->encoding.off, c->encoding.len);\n \t\treturn 1;\n@@ -741,13 +741,13 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,\n \n void format_commit_message(const struct commit *commit,\n \t\t\t   const char *format, struct strbuf *sb,\n-\t\t\t   enum date_mode dmode)\n+\t\t\t   const struct pretty_print_context *pretty_ctx)\n {\n \tstruct format_commit_context context;\n \n \tmemset(&context, 0, sizeof(context));\n \tcontext.commit = commit;\n-\tcontext.dmode = dmode;\n+\tcontext.pretty_ctx = pretty_ctx;\n \tstrbuf_expand(sb, format, format_commit_item, &context);\n }\n \n@@ -900,18 +900,18 @@ void pp_remainder(enum cmit_fmt fmt,\n }\n \n void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n-\t\t\t struct strbuf *sb, int abbrev,\n-\t\t\t const char *subject, const char *after_subject,\n-\t\t\t enum date_mode dmode, int need_8bit_cte)\n+\t\t\t struct strbuf *sb,\n+\t\t\t const struct pretty_print_context *context)\n {\n \tunsigned long beginning_of_body;\n \tint indent = 4;\n \tconst char *msg = commit->buffer;\n \tchar *reencoded;\n \tconst char *encoding;\n+\tint need_8bit_cte = context->need_8bit_cte;\n \n \tif (fmt == CMIT_FMT_USERFORMAT) {\n-\t\tformat_commit_message(commit, user_format, sb, dmode);\n+\t\tformat_commit_message(commit, user_format, sb, context);\n \t\treturn;\n \t}\n \n@@ -946,8 +946,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n \t\t}\n \t}\n \n-\tpp_header(fmt, abbrev, dmode, encoding, commit, &msg, sb);\n-\tif (fmt != CMIT_FMT_ONELINE && !subject) {\n+\tpp_header(fmt, context->abbrev, context->date_mode, encoding,\n+\t\t  commit, &msg, sb);\n+\tif (fmt != CMIT_FMT_ONELINE && !context->subject) {\n \t\tstrbuf_addch(sb, '\\n');\n \t}\n \n@@ -956,8 +957,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n \n \t/* These formats treat the title line specially. */\n \tif (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)\n-\t\tpp_title_line(fmt, &msg, sb, subject,\n-\t\t\t      after_subject, encoding, need_8bit_cte);\n+\t\tpp_title_line(fmt, &msg, sb, context->subject,\n+\t\t\t      context->after_subject, encoding, need_8bit_cte);\n \n \tbeginning_of_body = sb->len;\n \tif (fmt != CMIT_FMT_ONELINE)\n-- \n1.6.5.1.137.gefbc6\n"},{"id":"125393","messageId":"282b5085960e160c435157218af34a01706bb055.1255966426.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255966426.git.trast@student.ethz.ch","subject":"[PATCH v4 2/5] reflog-walk: refactor the branch@{num} formatting","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-19T15:48:09Z","receivedAt":"2009-10-19T15:48:09Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"We'll use the same output in an upcoming commit, so refactor its\nformatting (which was duplicated anyway) into a separate function.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n reflog-walk.c |   54 ++++++++++++++++++++++++++++++++----------------------\n 1 files changed, 32 insertions(+), 22 deletions(-)\n\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 5623ea6..596bafe 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -241,36 +241,46 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)\n \tcommit->object.flags &= ~(ADDED | SEEN | SHOWN);\n }\n \n-void show_reflog_message(struct reflog_walk_info *info, int oneline,\n+void get_reflog_selector(struct strbuf *sb,\n+\t\t\t struct reflog_walk_info *reflog_info,\n+\t\t\t enum date_mode dmode)\n+{\n+\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n+\tstruct reflog_info *info;\n+\n+\tif (!commit_reflog)\n+\t\treturn;\n+\n+\tstrbuf_addf(sb, \"%s@{\", commit_reflog->reflogs->ref);\n+\tif (commit_reflog->flag || dmode) {\n+\t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\t\tstrbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));\n+\t} else {\n+\t\tstrbuf_addf(sb, \"%d\", commit_reflog->reflogs->nr\n+\t\t\t    - 2 - commit_reflog->recno);\n+\t}\n+\n+\tstrbuf_addch(sb, '}');\n+}\n+\n+void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \tenum date_mode dmode)\n {\n-\tif (info && info->last_commit_reflog) {\n-\t\tstruct commit_reflog *commit_reflog = info->last_commit_reflog;\n+\tif (reflog_info && reflog_info->last_commit_reflog) {\n+\t\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n \t\tstruct reflog_info *info;\n+\t\tstruct strbuf selector = STRBUF_INIT;\n \n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\t\tget_reflog_selector(&selector, reflog_info, dmode);\n \t\tif (oneline) {\n-\t\t\tprintf(\"%s@{\", commit_reflog->reflogs->ref);\n-\t\t\tif (commit_reflog->flag || dmode)\n-\t\t\t\tprintf(\"%s\", show_date(info->timestamp,\n-\t\t\t\t\t\t       info->tz,\n-\t\t\t\t\t\t       dmode));\n-\t\t\telse\n-\t\t\t\tprintf(\"%d\", commit_reflog->reflogs->nr\n-\t\t\t\t       - 2 - commit_reflog->recno);\n-\t\t\tprintf(\"}: %s\", info->message);\n+\t\t\tprintf(\"%s: %s\", selector.buf, info->message);\n \t\t}\n \t\telse {\n-\t\t\tprintf(\"Reflog: %s@{\", commit_reflog->reflogs->ref);\n-\t\t\tif (commit_reflog->flag || dmode)\n-\t\t\t\tprintf(\"%s\", show_date(info->timestamp,\n-\t\t\t\t\t\t\tinfo->tz,\n-\t\t\t\t\t\t\tdmode));\n-\t\t\telse\n-\t\t\t\tprintf(\"%d\", commit_reflog->reflogs->nr\n-\t\t\t\t       - 2 - commit_reflog->recno);\n-\t\t\tprintf(\"} (%s)\\nReflog message: %s\",\n-\t\t\t       info->email, info->message);\n+\t\t\tprintf(\"Reflog: %s (%s)\\nReflog message: %s\",\n+\t\t\t       selector.buf, info->email, info->message);\n \t\t}\n+\n+\t\tstrbuf_release(&selector);\n \t}\n }\n-- \n1.6.5.1.137.gefbc6\n"},{"id":"125394","messageId":"323f8c160651d5d582a192c70eb3d580c21b8f8d.1255966426.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255966426.git.trast@student.ethz.ch","subject":"[PATCH v4 3/5] Introduce new pretty formats %g[sdD] for reflog information","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-19T15:48:10Z","receivedAt":"2009-10-19T15:48:10Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Add three new --pretty=format escapes:\n\n  %gD  long  reflog descriptor (e.g. refs/stash@{0})\n  %gd  short reflog descriptor (e.g. stash@{0})\n  %gs  reflog message\n\nThis is achieved by passing down the reflog info, if any, inside the\npretty_print_context struct.\n\nWe use the newly refactored get_reflog_selector(), and give it some\nextra functionality to extract a shortened ref.  The shortening is\ncached inside the commit_reflogs struct; the only allocation of it\nhappens in read_complete_reflog(), where it is initialised to 0.  Also\nadd another helper get_reflog_message() for the message extraction.\n\nNote that the --format=\"%h %gD: %gs\" tests may not work in real\nrepositories, as the --pretty formatter doesn't know to leave away the\n\": \" on the last commit in an incomplete (because git-gc removed the\nold part) reflog.  This equivalence is nevertheless the main goal of\nthis patch.\n\nThanks to Jeff King for reviews, the %gd testcase and documentation.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n Documentation/pretty-formats.txt |    9 +++++++++\n commit.h                         |    1 +\n log-tree.c                       |    1 +\n pretty.c                         |   17 +++++++++++++++++\n reflog-walk.c                    |   35 ++++++++++++++++++++++++++++++++---\n reflog-walk.h                    |    8 ++++++++\n t/t6006-rev-list-format.sh       |   18 ++++++++++++++++++\n 7 files changed, 86 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 2a845b1..38b9904 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -123,6 +123,9 @@ The placeholders are:\n - '%s': subject\n - '%f': sanitized subject line, suitable for a filename\n - '%b': body\n+- '%gD': reflog selector, e.g., `refs/stash@\\{1\\}`\n+- '%gd': shortened reflog selector, e.g., `stash@\\{1\\}`\n+- '%gs': reflog subject\n - '%Cred': switch color to red\n - '%Cgreen': switch color to green\n - '%Cblue': switch color to blue\n@@ -132,6 +135,12 @@ The placeholders are:\n - '%n': newline\n - '%x00': print a byte from a hex code\n \n+NOTE: Some placeholders may depend on other options given to the\n+revision traversal engine. For example, the `%g*` reflog options will\n+insert an empty string unless we are traversing reflog entries (e.g., by\n+`git log -g`). The `%d` placeholder will use the \"short\" decoration\n+format if `--decorate` was not already provided on the command line.\n+\n * 'tformat:'\n +\n The 'tformat:' format works exactly like 'format:', except that it\ndiff --git a/commit.h b/commit.h\nindex 084cf55..422f778 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -70,6 +70,7 @@ struct pretty_print_context\n \tconst char *after_subject;\n \tenum date_mode date_mode;\n \tint need_8bit_cte;\n+\tstruct reflog_walk_info *reflog_info;\n };\n \n extern int non_ascii(int);\ndiff --git a/log-tree.c b/log-tree.c\nindex 1675035..0fdf159 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -411,6 +411,7 @@ void show_log(struct rev_info *opt)\n \tctx.date_mode = opt->date_mode;\n \tctx.abbrev = opt->diffopt.abbrev;\n \tctx.after_subject = extra_headers;\n+\tctx.reflog_info = opt->reflog_info;\n \tpretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);\n \n \tif (opt->add_signoff)\ndiff --git a/pretty.c b/pretty.c\nindex 37ad6eb..da15cf2 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -7,6 +7,7 @@\n #include \"mailmap.h\"\n #include \"log-tree.h\"\n #include \"color.h\"\n+#include \"reflog-walk.h\"\n \n static char *user_format;\n \n@@ -701,6 +702,22 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,\n \tcase 'd':\n \t\tformat_decoration(sb, commit);\n \t\treturn 1;\n+\tcase 'g':\t\t/* reflog info */\n+\t\tswitch(placeholder[1]) {\n+\t\tcase 'd':\t/* reflog selector */\n+\t\tcase 'D':\n+\t\t\tif (c->pretty_ctx->reflog_info)\n+\t\t\t\tget_reflog_selector(sb,\n+\t\t\t\t\t\t    c->pretty_ctx->reflog_info,\n+\t\t\t\t\t\t    c->pretty_ctx->date_mode,\n+\t\t\t\t\t\t    (placeholder[1] == 'd'));\n+\t\t\treturn 2;\n+\t\tcase 's':\t/* reflog message */\n+\t\t\tif (c->pretty_ctx->reflog_info)\n+\t\t\t\tget_reflog_message(sb, c->pretty_ctx->reflog_info);\n+\t\t\treturn 2;\n+\t\t}\n+\t\treturn 0;\t/* unknown %g placeholder */\n \t}\n \n \t/* For the rest we have to parse the commit header. */\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 596bafe..caba4f7 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -8,6 +8,7 @@\n \n struct complete_reflogs {\n \tchar *ref;\n+\tconst char *short_ref;\n \tstruct reflog_info {\n \t\tunsigned char osha1[20], nsha1[20];\n \t\tchar *email;\n@@ -243,15 +244,26 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)\n \n void get_reflog_selector(struct strbuf *sb,\n \t\t\t struct reflog_walk_info *reflog_info,\n-\t\t\t enum date_mode dmode)\n+\t\t\t enum date_mode dmode,\n+\t\t\t int shorten)\n {\n \tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n \tstruct reflog_info *info;\n+\tconst char *printed_ref;\n \n \tif (!commit_reflog)\n \t\treturn;\n \n-\tstrbuf_addf(sb, \"%s@{\", commit_reflog->reflogs->ref);\n+\tif (shorten) {\n+\t\tif (!commit_reflog->reflogs->short_ref)\n+\t\t\tcommit_reflog->reflogs->short_ref\n+\t\t\t\t= shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);\n+\t\tprinted_ref = commit_reflog->reflogs->short_ref;\n+\t} else {\n+\t\tprinted_ref = commit_reflog->reflogs->ref;\n+\t}\n+\n+\tstrbuf_addf(sb, \"%s@{\", printed_ref);\n \tif (commit_reflog->flag || dmode) {\n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n \t\tstrbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));\n@@ -263,6 +275,23 @@ void get_reflog_selector(struct strbuf *sb,\n \tstrbuf_addch(sb, '}');\n }\n \n+void get_reflog_message(struct strbuf *sb,\n+\t\t\tstruct reflog_walk_info *reflog_info)\n+{\n+\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n+\tstruct reflog_info *info;\n+\tsize_t len;\n+\n+\tif (!commit_reflog)\n+\t\treturn;\n+\n+\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\tlen = strlen(info->message);\n+\tif (len > 0)\n+\t\tlen--; /* strip away trailing newline */\n+\tstrbuf_add(sb, info->message, len);\n+}\n+\n void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \tenum date_mode dmode)\n {\n@@ -272,7 +301,7 @@ void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \t\tstruct strbuf selector = STRBUF_INIT;\n \n \t\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n-\t\tget_reflog_selector(&selector, reflog_info, dmode);\n+\t\tget_reflog_selector(&selector, reflog_info, dmode, 0);\n \t\tif (oneline) {\n \t\t\tprintf(\"%s: %s\", selector.buf, info->message);\n \t\t}\ndiff --git a/reflog-walk.h b/reflog-walk.h\nindex 74c9096..7bd2cd4 100644\n--- a/reflog-walk.h\n+++ b/reflog-walk.h\n@@ -3,6 +3,8 @@\n \n #include \"cache.h\"\n \n+struct reflog_walk_info;\n+\n extern void init_reflog_walk(struct reflog_walk_info** info);\n extern int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\tstruct commit *commit, const char *name);\n@@ -10,5 +12,11 @@ extern void fake_reflog_parent(struct reflog_walk_info *info,\n \t\tstruct commit *commit);\n extern void show_reflog_message(struct reflog_walk_info *info, int,\n \t\tenum date_mode);\n+extern void get_reflog_message(struct strbuf *sb,\n+\t\tstruct reflog_walk_info *reflog_info);\n+extern void get_reflog_selector(struct strbuf *sb,\n+\t\tstruct reflog_walk_info *reflog_info,\n+\t\tenum date_mode dmode,\n+\t\tint shorten);\n \n #endif\ndiff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh\nindex 59d1f62..7f61ab0 100755\n--- a/t/t6006-rev-list-format.sh\n+++ b/t/t6006-rev-list-format.sh\n@@ -162,4 +162,22 @@ test_expect_success 'empty email' '\n \t}\n '\n \n+test_expect_success '\"%h %gD: %gs\" is same as git-reflog' '\n+\tgit reflog >expect &&\n+\tgit log -g --format=\"%h %gD: %gs\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '\"%h %gD: %gs\" is same as git-reflog (with date)' '\n+\tgit reflog --date=raw >expect &&\n+\tgit log -g --format=\"%h %gD: %gs\" --date=raw >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '%gd shortens ref name' '\n+\techo \"master@{0}\" >expect.gd-short &&\n+\tgit log -g -1 --format=%gd refs/heads/master >actual.gd-short &&\n+\ttest_cmp expect.gd-short actual.gd-short\n+'\n+\n test_done\n-- \n1.6.5.1.137.gefbc6\n"},{"id":"125396","messageId":"8f0b033e3359df6cf5068767dc8eef0fa9f2f82f.1255966426.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255966426.git.trast@student.ethz.ch","subject":"[PATCH v4 4/5] stash list: use new %g formats instead of sed","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-19T15:48:11Z","receivedAt":"2009-10-19T15:48:11Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"With the new formats, we can rewrite 'git stash list' in terms of an\nappropriate pretty format, instead of hand-editing with sed.  This has\nthe advantage that it obeys the normal settings for git-log, notably\nthe pager.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n git-stash.sh |    3 +--\n 1 files changed, 1 insertions(+), 2 deletions(-)\n\ndiff --git a/git-stash.sh b/git-stash.sh\nindex 4febbbf..f8847c1 100755\n--- a/git-stash.sh\n+++ b/git-stash.sh\n@@ -205,8 +205,7 @@ have_stash () {\n \n list_stash () {\n \thave_stash || return 0\n-\tgit log --no-color --pretty=oneline -g \"$@\" $ref_stash -- |\n-\tsed -n -e 's/^[.0-9a-f]* refs\\///p'\n+\tgit log --format=\"%gd: %gs\" -g \"$@\" $ref_stash --\n }\n \n show_stash () {\n-- \n1.6.5.1.137.gefbc6\n"},{"id":"125392","messageId":"25199f42f705f14d58876777241e0d561e2e10d9.1255966426.git.trast@student.ethz.ch","threadId":"21254","inReplyTo":"cover.1255966426.git.trast@student.ethz.ch","subject":"[PATCH v4 5/5] stash list: drop the default limit of 10 stashes","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-19T15:48:12Z","receivedAt":"2009-10-19T15:48:12Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"'git stash list' had an undocumented limit of 10 stashes, unless other\ngit-log arguments were specified.  This surprised at least one user,\nbut possibly served to cut the output below a screenful without using\na pager.\n\nSince the last commit, 'git stash list' will fire up a pager according\nto the same rules as the 'git log' it calls, so we can drop the limit.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n Documentation/git-stash.txt |    3 +--\n git-stash.sh                |    5 -----\n 2 files changed, 1 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt\nindex fafe728..3f14b72 100644\n--- a/Documentation/git-stash.txt\n+++ b/Documentation/git-stash.txt\n@@ -78,8 +78,7 @@ stash@{1}: On master: 9cc0589... Add git-stash\n ----------------------------------------------------------------\n +\n The command takes options applicable to the 'git-log'\n-command to control what is shown and how. If no options are set, the\n-default is `-n 10`. See linkgit:git-log[1].\n+command to control what is shown and how. See linkgit:git-log[1].\n \n show [<stash>]::\n \ndiff --git a/git-stash.sh b/git-stash.sh\nindex f8847c1..f796c2f 100755\n--- a/git-stash.sh\n+++ b/git-stash.sh\n@@ -382,11 +382,6 @@ test -n \"$seen_non_option\" || set \"save\" \"$@\"\n case \"$1\" in\n list)\n \tshift\n-\tif test $# = 0\n-\tthen\n-\t\tset x -n 10\n-\t\tshift\n-\tfi\n \tlist_stash \"$@\"\n \t;;\n show)\n-- \n1.6.5.1.137.gefbc6\n"}]}