All of lore.kernel.org
 help / color / mirror / Atom feed
* git stash list with more than 10 items?
@ 2009-10-12 15:47 Jef Driesen
  2009-10-12 17:52 ` Jeff King
  0 siblings, 1 reply; 49+ messages in thread
From: Jef Driesen @ 2009-10-12 15:47 UTC (permalink / raw)
  To: git

Hi,

Is it possible to make "git stash list" show more than 10 items?

Jef

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: git stash list with more than 10 items?
  2009-10-12 15:47 git stash list with more than 10 items? Jef Driesen
@ 2009-10-12 17:52 ` Jeff King
  2009-10-12 19:37   ` [PATCH] git-stash documentation: mention default options for 'list' Miklos Vajna
  2009-10-12 21:06   ` [RFC PATCH 0/5] Pretty formats for reflog data Thomas Rast
  0 siblings, 2 replies; 49+ messages in thread
From: Jeff King @ 2009-10-12 17:52 UTC (permalink / raw)
  To: Jef Driesen; +Cc: git

On Mon, Oct 12, 2009 at 05:47:34PM +0200, Jef Driesen wrote:

> Is it possible to make "git stash list" show more than 10 items?

Try "git stash list -30".

Stash listing is internally just "git log -g refs/stash", so you can
pass any formatting or limiting arguments you want there (see the git
log documentation for ideas). If no arguments are given, we pass "-10".

-Peff

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH] git-stash documentation: mention default options for 'list'
  2009-10-12 17:52 ` Jeff King
@ 2009-10-12 19:37   ` Miklos Vajna
  2009-10-12 19:39     ` Jeff King
  2009-10-12 21:06   ` [RFC PATCH 0/5] Pretty formats for reflog data Thomas Rast
  1 sibling, 1 reply; 49+ messages in thread
From: Miklos Vajna @ 2009-10-12 19:37 UTC (permalink / raw)
  To: Jeff King; +Cc: Jef Driesen, git

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---

I just noticed this was not mentioned in the manpage.

 Documentation/git-stash.txt |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index 3f14b72..fafe728 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -78,7 +78,8 @@ stash@{1}: On master: 9cc0589... Add git-stash
 ----------------------------------------------------------------
 +
 The command takes options applicable to the 'git-log'
-command to control what is shown and how. See linkgit:git-log[1].
+command to control what is shown and how. If no options are set, the
+default is `-n 10`. See linkgit:git-log[1].
 
 show [<stash>]::
 
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH] git-stash documentation: mention default options for 'list'
  2009-10-12 19:37   ` [PATCH] git-stash documentation: mention default options for 'list' Miklos Vajna
@ 2009-10-12 19:39     ` Jeff King
  0 siblings, 0 replies; 49+ messages in thread
From: Jeff King @ 2009-10-12 19:39 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: Jef Driesen, git

On Mon, Oct 12, 2009 at 09:37:39PM +0200, Miklos Vajna wrote:

> I just noticed this was not mentioned in the manpage.

Thanks, looks like an improvement to me.

-Peff

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [RFC PATCH 0/5] Pretty formats for reflog data
  2009-10-12 17:52 ` Jeff King
  2009-10-12 19:37   ` [PATCH] git-stash documentation: mention default options for 'list' Miklos Vajna
@ 2009-10-12 21:06   ` Thomas Rast
  2009-10-12 21:06     ` [RFC PATCH 1/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
                       ` (5 more replies)
  1 sibling, 6 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-12 21:06 UTC (permalink / raw)
  To: Jef Driesen, Jef Driesen; +Cc: Jeff King, Nanako Shiraishi, git

[I forgot to address the list on the first batch, sorry for the spam.]

Jeff King wrote:
> On Mon, Oct 12, 2009 at 05:47:34PM +0200, Jef Driesen wrote:
> 
> > Is it possible to make "git stash list" show more than 10 items?
> 
> Try "git stash list -30".
> 
> Stash listing is internally just "git log -g refs/stash", so you can
> pass any formatting or limiting arguments you want there (see the git
> log documentation for ideas). If no arguments are given, we pass "-10".

This seems fairly arbitrary, doesn't it?  My own working theory is
that Nanako put it in because the git-log|sed construct inherently
bars any way to a pager, so it needs to be cut short.

So suppose we could somehow get rid of the |sed... like if we had
--pretty specifiers for the reflog information.

Sadly

  git log -g --format="%h %g: %G"

still fails to exactly replicate the reflog format: if the reflog was
cut off during garbage collection, the last entry refers to a no
longer existing commit causing a stray ':' on that line.  Oh, well.

It's also still RFC because:

* I don't like the massive code churn in 2/5, maybe someone sees a
  better option.

* 5/5 has a pretty lame excuse.  I could also just change it in 'git
  stash list' to limit the backwards-incompatibility damage, but
  that's also a maintenance headache.


Thomas Rast (5):
  reflog-walk: refactor the branch@{num} formatting
  Introduce new pretty formats %g and %G for reflog information
  stash: Use new %g/%G formats instead of sed
  stash list: drop the default limit of 10 stashes
  stash: change built-in ref to 'stash' instead of 'refs/stash'

 archive.c             |    2 +-
 builtin-branch.c      |    3 +-
 builtin-checkout.c    |    2 +-
 builtin-commit.c      |    4 +-
 builtin-log.c         |    2 +-
 builtin-merge.c       |    2 +-
 builtin-rev-list.c    |    2 +-
 builtin-shortlog.c    |    2 +-
 builtin-show-branch.c |    2 +-
 commit.h              |    7 +++-
 git-stash.sh          |   10 +-----
 log-tree.c            |    4 +-
 pretty.c              |   20 +++++++++++--
 reflog-walk.c         |   72 ++++++++++++++++++++++++++++++++++---------------
 reflog-walk.h         |    7 +++++
 15 files changed, 94 insertions(+), 47 deletions(-)

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [RFC PATCH 1/5] reflog-walk: refactor the branch@{num} formatting
  2009-10-12 21:06   ` [RFC PATCH 0/5] Pretty formats for reflog data Thomas Rast
@ 2009-10-12 21:06     ` Thomas Rast
  2009-10-12 21:06     ` [RFC PATCH 2/5] Introduce new pretty formats %g and %G for reflog information Thomas Rast
                       ` (4 subsequent siblings)
  5 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-12 21:06 UTC (permalink / raw)
  To: Jef Driesen; +Cc: Jeff King, Nanako Shiraishi, git

We'll use the same output in an upcoming commit, so refactor its
formatting (which was duplicated anyway) into a separate function.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 reflog-walk.c |   56 ++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/reflog-walk.c b/reflog-walk.c
index 5623ea6..9478dbc 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -241,36 +241,48 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
 	commit->object.flags &= ~(ADDED | SEEN | SHOWN);
 }
 
-void show_reflog_message(struct reflog_walk_info *info, int oneline,
+void get_reflog_selector(struct strbuf *sb,
+			 struct reflog_walk_info *reflog_info,
+			 enum date_mode dmode)
+{
+	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+	struct reflog_info *info;
+
+	if (!commit_reflog)
+		return;
+
+	strbuf_addf(sb, "%s@{", commit_reflog->reflogs->ref);
+	if (commit_reflog->flag || dmode) {
+		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+		strbuf_addf(sb, "%s", show_date(info->timestamp,
+						info->tz,
+						dmode));
+	} else {
+		strbuf_addf(sb, "%d", commit_reflog->reflogs->nr
+			    - 2 - commit_reflog->recno);
+	}
+
+	strbuf_addch(sb, '}');
+}
+
+void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 	enum date_mode dmode)
 {
-	if (info && info->last_commit_reflog) {
-		struct commit_reflog *commit_reflog = info->last_commit_reflog;
+	if (reflog_info && reflog_info->last_commit_reflog) {
+		struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
 		struct reflog_info *info;
+		struct strbuf selector = STRBUF_INIT;
 
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+		get_reflog_selector(&selector, reflog_info, dmode);
 		if (oneline) {
-			printf("%s@{", commit_reflog->reflogs->ref);
-			if (commit_reflog->flag || dmode)
-				printf("%s", show_date(info->timestamp,
-						       info->tz,
-						       dmode));
-			else
-				printf("%d", commit_reflog->reflogs->nr
-				       - 2 - commit_reflog->recno);
-			printf("}: %s", info->message);
+			printf("%s: %s", selector.buf, info->message);
 		}
 		else {
-			printf("Reflog: %s@{", commit_reflog->reflogs->ref);
-			if (commit_reflog->flag || dmode)
-				printf("%s", show_date(info->timestamp,
-							info->tz,
-							dmode));
-			else
-				printf("%d", commit_reflog->reflogs->nr
-				       - 2 - commit_reflog->recno);
-			printf("} (%s)\nReflog message: %s",
-			       info->email, info->message);
+			printf("Reflog: %s (%s)\nReflog message: %s",
+			       selector.buf, info->email, info->message);
 		}
+
+		strbuf_release(&selector);
 	}
 }
-- 
1.6.5.64.g01287

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [RFC PATCH 2/5] Introduce new pretty formats %g and %G for reflog information
  2009-10-12 21:06   ` [RFC PATCH 0/5] Pretty formats for reflog data Thomas Rast
  2009-10-12 21:06     ` [RFC PATCH 1/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
@ 2009-10-12 21:06     ` Thomas Rast
  2009-10-14  4:59       ` Jeff King
  2009-10-14  9:13       ` Junio C Hamano
  2009-10-12 21:06     ` [RFC PATCH 3/5] stash: Use new %g/%G formats instead of sed Thomas Rast
                       ` (3 subsequent siblings)
  5 siblings, 2 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-12 21:06 UTC (permalink / raw)
  To: Jef Driesen; +Cc: Jeff King, Nanako Shiraishi, git

Add two new pretty escapes: %g expands to the reflog selector (i.e.,
branch@{number} or branch@{date}) and %G expands to the reflog
message.

We use the newly refactored selector formatting function and introduce
another wrapper to get the reflog message.

Unfortunately, we also need to pass down the reflog_walk_info from
show_log(), so this commit touches a lot of (unrelated) callers to
pretty_print_commit() and format_commit_message() to accomodate the
extra argument.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 archive.c             |    2 +-
 builtin-branch.c      |    3 ++-
 builtin-checkout.c    |    2 +-
 builtin-commit.c      |    4 ++--
 builtin-log.c         |    2 +-
 builtin-merge.c       |    2 +-
 builtin-rev-list.c    |    2 +-
 builtin-shortlog.c    |    2 +-
 builtin-show-branch.c |    2 +-
 commit.h              |    7 +++++--
 log-tree.c            |    4 ++--
 pretty.c              |   20 +++++++++++++++++---
 reflog-walk.c         |   16 ++++++++++++++++
 reflog-walk.h         |    7 +++++++
 14 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/archive.c b/archive.c
index 0cc79d2..d325ce3 100644
--- a/archive.c
+++ b/archive.c
@@ -48,7 +48,7 @@ static void format_subst(const struct commit *commit,
 		strbuf_add(&fmt, b + 8, c - b - 8);
 
 		strbuf_add(buf, src, b - src);
-		format_commit_message(commit, fmt.buf, buf, DATE_NORMAL);
+		format_commit_message(commit, fmt.buf, buf, DATE_NORMAL, NULL);
 		len -= c + 1 - src;
 		src  = c + 1;
 	}
diff --git a/builtin-branch.c b/builtin-branch.c
index 9f57992..d90bfaf 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -388,7 +388,8 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 		commit = item->commit;
 		if (commit && !parse_commit(commit)) {
 			pretty_print_commit(CMIT_FMT_ONELINE, commit,
-					    &subject, 0, NULL, NULL, 0, 0);
+					    &subject, 0, NULL, NULL, 0, 0,
+					    NULL);
 			sub = subject.buf;
 		}
 
diff --git a/builtin-checkout.c b/builtin-checkout.c
index d050c37..b6b9c45 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -303,7 +303,7 @@ static void describe_detached_head(char *msg, struct commit *commit)
 {
 	struct strbuf sb = STRBUF_INIT;
 	parse_commit(commit);
-	pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);
+	pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0, NULL);
 	fprintf(stderr, "%s %s... %s\n", msg,
 		find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
 	strbuf_release(&sb);
diff --git a/builtin-commit.c b/builtin-commit.c
index 200ffda..d63d467 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -685,7 +685,7 @@ static int message_is_empty(struct strbuf *sb)
 	commit = get_revision(&revs);
 	if (commit) {
 		strbuf_release(&buf);
-		format_commit_message(commit, "%an <%ae>", &buf, DATE_NORMAL);
+		format_commit_message(commit, "%an <%ae>", &buf, DATE_NORMAL, NULL);
 		return strbuf_detach(&buf, NULL);
 	}
 	die("No existing author found with '%s'", name);
@@ -943,7 +943,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
 
 	if (!log_tree_commit(&rev, commit)) {
 		struct strbuf buf = STRBUF_INIT;
-		format_commit_message(commit, format + 7, &buf, DATE_NORMAL);
+		format_commit_message(commit, format + 7, &buf, DATE_NORMAL, NULL);
 		printf("%s\n", buf.buf);
 		strbuf_release(&buf);
 	}
diff --git a/builtin-log.c b/builtin-log.c
index 25e21ed..57df76e 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -1305,7 +1305,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
 		if (verbose) {
 			struct strbuf buf = STRBUF_INIT;
 			pretty_print_commit(CMIT_FMT_ONELINE, commit,
-			                    &buf, 0, NULL, NULL, 0, 0);
+			                    &buf, 0, NULL, NULL, 0, 0, NULL);
 			printf("%c %s %s\n", sign,
 			       sha1_to_hex(commit->object.sha1), buf.buf);
 			strbuf_release(&buf);
diff --git a/builtin-merge.c b/builtin-merge.c
index b6b8428..70f1488 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -291,7 +291,7 @@ static void squash_message(void)
 		strbuf_addf(&out, "commit %s\n",
 			sha1_to_hex(commit->object.sha1));
 		pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,
-			NULL, NULL, rev.date_mode, 0);
+			NULL, NULL, rev.date_mode, 0, NULL);
 	}
 	if (write(fd, out.buf, out.len) < 0)
 		die_errno("Writing SQUASH_MSG");
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 4ba1c12..78659c8 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -98,7 +98,7 @@ static void show_commit(struct commit *commit, void *data)
 		struct strbuf buf = STRBUF_INIT;
 		pretty_print_commit(revs->commit_format, commit,
 				    &buf, revs->abbrev, NULL, NULL,
-				    revs->date_mode, 0);
+				    revs->date_mode, 0, NULL);
 		if (revs->graph) {
 			if (buf.len) {
 				if (revs->commit_format != CMIT_FMT_ONELINE)
diff --git a/builtin-shortlog.c b/builtin-shortlog.c
index 4d4a3c8..128b382 100644
--- a/builtin-shortlog.c
+++ b/builtin-shortlog.c
@@ -160,7 +160,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
 		struct strbuf buf = STRBUF_INIT;
 
 		pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf,
-			DEFAULT_ABBREV, "", "", DATE_NORMAL, 0);
+			DEFAULT_ABBREV, "", "", DATE_NORMAL, 0, NULL);
 		insert_one_record(log, author, buf.buf);
 		strbuf_release(&buf);
 		return;
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index be95930..73ea7ce 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -294,7 +294,7 @@ static void show_one_commit(struct commit *commit, int no_name)
 
 	if (commit->object.parsed) {
 		pretty_print_commit(CMIT_FMT_ONELINE, commit,
-				    &pretty, 0, NULL, NULL, 0, 0);
+				    &pretty, 0, NULL, NULL, 0, 0, NULL);
 		pretty_str = pretty.buf;
 	}
 	if (!prefixcmp(pretty_str, "[PATCH] "))
diff --git a/commit.h b/commit.h
index f4fc5c5..93efeeb 100644
--- a/commit.h
+++ b/commit.h
@@ -69,14 +69,17 @@ enum cmit_fmt {
 extern char *reencode_commit_message(const struct commit *commit,
 				     const char **encoding_p);
 extern void get_commit_format(const char *arg, struct rev_info *);
+struct reflog_walk_info;
 extern void format_commit_message(const struct commit *commit,
 				  const void *format, struct strbuf *sb,
-				  enum date_mode dmode);
+				  enum date_mode dmode,
+				  struct reflog_walk_info *reflog_info);
 extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,
                                 struct strbuf *,
                                 int abbrev, const char *subject,
                                 const char *after_subject, enum date_mode,
-				int need_8bit_cte);
+				int need_8bit_cte,
+				struct reflog_walk_info *reflog_info);
 void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
 		   const char *line, enum date_mode dmode,
 		   const char *encoding);
diff --git a/log-tree.c b/log-tree.c
index 1618f3c..e75f953 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -179,7 +179,7 @@ void get_patch_filename(struct commit *commit, int nr, const char *suffix,
 	if (commit) {
 		int max_len = start_len + FORMAT_PATCH_NAME_MAX - suffix_len;
 
-		format_commit_message(commit, "%f", buf, DATE_NORMAL);
+		format_commit_message(commit, "%f", buf, DATE_NORMAL, NULL);
 		if (max_len < buf->len)
 			strbuf_setlen(buf, max_len);
 		strbuf_addstr(buf, suffix);
@@ -408,7 +408,7 @@ void show_log(struct rev_info *opt)
 		need_8bit_cte = has_non_ascii(opt->add_signoff);
 	pretty_print_commit(opt->commit_format, commit, &msgbuf,
 			    abbrev, subject, extra_headers, opt->date_mode,
-			    need_8bit_cte);
+			    need_8bit_cte, opt->reflog_info);
 
 	if (opt->add_signoff)
 		append_signoff(&msgbuf, opt->add_signoff);
diff --git a/pretty.c b/pretty.c
index f5983f8..0b67580 100644
--- a/pretty.c
+++ b/pretty.c
@@ -7,6 +7,7 @@
 #include "mailmap.h"
 #include "log-tree.h"
 #include "color.h"
+#include "reflog-walk.h"
 
 static char *user_format;
 
@@ -443,6 +444,7 @@ struct chunk {
 struct format_commit_context {
 	const struct commit *commit;
 	enum date_mode dmode;
+	struct reflog_walk_info *reflog_info;
 	unsigned commit_header_parsed:1;
 	unsigned commit_message_parsed:1;
 
@@ -701,6 +703,14 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 	case 'd':
 		format_decoration(sb, commit);
 		return 1;
+	case 'g':		/* reflog handle */
+		if (c->reflog_info)
+			get_reflog_selector(sb, c->reflog_info, c->dmode);
+		return 1;
+	case 'G':		/* reflog message */
+		if (c->reflog_info)
+			get_reflog_message(sb, c->reflog_info);
+		return 1;
 	}
 
 	/* For the rest we have to parse the commit header. */
@@ -741,13 +751,15 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 
 void format_commit_message(const struct commit *commit,
 			   const void *format, struct strbuf *sb,
-			   enum date_mode dmode)
+			   enum date_mode dmode,
+			   struct reflog_walk_info *reflog_info)
 {
 	struct format_commit_context context;
 
 	memset(&context, 0, sizeof(context));
 	context.commit = commit;
 	context.dmode = dmode;
+	context.reflog_info = reflog_info;
 	strbuf_expand(sb, format, format_commit_item, &context);
 }
 
@@ -902,7 +914,8 @@ void pp_remainder(enum cmit_fmt fmt,
 void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
 			 struct strbuf *sb, int abbrev,
 			 const char *subject, const char *after_subject,
-			 enum date_mode dmode, int need_8bit_cte)
+			 enum date_mode dmode, int need_8bit_cte,
+			 struct reflog_walk_info *reflog_info)
 {
 	unsigned long beginning_of_body;
 	int indent = 4;
@@ -911,7 +924,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
 	const char *encoding;
 
 	if (fmt == CMIT_FMT_USERFORMAT) {
-		format_commit_message(commit, user_format, sb, dmode);
+		format_commit_message(commit, user_format, sb, dmode,
+				      reflog_info);
 		return;
 	}
 
diff --git a/reflog-walk.c b/reflog-walk.c
index 9478dbc..929f025 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -265,6 +265,22 @@ void get_reflog_selector(struct strbuf *sb,
 	strbuf_addch(sb, '}');
 }
 
+void get_reflog_message(struct strbuf *sb,
+			struct reflog_walk_info *reflog_info)
+{
+	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+	struct reflog_info *info;
+
+	if (!commit_reflog)
+		return;
+
+	info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+	size_t len = strlen(info->message);
+	if (len > 0)
+		len--;
+	strbuf_add(sb, info->message, len);
+}
+
 void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 	enum date_mode dmode)
 {
diff --git a/reflog-walk.h b/reflog-walk.h
index 74c9096..986121f 100644
--- a/reflog-walk.h
+++ b/reflog-walk.h
@@ -3,6 +3,8 @@
 
 #include "cache.h"
 
+struct reflog_walk_info;
+
 extern void init_reflog_walk(struct reflog_walk_info** info);
 extern int add_reflog_for_walk(struct reflog_walk_info *info,
 		struct commit *commit, const char *name);
@@ -10,5 +12,10 @@ extern void fake_reflog_parent(struct reflog_walk_info *info,
 		struct commit *commit);
 extern void show_reflog_message(struct reflog_walk_info *info, int,
 		enum date_mode);
+extern void get_reflog_message(struct strbuf *sb,
+		struct reflog_walk_info *reflog_info);
+extern void get_reflog_selector(struct strbuf *sb,
+		struct reflog_walk_info *reflog_info,
+		enum date_mode dmode);
 
 #endif
-- 
1.6.5.64.g01287

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [RFC PATCH 3/5] stash: Use new %g/%G formats instead of sed
  2009-10-12 21:06   ` [RFC PATCH 0/5] Pretty formats for reflog data Thomas Rast
  2009-10-12 21:06     ` [RFC PATCH 1/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
  2009-10-12 21:06     ` [RFC PATCH 2/5] Introduce new pretty formats %g and %G for reflog information Thomas Rast
@ 2009-10-12 21:06     ` Thomas Rast
  2009-10-14  5:00       ` Jeff King
  2009-10-12 21:06     ` [RFC PATCH 4/5] stash list: drop the default limit of 10 stashes Thomas Rast
                       ` (2 subsequent siblings)
  5 siblings, 1 reply; 49+ messages in thread
From: Thomas Rast @ 2009-10-12 21:06 UTC (permalink / raw)
  To: Jef Driesen; +Cc: Jeff King, Nanako Shiraishi, git

With the new formats, we can rewrite 'git stash list' in terms of an
appropriate pretty format, instead of hand-editing with sed.  This has
the advantage that it obeys the normal settings for git-log, notably
the pager.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-stash.sh |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index 4febbbf..8fbf10a 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -205,8 +205,7 @@ have_stash () {
 
 list_stash () {
 	have_stash || return 0
-	git log --no-color --pretty=oneline -g "$@" $ref_stash -- |
-	sed -n -e 's/^[.0-9a-f]* refs\///p'
+	git log --format="%g: %G" -g "$@" $ref_stash
 }
 
 show_stash () {
-- 
1.6.5.64.g01287

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [RFC PATCH 4/5] stash list: drop the default limit of 10 stashes
  2009-10-12 21:06   ` [RFC PATCH 0/5] Pretty formats for reflog data Thomas Rast
                       ` (2 preceding siblings ...)
  2009-10-12 21:06     ` [RFC PATCH 3/5] stash: Use new %g/%G formats instead of sed Thomas Rast
@ 2009-10-12 21:06     ` Thomas Rast
  2009-10-14  5:02       ` Jeff King
  2009-10-12 21:06     ` [RFC PATCH 5/5] stash: change built-in ref to 'stash' instead of 'refs/stash' Thomas Rast
  2009-10-12 21:37     ` [RFC PATCH " Jeff King
  5 siblings, 1 reply; 49+ messages in thread
From: Thomas Rast @ 2009-10-12 21:06 UTC (permalink / raw)
  To: Jef Driesen; +Cc: Jeff King, Nanako Shiraishi, git

'git stash list' had an undocumented limit of 10 stashes, unless other
git-log arguments were specified.  This surprised at least one user,
but possibly served to cut the output below a screenful without using
a pager.

Since the last commit, 'git stash list' will fire up a pager according
to the same rules as the 'git log' it calls, so we can drop the limit.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-stash.sh |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index 8fbf10a..08a7669 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -382,11 +382,6 @@ test -n "$seen_non_option" || set "save" "$@"
 case "$1" in
 list)
 	shift
-	if test $# = 0
-	then
-		set x -n 10
-		shift
-	fi
 	list_stash "$@"
 	;;
 show)
-- 
1.6.5.64.g01287

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [RFC PATCH 5/5] stash: change built-in ref to 'stash' instead of 'refs/stash'
  2009-10-12 21:06   ` [RFC PATCH 0/5] Pretty formats for reflog data Thomas Rast
                       ` (3 preceding siblings ...)
  2009-10-12 21:06     ` [RFC PATCH 4/5] stash list: drop the default limit of 10 stashes Thomas Rast
@ 2009-10-12 21:06     ` Thomas Rast
  2009-10-14  5:06       ` Jeff King
  2009-10-12 21:37     ` [RFC PATCH " Jeff King
  5 siblings, 1 reply; 49+ messages in thread
From: Thomas Rast @ 2009-10-12 21:06 UTC (permalink / raw)
  To: Jef Driesen; +Cc: Jeff King, Nanako Shiraishi, git

'git stash list' now always shows 'refs/stash@{...}' instead of
'stash@{...}', because that's what we specify for the ref.

Since git checks .git/$ref, .git/refs/$ref and only then
.git/refs/{branches,tags,remotes}, we can drop the prefix.  This only
affects people who have .git/stash, who were never able to refer to
their stashes by stash@{...}.  (Sadly, now they won't be able to use
git-stash anymore at all.)

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-stash.sh |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index 08a7669..8bf464b 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -19,7 +19,7 @@ cd_to_toplevel
 TMP="$GIT_DIR/.git-stash.$$"
 trap 'rm -f "$TMP-*"' 0
 
-ref_stash=refs/stash
+ref_stash=stash
 
 if git config --get-colorbool color.interactive; then
        help_color="$(git config --get-color color.interactive.help 'red bold')"
-- 
1.6.5.64.g01287

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [RFC PATCH 0/5] Pretty formats for reflog data
  2009-10-12 21:06   ` [RFC PATCH 0/5] Pretty formats for reflog data Thomas Rast
                       ` (4 preceding siblings ...)
  2009-10-12 21:06     ` [RFC PATCH 5/5] stash: change built-in ref to 'stash' instead of 'refs/stash' Thomas Rast
@ 2009-10-12 21:37     ` Jeff King
  2009-10-12 21:52       ` Thomas Rast
  5 siblings, 1 reply; 49+ messages in thread
From: Jeff King @ 2009-10-12 21:37 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jef Driesen, Nanako Shiraishi, git

On Mon, Oct 12, 2009 at 11:02:29PM +0200, Thomas Rast wrote:

> > Stash listing is internally just "git log -g refs/stash", so you can
> > pass any formatting or limiting arguments you want there (see the git
> > log documentation for ideas). If no arguments are given, we pass "-10".
> 
> This seems fairly arbitrary, doesn't it?  My own working theory is
> that Nanako put it in because the git-log|sed construct inherently
> bars any way to a pager, so it needs to be cut short.

Yes, it's arbitrary, though it is probably a reasonable estimate for the
intended use of stash. It's a stack, so you generally are only
interested in the last couple of entries.

What's much worse though is that the logic is not "if you told me how
many to show, show that; otherwise, show 10".  Instead it is "if you
gave me no options, default the size of the list.  But if you gave me
any options, even if they have nothing whatsoever to do with limiting
the size of the list, then show all".

So something like "git stash list --date=relative" suddenly shows many more
stashes than just "git stash list". It would be nice to fix that.

> So suppose we could somehow get rid of the |sed... like if we had
> --pretty specifiers for the reflog information.

I'm not sure if people will like having a longer list in a pager than a
shorter list without one (I personally can't remember ever using "git
stash list", so I have no strong opinion).

But certainly the idea of adding pretty format specifiers to access
reflog data seems like a good idea on its own.

-Peff

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [RFC PATCH 0/5] Pretty formats for reflog data
  2009-10-12 21:37     ` [RFC PATCH " Jeff King
@ 2009-10-12 21:52       ` Thomas Rast
  0 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-12 21:52 UTC (permalink / raw)
  To: Jeff King; +Cc: Jef Driesen, Nanako Shiraishi, git

Jeff King wrote:
> 
> I'm not sure if people will like having a longer [stash] list in a
> pager than a shorter list without one (I personally can't remember
> ever using "git stash list", so I have no strong opinion).

True.  Then again we patched git-stash(1) to recommend stash/pop over
stash/apply, so we should actively show the user that s/he has a long
stash list and may want to apply them somewhere.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [RFC PATCH 2/5] Introduce new pretty formats %g and %G for reflog information
  2009-10-12 21:06     ` [RFC PATCH 2/5] Introduce new pretty formats %g and %G for reflog information Thomas Rast
@ 2009-10-14  4:59       ` Jeff King
  2009-10-14  9:58         ` Thomas Rast
  2009-10-14  9:13       ` Junio C Hamano
  1 sibling, 1 reply; 49+ messages in thread
From: Jeff King @ 2009-10-14  4:59 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jef Driesen, Nanako Shiraishi, git

On Mon, Oct 12, 2009 at 11:06:04PM +0200, Thomas Rast wrote:

> Unfortunately, we also need to pass down the reflog_walk_info from
> show_log(), so this commit touches a lot of (unrelated) callers to
> pretty_print_commit() and format_commit_message() to accomodate the
> extra argument.

A while back I wanted to add a feature to pretty-printing, and I ran
into the same situation (though my feature never made it to the list).
We really end up passing around the same arguments over and over.  Maybe
it makes sense instead of adding another argument to refactor into a
"pretty_print_context" struct that contains all of the arguments and
current state.

It would be an even more invasive patch, but I think it would make
things more readable, and make future changes much easier to see.

-Peff

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [RFC PATCH 3/5] stash: Use new %g/%G formats instead of sed
  2009-10-12 21:06     ` [RFC PATCH 3/5] stash: Use new %g/%G formats instead of sed Thomas Rast
@ 2009-10-14  5:00       ` Jeff King
  0 siblings, 0 replies; 49+ messages in thread
From: Jeff King @ 2009-10-14  5:00 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jef Driesen, Nanako Shiraishi, git

On Mon, Oct 12, 2009 at 11:06:05PM +0200, Thomas Rast wrote:

>  list_stash () {
>  	have_stash || return 0
> -	git log --no-color --pretty=oneline -g "$@" $ref_stash -- |
> -	sed -n -e 's/^[.0-9a-f]* refs\///p'
> +	git log --format="%g: %G" -g "$@" $ref_stash

You dropped the trailing "--" which is needed for disambiguation.

-Peff

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [RFC PATCH 4/5] stash list: drop the default limit of 10 stashes
  2009-10-12 21:06     ` [RFC PATCH 4/5] stash list: drop the default limit of 10 stashes Thomas Rast
@ 2009-10-14  5:02       ` Jeff King
  0 siblings, 0 replies; 49+ messages in thread
From: Jeff King @ 2009-10-14  5:02 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jef Driesen, Nanako Shiraishi, git

On Mon, Oct 12, 2009 at 11:06:06PM +0200, Thomas Rast wrote:

> 'git stash list' had an undocumented limit of 10 stashes, unless other
> git-log arguments were specified.  This surprised at least one user,
> but possibly served to cut the output below a screenful without using
> a pager.
> 
> Since the last commit, 'git stash list' will fire up a pager according
> to the same rules as the 'git log' it calls, so we can drop the limit.

Having slept on it, I think I agree that this is a good change. It fixes
the ugly corner cases I mentioned, and it is easier to explain.

-Peff

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [RFC PATCH 5/5] stash: change built-in ref to 'stash' instead of 'refs/stash'
  2009-10-12 21:06     ` [RFC PATCH 5/5] stash: change built-in ref to 'stash' instead of 'refs/stash' Thomas Rast
@ 2009-10-14  5:06       ` Jeff King
  2009-10-15 22:41         ` [PATCH v2 0/5] Pretty formats for reflog data Thomas Rast
  0 siblings, 1 reply; 49+ messages in thread
From: Jeff King @ 2009-10-14  5:06 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jef Driesen, Nanako Shiraishi, git

On Mon, Oct 12, 2009 at 11:06:07PM +0200, Thomas Rast wrote:

> 'git stash list' now always shows 'refs/stash@{...}' instead of
> 'stash@{...}', because that's what we specify for the ref.
> 
> Since git checks .git/$ref, .git/refs/$ref and only then
> .git/refs/{branches,tags,remotes}, we can drop the prefix.  This only
> affects people who have .git/stash, who were never able to refer to
> their stashes by stash@{...}.  (Sadly, now they won't be able to use
> git-stash anymore at all.)

Maybe a better solution would be a "short name" variant for pretty
format specifiers. We already have %(refname) and %(refname:short) in
for-each-ref, where the latter cuts off "refs/heads/", "refs/tags", or
"refs/remotes/" from the beginning. I'm not sure if it does just
"refs/", but probably it should. It may even check for ambiguity, but
I'd have to double-check the code.

The tricky part would be deciding on a syntax. This seems to come up a
fair bit. I think there is room for somebody to suggest a more expansive
--format syntax that can handle arbitrary arguments being given to
expansions (I think there was some discussion recently in a related
thread about body indentation, but I haven't been following it too
closely).

-Peff

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [RFC PATCH 2/5] Introduce new pretty formats %g and %G for reflog information
  2009-10-12 21:06     ` [RFC PATCH 2/5] Introduce new pretty formats %g and %G for reflog information Thomas Rast
  2009-10-14  4:59       ` Jeff King
@ 2009-10-14  9:13       ` Junio C Hamano
  1 sibling, 0 replies; 49+ messages in thread
From: Junio C Hamano @ 2009-10-14  9:13 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jef Driesen, Jeff King, Nanako Shiraishi, git

Squash this patch on top, as

    cc1: warnings being treated as errors
    reflog-walk.c: In function 'get_reflog_message':
    reflog-walk.c:278: error: ISO C90 forbids mixed declarations and code

---

 reflog-walk.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/reflog-walk.c b/reflog-walk.c
index 929f025..5cbcb1a 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -270,12 +270,13 @@ void get_reflog_message(struct strbuf *sb,
 {
 	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
 	struct reflog_info *info;
+	size_t len;
 
 	if (!commit_reflog)
 		return;
 
 	info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
-	size_t len = strlen(info->message);
+	len = strlen(info->message);
 	if (len > 0)
 		len--;
 	strbuf_add(sb, info->message, len);

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [RFC PATCH 2/5] Introduce new pretty formats %g and %G for reflog information
  2009-10-14  4:59       ` Jeff King
@ 2009-10-14  9:58         ` Thomas Rast
  0 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-14  9:58 UTC (permalink / raw)
  To: Jeff King; +Cc: Jef Driesen, Nanako Shiraishi, git

Jeff King wrote:
> On Mon, Oct 12, 2009 at 11:06:04PM +0200, Thomas Rast wrote:
> 
> > Unfortunately, we also need to pass down the reflog_walk_info from
> > show_log(), so this commit touches a lot of (unrelated) callers to
> > pretty_print_commit() and format_commit_message() to accomodate the
> > extra argument.
> 
> A while back I wanted to add a feature to pretty-printing, and I ran
> into the same situation (though my feature never made it to the list).
> We really end up passing around the same arguments over and over.  Maybe
> it makes sense instead of adding another argument to refactor into a
> "pretty_print_context" struct that contains all of the arguments and
> current state.
> 
> It would be an even more invasive patch, but I think it would make
> things more readable, and make future changes much easier to see.

Ok, I'll try for the next round.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2 0/5] Pretty formats for reflog data
  2009-10-14  5:06       ` Jeff King
@ 2009-10-15 22:41         ` Thomas Rast
  2009-10-15 22:41           ` [PATCH v2 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
                             ` (5 more replies)
  0 siblings, 6 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-15 22:41 UTC (permalink / raw)
  To: Jeff King, Junio C Hamano; +Cc: Jef Driesen, Nanako Shiraishi, git

Jeff King wrote:
> Maybe a better solution would be a "short name" variant for pretty
> format specifiers. We already have %(refname) and %(refname:short) [...]
> The tricky part would be deciding on a syntax. This seems to come up a
> fair bit.

Ok, I settled for %g[dDs] for now to save on letters.  I'm saving the
syntax question for a later series while we discuss this one ;-)

I think going for %(...) wouldn't be too bad since we already have
that in for-each-ref, and it can be backwards compatible.  So we would
have different sets of short and long specifiers, e.g.

  %ae = %(authoremail)
  %aE = %(authoremail:mailmap)

We can then pass arguments via some yet-to-be decided syntax, say,
%(body:indent(10)).

Other changes in this version include:

* I followed your struct suggestion, which is the new 1/5.

* Since the shortening can be handled by %gd, the old 5/5 (change from
  refs/stash to only stash) is no longer needed.

* I fixed the warning that Junio found (and finally found the right
  combination of -W flags, though I cannot compile with -Werror myself
  because of *other* warnings...)

I also added tests and docs to the main patch (now 3/5).

Thomas Rast (5):
  Refactor pretty_print_commit arguments into a struct
  reflog-walk: refactor the branch@{num} formatting
  Introduce new pretty formats %g[sdD] for reflog information
  stash list: use new %g formats instead of sed
  stash list: drop the default limit of 10 stashes

 Documentation/pretty-formats.txt |    3 +
 builtin-branch.c                 |    3 +-
 builtin-checkout.c               |    3 +-
 builtin-log.c                    |    3 +-
 builtin-merge.c                  |    7 ++-
 builtin-rev-list.c               |    7 ++-
 builtin-shortlog.c               |    9 +++-
 builtin-show-branch.c            |    4 +-
 commit.h                         |   20 ++++++---
 git-stash.sh                     |    8 +---
 log-tree.c                       |   21 +++++----
 pretty.c                         |   44 ++++++++++++++------
 reflog-walk.c                    |   85 ++++++++++++++++++++++++++++----------
 reflog-walk.h                    |    8 ++++
 t/t1411-reflog-show.sh           |   12 +++++
 15 files changed, 166 insertions(+), 71 deletions(-)

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2 1/5] Refactor pretty_print_commit arguments into a struct
  2009-10-15 22:41         ` [PATCH v2 0/5] Pretty formats for reflog data Thomas Rast
@ 2009-10-15 22:41           ` Thomas Rast
  2009-10-15 22:41           ` [PATCH v2 2/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
                             ` (4 subsequent siblings)
  5 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-15 22:41 UTC (permalink / raw)
  To: Jeff King, Junio C Hamano; +Cc: Jef Driesen, Nanako Shiraishi, git

pretty_print_commit() has a bunch of rarely-used arguments, and
introducing more of them requires yet another update of all the call
sites.  Refactor most of them into a struct to make future extensions
easier.

The ones that stay "plain" arguments were chosen on the grounds that
all callers put real arguments there, whereas some callers have 0/NULL
for all arguments that were factored into the struct.

We declare the struct 'const' to ensure none of the callers are bitten
by the changed (no longer call-by-value) semantics.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 builtin-branch.c      |    3 ++-
 builtin-checkout.c    |    3 ++-
 builtin-log.c         |    3 ++-
 builtin-merge.c       |    7 +++++--
 builtin-rev-list.c    |    7 ++++---
 builtin-shortlog.c    |    9 ++++++---
 builtin-show-branch.c |    4 ++--
 commit.h              |   19 +++++++++++++------
 log-tree.c            |   20 ++++++++++----------
 pretty.c              |   27 ++++++++++++++-------------
 10 files changed, 60 insertions(+), 42 deletions(-)

diff --git a/builtin-branch.c b/builtin-branch.c
index 9f57992..05e876e 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -387,8 +387,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 
 		commit = item->commit;
 		if (commit && !parse_commit(commit)) {
+			struct pretty_print_context ctx = {0};
 			pretty_print_commit(CMIT_FMT_ONELINE, commit,
-					    &subject, 0, NULL, NULL, 0, 0);
+					    &subject, &ctx);
 			sub = subject.buf;
 		}
 
diff --git a/builtin-checkout.c b/builtin-checkout.c
index d050c37..075a49f 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -302,8 +302,9 @@ static void show_local_changes(struct object *head)
 static void describe_detached_head(char *msg, struct commit *commit)
 {
 	struct strbuf sb = STRBUF_INIT;
+	struct pretty_print_context ctx = {0};
 	parse_commit(commit);
-	pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);
+	pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx);
 	fprintf(stderr, "%s %s... %s\n", msg,
 		find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
 	strbuf_release(&sb);
diff --git a/builtin-log.c b/builtin-log.c
index 25e21ed..207a361 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -1304,8 +1304,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
 
 		if (verbose) {
 			struct strbuf buf = STRBUF_INIT;
+			struct pretty_print_context ctx = {0};
 			pretty_print_commit(CMIT_FMT_ONELINE, commit,
-			                    &buf, 0, NULL, NULL, 0, 0);
+					    &buf, &ctx);
 			printf("%c %s %s\n", sign,
 			       sha1_to_hex(commit->object.sha1), buf.buf);
 			strbuf_release(&buf);
diff --git a/builtin-merge.c b/builtin-merge.c
index b6b8428..c69a305 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -264,6 +264,7 @@ static void squash_message(void)
 	struct strbuf out = STRBUF_INIT;
 	struct commit_list *j;
 	int fd;
+	struct pretty_print_context ctx = {0};
 
 	printf("Squash commit -- not updating HEAD\n");
 	fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
@@ -285,13 +286,15 @@ static void squash_message(void)
 	if (prepare_revision_walk(&rev))
 		die("revision walk setup failed");
 
+	ctx.abbrev = rev.abbrev;
+	ctx.date_mode = rev.date_mode;
+
 	strbuf_addstr(&out, "Squashed commit of the following:\n");
 	while ((commit = get_revision(&rev)) != NULL) {
 		strbuf_addch(&out, '\n');
 		strbuf_addf(&out, "commit %s\n",
 			sha1_to_hex(commit->object.sha1));
-		pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,
-			NULL, NULL, rev.date_mode, 0);
+		pretty_print_commit(rev.commit_format, commit, &out, &ctx);
 	}
 	if (write(fd, out.buf, out.len) < 0)
 		die_errno("Writing SQUASH_MSG");
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 4ba1c12..42cc8d8 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -96,9 +96,10 @@ static void show_commit(struct commit *commit, void *data)
 
 	if (revs->verbose_header && commit->buffer) {
 		struct strbuf buf = STRBUF_INIT;
-		pretty_print_commit(revs->commit_format, commit,
-				    &buf, revs->abbrev, NULL, NULL,
-				    revs->date_mode, 0);
+		struct pretty_print_context ctx = {0};
+		ctx.abbrev = revs->abbrev;
+		ctx.date_mode = revs->date_mode;
+		pretty_print_commit(revs->commit_format, commit, &buf, &ctx);
 		if (revs->graph) {
 			if (buf.len) {
 				if (revs->commit_format != CMIT_FMT_ONELINE)
diff --git a/builtin-shortlog.c b/builtin-shortlog.c
index 4d4a3c8..8aa63c7 100644
--- a/builtin-shortlog.c
+++ b/builtin-shortlog.c
@@ -158,9 +158,12 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
 		    sha1_to_hex(commit->object.sha1));
 	if (log->user_format) {
 		struct strbuf buf = STRBUF_INIT;
-
-		pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf,
-			DEFAULT_ABBREV, "", "", DATE_NORMAL, 0);
+		struct pretty_print_context ctx = {0};
+		ctx.abbrev = DEFAULT_ABBREV;
+		ctx.subject = "";
+		ctx.after_subject = "";
+		ctx.date_mode = DATE_NORMAL;
+		pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf, &ctx);
 		insert_one_record(log, author, buf.buf);
 		strbuf_release(&buf);
 		return;
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index be95930..9f13caa 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -293,8 +293,8 @@ static void show_one_commit(struct commit *commit, int no_name)
 	struct commit_name *name = commit->util;
 
 	if (commit->object.parsed) {
-		pretty_print_commit(CMIT_FMT_ONELINE, commit,
-				    &pretty, 0, NULL, NULL, 0, 0);
+		struct pretty_print_context ctx = {0};
+		pretty_print_commit(CMIT_FMT_ONELINE, commit, &pretty, &ctx);
 		pretty_str = pretty.buf;
 	}
 	if (!prefixcmp(pretty_str, "[PATCH] "))
diff --git a/commit.h b/commit.h
index f4fc5c5..011766d 100644
--- a/commit.h
+++ b/commit.h
@@ -63,6 +63,15 @@ enum cmit_fmt {
 	CMIT_FMT_UNSPECIFIED,
 };
 
+struct pretty_print_context
+{
+	int abbrev;
+	const char *subject;
+	const char *after_subject;
+	enum date_mode date_mode;
+	int need_8bit_cte;
+};
+
 extern int non_ascii(int);
 extern int has_non_ascii(const char *text);
 struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
@@ -71,12 +80,10 @@ enum cmit_fmt {
 extern void get_commit_format(const char *arg, struct rev_info *);
 extern void format_commit_message(const struct commit *commit,
 				  const void *format, struct strbuf *sb,
-				  enum date_mode dmode);
-extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,
-                                struct strbuf *,
-                                int abbrev, const char *subject,
-                                const char *after_subject, enum date_mode,
-				int need_8bit_cte);
+				  const struct pretty_print_context *context);
+extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
+				struct strbuf *sb,
+				const struct pretty_print_context *context);
 void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
 		   const char *line, enum date_mode dmode,
 		   const char *encoding);
diff --git a/log-tree.c b/log-tree.c
index f7d54f2..f57487f 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -277,10 +277,9 @@ void show_log(struct rev_info *opt)
 	struct strbuf msgbuf = STRBUF_INIT;
 	struct log_info *log = opt->loginfo;
 	struct commit *commit = log->commit, *parent = log->parent;
-	int abbrev = opt->diffopt.abbrev;
 	int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;
-	const char *subject = NULL, *extra_headers = opt->extra_headers;
-	int need_8bit_cte = 0;
+	const char *extra_headers = opt->extra_headers;
+	struct pretty_print_context ctx = {0};
 
 	opt->loginfo = NULL;
 	if (!opt->verbose_header) {
@@ -347,8 +346,8 @@ void show_log(struct rev_info *opt)
 	 */
 
 	if (opt->commit_format == CMIT_FMT_EMAIL) {
-		log_write_email_headers(opt, commit, &subject, &extra_headers,
-					&need_8bit_cte);
+		log_write_email_headers(opt, commit, &ctx.subject, &extra_headers,
+					&ctx.need_8bit_cte);
 	} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
 		fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
 		if (opt->commit_format != CMIT_FMT_ONELINE)
@@ -405,11 +404,12 @@ void show_log(struct rev_info *opt)
 	/*
 	 * And then the pretty-printed message itself
 	 */
-	if (need_8bit_cte >= 0)
-		need_8bit_cte = has_non_ascii(opt->add_signoff);
-	pretty_print_commit(opt->commit_format, commit, &msgbuf,
-			    abbrev, subject, extra_headers, opt->date_mode,
-			    need_8bit_cte);
+	if (ctx.need_8bit_cte >= 0)
+		ctx.need_8bit_cte = has_non_ascii(opt->add_signoff);
+	ctx.date_mode = opt->date_mode;
+	ctx.abbrev = opt->diffopt.abbrev;
+	ctx.after_subject = extra_headers;
+	pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);
 
 	if (opt->add_signoff)
 		append_signoff(&msgbuf, opt->add_signoff);
diff --git a/pretty.c b/pretty.c
index f5983f8..d6d57eb 100644
--- a/pretty.c
+++ b/pretty.c
@@ -442,7 +442,7 @@ struct chunk {
 
 struct format_commit_context {
 	const struct commit *commit;
-	enum date_mode dmode;
+	const struct pretty_print_context *pretty_ctx;
 	unsigned commit_header_parsed:1;
 	unsigned commit_message_parsed:1;
 
@@ -711,11 +711,11 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 	case 'a':	/* author ... */
 		return format_person_part(sb, placeholder[1],
 				   msg + c->author.off, c->author.len,
-				   c->dmode);
+				   c->pretty_ctx->date_mode);
 	case 'c':	/* committer ... */
 		return format_person_part(sb, placeholder[1],
 				   msg + c->committer.off, c->committer.len,
-				   c->dmode);
+				   c->pretty_ctx->date_mode);
 	case 'e':	/* encoding */
 		strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
 		return 1;
@@ -741,13 +741,13 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 
 void format_commit_message(const struct commit *commit,
 			   const void *format, struct strbuf *sb,
-			   enum date_mode dmode)
+			   const struct pretty_print_context *pretty_ctx)
 {
 	struct format_commit_context context;
 
 	memset(&context, 0, sizeof(context));
 	context.commit = commit;
-	context.dmode = dmode;
+	context.pretty_ctx = pretty_ctx;
 	strbuf_expand(sb, format, format_commit_item, &context);
 }
 
@@ -900,18 +900,18 @@ void pp_remainder(enum cmit_fmt fmt,
 }
 
 void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
-			 struct strbuf *sb, int abbrev,
-			 const char *subject, const char *after_subject,
-			 enum date_mode dmode, int need_8bit_cte)
+			 struct strbuf *sb,
+			 const struct pretty_print_context *context)
 {
 	unsigned long beginning_of_body;
 	int indent = 4;
 	const char *msg = commit->buffer;
 	char *reencoded;
 	const char *encoding;
+	int need_8bit_cte = context->need_8bit_cte;
 
 	if (fmt == CMIT_FMT_USERFORMAT) {
-		format_commit_message(commit, user_format, sb, dmode);
+		format_commit_message(commit, user_format, sb, context);
 		return;
 	}
 
@@ -946,8 +946,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
 		}
 	}
 
-	pp_header(fmt, abbrev, dmode, encoding, commit, &msg, sb);
-	if (fmt != CMIT_FMT_ONELINE && !subject) {
+	pp_header(fmt, context->abbrev, context->date_mode, encoding,
+		  commit, &msg, sb);
+	if (fmt != CMIT_FMT_ONELINE && !context->subject) {
 		strbuf_addch(sb, '\n');
 	}
 
@@ -956,8 +957,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
 
 	/* These formats treat the title line specially. */
 	if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
-		pp_title_line(fmt, &msg, sb, subject,
-			      after_subject, encoding, need_8bit_cte);
+		pp_title_line(fmt, &msg, sb, context->subject,
+			      context->after_subject, encoding, need_8bit_cte);
 
 	beginning_of_body = sb->len;
 	if (fmt != CMIT_FMT_ONELINE)
-- 
1.6.5.18.g9f87a.dirty

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 2/5] reflog-walk: refactor the branch@{num} formatting
  2009-10-15 22:41         ` [PATCH v2 0/5] Pretty formats for reflog data Thomas Rast
  2009-10-15 22:41           ` [PATCH v2 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
@ 2009-10-15 22:41           ` Thomas Rast
  2009-10-15 22:41           ` [PATCH v2 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
                             ` (3 subsequent siblings)
  5 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-15 22:41 UTC (permalink / raw)
  To: Jeff King, Junio C Hamano; +Cc: Jef Driesen, Nanako Shiraishi, git

We'll use the same output in an upcoming commit, so refactor its
formatting (which was duplicated anyway) into a separate function.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 reflog-walk.c |   54 ++++++++++++++++++++++++++++++++----------------------
 1 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/reflog-walk.c b/reflog-walk.c
index 5623ea6..596bafe 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -241,36 +241,46 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
 	commit->object.flags &= ~(ADDED | SEEN | SHOWN);
 }
 
-void show_reflog_message(struct reflog_walk_info *info, int oneline,
+void get_reflog_selector(struct strbuf *sb,
+			 struct reflog_walk_info *reflog_info,
+			 enum date_mode dmode)
+{
+	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+	struct reflog_info *info;
+
+	if (!commit_reflog)
+		return;
+
+	strbuf_addf(sb, "%s@{", commit_reflog->reflogs->ref);
+	if (commit_reflog->flag || dmode) {
+		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+		strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));
+	} else {
+		strbuf_addf(sb, "%d", commit_reflog->reflogs->nr
+			    - 2 - commit_reflog->recno);
+	}
+
+	strbuf_addch(sb, '}');
+}
+
+void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 	enum date_mode dmode)
 {
-	if (info && info->last_commit_reflog) {
-		struct commit_reflog *commit_reflog = info->last_commit_reflog;
+	if (reflog_info && reflog_info->last_commit_reflog) {
+		struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
 		struct reflog_info *info;
+		struct strbuf selector = STRBUF_INIT;
 
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+		get_reflog_selector(&selector, reflog_info, dmode);
 		if (oneline) {
-			printf("%s@{", commit_reflog->reflogs->ref);
-			if (commit_reflog->flag || dmode)
-				printf("%s", show_date(info->timestamp,
-						       info->tz,
-						       dmode));
-			else
-				printf("%d", commit_reflog->reflogs->nr
-				       - 2 - commit_reflog->recno);
-			printf("}: %s", info->message);
+			printf("%s: %s", selector.buf, info->message);
 		}
 		else {
-			printf("Reflog: %s@{", commit_reflog->reflogs->ref);
-			if (commit_reflog->flag || dmode)
-				printf("%s", show_date(info->timestamp,
-							info->tz,
-							dmode));
-			else
-				printf("%d", commit_reflog->reflogs->nr
-				       - 2 - commit_reflog->recno);
-			printf("} (%s)\nReflog message: %s",
-			       info->email, info->message);
+			printf("Reflog: %s (%s)\nReflog message: %s",
+			       selector.buf, info->email, info->message);
 		}
+
+		strbuf_release(&selector);
 	}
 }
-- 
1.6.5.18.g9f87a.dirty

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 3/5] Introduce new pretty formats %g[sdD] for reflog information
  2009-10-15 22:41         ` [PATCH v2 0/5] Pretty formats for reflog data Thomas Rast
  2009-10-15 22:41           ` [PATCH v2 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
  2009-10-15 22:41           ` [PATCH v2 2/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
@ 2009-10-15 22:41           ` Thomas Rast
  2009-10-16  5:32             ` Jeff King
  2009-10-15 22:41           ` [PATCH v2 4/5] stash list: use new %g formats instead of sed Thomas Rast
                             ` (2 subsequent siblings)
  5 siblings, 1 reply; 49+ messages in thread
From: Thomas Rast @ 2009-10-15 22:41 UTC (permalink / raw)
  To: Jeff King, Junio C Hamano; +Cc: Jef Driesen, Nanako Shiraishi, git

Add three new --pretty=format escapes:

  %gD  long  reflog descriptor (e.g. refs/stash@{0})
  %gd  short reflog descriptor (e.g. stash@{0})
  %gs  reflog message

This is achieved by passing down the reflog info, if any, inside the
pretty_print_context struct.

We use the newly refactored get_reflog_selector(), and give it some
extra functionality to extract a shortened ref.  The shortening has a
very simple 1-element cache, since it will usually be called with the
same ref every time.  Add another helper get_reflog_message() for the
message extraction.

Note that the --format="%h %gD: %gs" tests may not work in real
repositories, as the --pretty formatter doesn't know to leave away the
": " on the last commit in an incomplete (because git-gc removed the
old part) reflog.  This equivalence is nevertheless the main goal of
this patch.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/pretty-formats.txt |    3 +++
 commit.h                         |    1 +
 log-tree.c                       |    1 +
 pretty.c                         |   17 +++++++++++++++++
 reflog-walk.c                    |   37 ++++++++++++++++++++++++++++++++++---
 reflog-walk.h                    |    8 ++++++++
 t/t1411-reflog-show.sh           |   12 ++++++++++++
 7 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 2a845b1..6359272 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -123,6 +123,9 @@ The placeholders are:
 - '%s': subject
 - '%f': sanitized subject line, suitable for a filename
 - '%b': body
+- '%gD': reflog selector, e.g., `refs/stash@{1}`
+- '%gd': shortened reflog selector, e.g., `stash@{1}`
+- '%gs': reflog subject
 - '%Cred': switch color to red
 - '%Cgreen': switch color to green
 - '%Cblue': switch color to blue
diff --git a/commit.h b/commit.h
index 011766d..15cb649 100644
--- a/commit.h
+++ b/commit.h
@@ -70,6 +70,7 @@ struct pretty_print_context
 	const char *after_subject;
 	enum date_mode date_mode;
 	int need_8bit_cte;
+	struct reflog_walk_info *reflog_info;
 };
 
 extern int non_ascii(int);
diff --git a/log-tree.c b/log-tree.c
index f57487f..8e782fc 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -409,6 +409,7 @@ void show_log(struct rev_info *opt)
 	ctx.date_mode = opt->date_mode;
 	ctx.abbrev = opt->diffopt.abbrev;
 	ctx.after_subject = extra_headers;
+	ctx.reflog_info = opt->reflog_info;
 	pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);
 
 	if (opt->add_signoff)
diff --git a/pretty.c b/pretty.c
index d6d57eb..fc65fca 100644
--- a/pretty.c
+++ b/pretty.c
@@ -7,6 +7,7 @@
 #include "mailmap.h"
 #include "log-tree.h"
 #include "color.h"
+#include "reflog-walk.h"
 
 static char *user_format;
 
@@ -701,6 +702,22 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 	case 'd':
 		format_decoration(sb, commit);
 		return 1;
+	case 'g':		/* reflog info */
+		switch(placeholder[1]) {
+		case 'd':	/* reflog selector */
+		case 'D':
+			if (c->pretty_ctx->reflog_info)
+				get_reflog_selector(sb,
+						    c->pretty_ctx->reflog_info,
+						    c->pretty_ctx->date_mode,
+						    (placeholder[1] == 'd'));
+			return 2;
+		case 's':	/* reflog message */
+			if (c->pretty_ctx->reflog_info)
+				get_reflog_message(sb, c->pretty_ctx->reflog_info);
+			return 2;
+		}
+		return 0;	/* unknown %g placeholder */
 	}
 
 	/* For the rest we have to parse the commit header. */
diff --git a/reflog-walk.c b/reflog-walk.c
index 596bafe..6c6867b 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -243,15 +243,29 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
 
 void get_reflog_selector(struct strbuf *sb,
 			 struct reflog_walk_info *reflog_info,
-			 enum date_mode dmode)
+			 enum date_mode dmode,
+			 int shorten)
 {
 	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
 	struct reflog_info *info;
+	static const char *last_ref = NULL;
+	static char *last_short_ref = NULL;
+	const char *printed_ref;
 
 	if (!commit_reflog)
 		return;
 
-	strbuf_addf(sb, "%s@{", commit_reflog->reflogs->ref);
+	if (shorten) {
+		if (last_ref != commit_reflog->reflogs->ref) {
+			free(last_short_ref);
+			last_short_ref = shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);
+		}
+		printed_ref = last_short_ref;
+	} else {
+		printed_ref = commit_reflog->reflogs->ref;
+	}
+
+	strbuf_addf(sb, "%s@{", printed_ref);
 	if (commit_reflog->flag || dmode) {
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
 		strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));
@@ -263,6 +277,23 @@ void get_reflog_selector(struct strbuf *sb,
 	strbuf_addch(sb, '}');
 }
 
+void get_reflog_message(struct strbuf *sb,
+			struct reflog_walk_info *reflog_info)
+{
+	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+	struct reflog_info *info;
+	size_t len;
+
+	if (!commit_reflog)
+		return;
+
+	info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+	len = strlen(info->message);
+	if (len > 0)
+		len--; /* strip away trailing newline */
+	strbuf_add(sb, info->message, len);
+}
+
 void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 	enum date_mode dmode)
 {
@@ -272,7 +303,7 @@ void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 		struct strbuf selector = STRBUF_INIT;
 
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
-		get_reflog_selector(&selector, reflog_info, dmode);
+		get_reflog_selector(&selector, reflog_info, dmode, 0);
 		if (oneline) {
 			printf("%s: %s", selector.buf, info->message);
 		}
diff --git a/reflog-walk.h b/reflog-walk.h
index 74c9096..7bd2cd4 100644
--- a/reflog-walk.h
+++ b/reflog-walk.h
@@ -3,6 +3,8 @@
 
 #include "cache.h"
 
+struct reflog_walk_info;
+
 extern void init_reflog_walk(struct reflog_walk_info** info);
 extern int add_reflog_for_walk(struct reflog_walk_info *info,
 		struct commit *commit, const char *name);
@@ -10,5 +12,11 @@ extern void fake_reflog_parent(struct reflog_walk_info *info,
 		struct commit *commit);
 extern void show_reflog_message(struct reflog_walk_info *info, int,
 		enum date_mode);
+extern void get_reflog_message(struct strbuf *sb,
+		struct reflog_walk_info *reflog_info);
+extern void get_reflog_selector(struct strbuf *sb,
+		struct reflog_walk_info *reflog_info,
+		enum date_mode dmode,
+		int shorten);
 
 #endif
diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh
index c18ed8e..cb8d0fd 100755
--- a/t/t1411-reflog-show.sh
+++ b/t/t1411-reflog-show.sh
@@ -64,4 +64,16 @@ test_expect_success 'using --date= shows reflog date (oneline)' '
 	test_cmp expect actual
 '
 
+test_expect_success '--format="%h %gD: %gs" is same as git-reflog' '
+	git reflog >expect &&
+	git log -g --format="%h %gD: %gs" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '--format="%h %gD: %gs" is same as git-reflog (with date)' '
+	git reflog --date=raw >expect &&
+	git log -g --format="%h %gD: %gs" --date=raw >actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
1.6.5.18.g9f87a.dirty

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 4/5] stash list: use new %g formats instead of sed
  2009-10-15 22:41         ` [PATCH v2 0/5] Pretty formats for reflog data Thomas Rast
                             ` (2 preceding siblings ...)
  2009-10-15 22:41           ` [PATCH v2 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
@ 2009-10-15 22:41           ` Thomas Rast
  2009-10-15 22:41           ` [PATCH v2 5/5] stash list: drop the default limit of 10 stashes Thomas Rast
  2009-10-16  5:20           ` [PATCH v2 0/5] Pretty formats for reflog data Jeff King
  5 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-15 22:41 UTC (permalink / raw)
  To: Jeff King, Junio C Hamano; +Cc: Jef Driesen, Nanako Shiraishi, git

With the new formats, we can rewrite 'git stash list' in terms of an
appropriate pretty format, instead of hand-editing with sed.  This has
the advantage that it obeys the normal settings for git-log, notably
the pager.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-stash.sh |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index 4febbbf..f8847c1 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -205,8 +205,7 @@ have_stash () {
 
 list_stash () {
 	have_stash || return 0
-	git log --no-color --pretty=oneline -g "$@" $ref_stash -- |
-	sed -n -e 's/^[.0-9a-f]* refs\///p'
+	git log --format="%gd: %gs" -g "$@" $ref_stash --
 }
 
 show_stash () {
-- 
1.6.5.18.g9f87a.dirty

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 5/5] stash list: drop the default limit of 10 stashes
  2009-10-15 22:41         ` [PATCH v2 0/5] Pretty formats for reflog data Thomas Rast
                             ` (3 preceding siblings ...)
  2009-10-15 22:41           ` [PATCH v2 4/5] stash list: use new %g formats instead of sed Thomas Rast
@ 2009-10-15 22:41           ` Thomas Rast
  2009-10-16  5:20           ` [PATCH v2 0/5] Pretty formats for reflog data Jeff King
  5 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-15 22:41 UTC (permalink / raw)
  To: Jeff King, Junio C Hamano; +Cc: Jef Driesen, Nanako Shiraishi, git

'git stash list' had an undocumented limit of 10 stashes, unless other
git-log arguments were specified.  This surprised at least one user,
but possibly served to cut the output below a screenful without using
a pager.

Since the last commit, 'git stash list' will fire up a pager according
to the same rules as the 'git log' it calls, so we can drop the limit.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-stash.sh |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index f8847c1..f796c2f 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -382,11 +382,6 @@ test -n "$seen_non_option" || set "save" "$@"
 case "$1" in
 list)
 	shift
-	if test $# = 0
-	then
-		set x -n 10
-		shift
-	fi
 	list_stash "$@"
 	;;
 show)
-- 
1.6.5.18.g9f87a.dirty

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 0/5] Pretty formats for reflog data
  2009-10-15 22:41         ` [PATCH v2 0/5] Pretty formats for reflog data Thomas Rast
                             ` (4 preceding siblings ...)
  2009-10-15 22:41           ` [PATCH v2 5/5] stash list: drop the default limit of 10 stashes Thomas Rast
@ 2009-10-16  5:20           ` Jeff King
  2009-10-16  9:00             ` Jakub Narebski
  5 siblings, 1 reply; 49+ messages in thread
From: Jeff King @ 2009-10-16  5:20 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

On Fri, Oct 16, 2009 at 12:41:43AM +0200, Thomas Rast wrote:

> Jeff King wrote:
> > Maybe a better solution would be a "short name" variant for pretty
> > format specifiers. We already have %(refname) and %(refname:short) [...]
> > The tricky part would be deciding on a syntax. This seems to come up a
> > fair bit.
> 
> Ok, I settled for %g[dDs] for now to save on letters.  I'm saving the
> syntax question for a later series while we discuss this one ;-)

:) That is probably sensible. Your %g[dD] doesn't support selecting
between the numbered version and the "date" version, which is something
we might want, but certainly it is no worse than the status quo (and
doing something like that probably _would_ want an extended syntax, as
you now have two orthogonal arguments: shorten and date/numbered).

> I think going for %(...) wouldn't be too bad since we already have
> that in for-each-ref, and it can be backwards compatible.  So we would
> have different sets of short and long specifiers, e.g.
> 
>   %ae = %(authoremail)
>   %aE = %(authoremail:mailmap)
> 
> We can then pass arguments via some yet-to-be decided syntax, say,
> %(body:indent(10)).

That seems reasonable to me, though if we can limit ourselves to one
argument per specifier (I suspect most specifiers would simply be
boolean, but a few may take numbers or strings), then something like
%(body:indent=10) might be a little more readable.

It would also be nice to have some sort of conditional inclusion, which
could deal with your extra ": " in patch 3. Either something like:

  %(reflog:short)%(reflog:+: )

or even

  %(reflog:short:prefix=\: )

and note that allowing arbitrary arguments means we get to deal with
quoting.

But that is all for another potential series.

> Other changes in this version include:
> 
> * I followed your struct suggestion, which is the new 1/5.

Thanks. It looks like it didn't turn out to be too invasive, and I think
some of the callsites are a bit more readable.

> * I fixed the warning that Junio found (and finally found the right
>   combination of -W flags, though I cannot compile with -Werror myself
>   because of *other* warnings...)

I always compile with -Wall -Werror (including testing your series);
what warnings are you getting?

> Thomas Rast (5):
>   Refactor pretty_print_commit arguments into a struct
>   reflog-walk: refactor the branch@{num} formatting
>   Introduce new pretty formats %g[sdD] for reflog information
>   stash list: use new %g formats instead of sed
>   stash list: drop the default limit of 10 stashes

Thanks, this series looks really good to me. I have a few comments on
patch 3 which I'll send separately.

-Peff

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 3/5] Introduce new pretty formats %g[sdD] for reflog information
  2009-10-15 22:41           ` [PATCH v2 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
@ 2009-10-16  5:32             ` Jeff King
  2009-10-16  8:50               ` Thomas Rast
  2009-10-16 14:20               ` [PATCH v3 0/5] Pretty formats for reflog data Thomas Rast
  0 siblings, 2 replies; 49+ messages in thread
From: Jeff King @ 2009-10-16  5:32 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

On Fri, Oct 16, 2009 at 12:41:46AM +0200, Thomas Rast wrote:

> Note that the --format="%h %gD: %gs" tests may not work in real
> repositories, as the --pretty formatter doesn't know to leave away the
> ": " on the last commit in an incomplete (because git-gc removed the
> old part) reflog.  This equivalence is nevertheless the main goal of
> this patch.

Yeah, I see what you are talking about in my git.git repo. I am tempted
to suggest cutting it out of both formats, as it is somewhat confusing,
but it does actually convey a slight bit of information (even if
information that is extremely unlikely to be of use).

I am also fine with leaving it, and if we one day invent the
"conditionally include the ': '" syntax, using it then.

> diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
> index 2a845b1..6359272 100644
> --- a/Documentation/pretty-formats.txt
> +++ b/Documentation/pretty-formats.txt
> @@ -123,6 +123,9 @@ The placeholders are:
>  - '%s': subject
>  - '%f': sanitized subject line, suitable for a filename
>  - '%b': body
> +- '%gD': reflog selector, e.g., `refs/stash@{1}`
> +- '%gd': shortened reflog selector, e.g., `stash@{1}`
> +- '%gs': reflog subject
>  - '%Cred': switch color to red
>  - '%Cgreen': switch color to green
>  - '%Cblue': switch color to blue

Should we give a note that these do nothing if "-g" was not given?

> +	if (shorten) {
> +		if (last_ref != commit_reflog->reflogs->ref) {
> +			free(last_short_ref);
> +			last_short_ref = shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);
> +		}
> +		printed_ref = last_short_ref;

Clever. I hadn't considered caching, but you are right that
shorten_unambiguous_ref is a bit heavyweight to be calling for every
entry.

> diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh
> index c18ed8e..cb8d0fd 100755
> --- a/t/t1411-reflog-show.sh
> +++ b/t/t1411-reflog-show.sh
> @@ -64,4 +64,16 @@ test_expect_success 'using --date= shows reflog date (oneline)' '
>  	test_cmp expect actual
>  '
>  
> +test_expect_success '--format="%h %gD: %gs" is same as git-reflog' '
> +	git reflog >expect &&
> +	git log -g --format="%h %gD: %gs" >actual &&
> +	test_cmp expect actual
> +'
> +
> +test_expect_success '--format="%h %gD: %gs" is same as git-reflog (with date)' '
> +	git reflog --date=raw >expect &&
> +	git log -g --format="%h %gD: %gs" --date=raw >actual &&
> +	test_cmp expect actual
> +'

A test for '%gd' would be nice. A squashable one is below. I am tempted
to test all three forms in t6006, since the intent of that script is to
test all format specifiers. However, those tests would be somewhat
redundant with your t1411 tests.

---
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index 59d1f62..d1f2476 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -162,4 +162,10 @@ test_expect_success 'empty email' '
 	}
 '
 
+test_expect_success '%gd shortens ref name' '
+	echo "master@{0}" >expect.gd-short &&
+	git log -g -1 --format=%gd refs/heads/master >actual.gd-short &&
+	test_cmp expect.gd-short actual.gd-short
+'
+
 test_done

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 3/5] Introduce new pretty formats %g[sdD] for reflog information
  2009-10-16  5:32             ` Jeff King
@ 2009-10-16  8:50               ` Thomas Rast
  2009-10-16 14:20               ` [PATCH v3 0/5] Pretty formats for reflog data Thomas Rast
  1 sibling, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-16  8:50 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

Jeff King wrote:
> > +	if (shorten) {
> > +		if (last_ref != commit_reflog->reflogs->ref) {
> > +			free(last_short_ref);
> > +			last_short_ref = shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);
> > +		}
> > +		printed_ref = last_short_ref;
> 
> Clever. I hadn't considered caching, but you are right that
> shorten_unambiguous_ref is a bit heavyweight to be calling for every
> entry.

I had a slightly better idea today: We can just put an extra member
into the complete_reflogs struct, i.e., a short_ref to go along with
the ref.  It'll take a bit of auditing to verify that all allocations
are zeroed, but since the struct is local to the file that shouldn't
be so hard.

> A test for '%gd' would be nice. A squashable one is below. I am tempted
> to test all three forms in t6006, since the intent of that script is to
> test all format specifiers. However, those tests would be somewhat
> redundant with your t1411 tests.

Ah, yeah, I looked for "reflog" instead of something about pretty, so
I ended up with t1411.  t6006 is a better fit.  Thanks for the extra
test!

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 0/5] Pretty formats for reflog data
  2009-10-16  5:20           ` [PATCH v2 0/5] Pretty formats for reflog data Jeff King
@ 2009-10-16  9:00             ` Jakub Narebski
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Narebski @ 2009-10-16  9:00 UTC (permalink / raw)
  To: Jeff King; +Cc: Thomas Rast, Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

Jeff King <peff@peff.net> writes:

> On Fri, Oct 16, 2009 at 12:41:43AM +0200, Thomas Rast wrote:

> > I think going for %(...) wouldn't be too bad since we already have
> > that in for-each-ref, and it can be backwards compatible.  So we would
> > have different sets of short and long specifiers, e.g.
> > 
> >   %ae = %(authoremail)
> >   %aE = %(authoremail:mailmap)
> > 
> > We can then pass arguments via some yet-to-be decided syntax, say,
> > %(body:indent(10)).
> 
> That seems reasonable to me, though if we can limit ourselves to one
> argument per specifier (I suspect most specifiers would simply be
> boolean, but a few may take numbers or strings), then something like
> %(body:indent=10) might be a little more readable.
> 
> It would also be nice to have some sort of conditional inclusion, which
> could deal with your extra ": " in patch 3. Either something like:
> 
>   %(reflog:short)%(reflog:+: )
> 
> or even
> 
>   %(reflog:short:prefix=\: )
> 
> and note that allowing arbitrary arguments means we get to deal with
> quoting.
> 
> But that is all for another potential series.

Or we could go the whole nine miles, and implement some subset of
advanced shell syntax, 

  %(parameter:-word)
  %(parameter:=word)
  %(parameter:?word)
  %(parameter:+word)

RPM spec syntax, 

  %(?parameter)      # expand if exists
  %(!?parameter)     # expand if does not exists
  %(?parameter:literal)
  %(!?parameter:literal)

or RPM queryformat

  %10(parameter)
  %-30(parameter)

  [    %(messagebody)\n]   # messagebody is list of lines
  [%(=param) %(list)\n]    # param is not a list; repeat it

  %|parameter?{present}:{missing}|

  %(parameter:date)
  %(parameter:shescape)

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 0/5] Pretty formats for reflog data
  2009-10-16  5:32             ` Jeff King
  2009-10-16  8:50               ` Thomas Rast
@ 2009-10-16 14:20               ` Thomas Rast
  2009-10-16 14:20                 ` [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
                                   ` (6 more replies)
  1 sibling, 7 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-16 14:20 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

Next round :-)

I only changed 3/5, as per your comments:

Jeff King wrote:
> On Fri, Oct 16, 2009 at 12:41:46AM +0200, Thomas Rast wrote:
> > +- '%gD': reflog selector, e.g., `refs/stash@{1}`
> > +- '%gd': shortened reflog selector, e.g., `stash@{1}`
> > +- '%gs': reflog subject
> 
> Should we give a note that these do nothing if "-g" was not given?

I tried for some time, but all attempts at interrupting the lists
ended up terminating it again, so that the %g family list would not
line up with the rest of the parameters.  Having the note there would
be nice, but I think keeping the list together optically is more
important.  However, AFAICS it really is the first character that only
works with certain options (%m makes little sense without A...B, but
still expands to >).

Looking at it did make me notice that @{1} is invalid asciidoc and
needs to be spelled @\{1\} though :-)

> A test for '%gd' would be nice. A squashable one is below. I am tempted
> to test all three forms in t6006, since the intent of that script is to
> test all format specifiers. However, those tests would be somewhat
> redundant with your t1411 tests.

I added yours and moved my tests to t6006 too, as indicated in the
other mail.

I also changed the caching, as outlined earlier:

I wrote:
> I had a slightly better idea today: We can just put an extra member
> into the complete_reflogs struct, i.e., a short_ref to go along with
> the ref.  It'll take a bit of auditing to verify that all allocations
> are zeroed, but since the struct is local to the file that shouldn't
> be so hard.

There's in fact only a single allocation (with xcalloc).


Thomas Rast (5):
  Refactor pretty_print_commit arguments into a struct
  reflog-walk: refactor the branch@{num} formatting
  Introduce new pretty formats %g[sdD] for reflog information
  stash list: use new %g formats instead of sed
  stash list: drop the default limit of 10 stashes

 Documentation/pretty-formats.txt |    3 +
 builtin-branch.c                 |    3 +-
 builtin-checkout.c               |    3 +-
 builtin-log.c                    |    3 +-
 builtin-merge.c                  |    7 ++-
 builtin-rev-list.c               |    7 ++-
 builtin-shortlog.c               |    9 +++-
 builtin-show-branch.c            |    4 +-
 commit.h                         |   20 ++++++---
 git-stash.sh                     |    8 +---
 log-tree.c                       |   21 +++++-----
 pretty.c                         |   44 ++++++++++++++------
 reflog-walk.c                    |   83 ++++++++++++++++++++++++++++----------
 reflog-walk.h                    |    8 ++++
 t/t6006-rev-list-format.sh       |   18 ++++++++
 15 files changed, 170 insertions(+), 71 deletions(-)

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct
  2009-10-16 14:20               ` [PATCH v3 0/5] Pretty formats for reflog data Thomas Rast
@ 2009-10-16 14:20                 ` Thomas Rast
  2009-10-17 17:05                   ` Junio C Hamano
  2009-10-16 14:20                 ` [PATCH v3 2/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
                                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 49+ messages in thread
From: Thomas Rast @ 2009-10-16 14:20 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

pretty_print_commit() has a bunch of rarely-used arguments, and
introducing more of them requires yet another update of all the call
sites.  Refactor most of them into a struct to make future extensions
easier.

The ones that stay "plain" arguments were chosen on the grounds that
all callers put real arguments there, whereas some callers have 0/NULL
for all arguments that were factored into the struct.

We declare the struct 'const' to ensure none of the callers are bitten
by the changed (no longer call-by-value) semantics.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 builtin-branch.c      |    3 ++-
 builtin-checkout.c    |    3 ++-
 builtin-log.c         |    3 ++-
 builtin-merge.c       |    7 +++++--
 builtin-rev-list.c    |    7 ++++---
 builtin-shortlog.c    |    9 ++++++---
 builtin-show-branch.c |    4 ++--
 commit.h              |   19 +++++++++++++------
 log-tree.c            |   20 ++++++++++----------
 pretty.c              |   27 ++++++++++++++-------------
 10 files changed, 60 insertions(+), 42 deletions(-)

diff --git a/builtin-branch.c b/builtin-branch.c
index 9f57992..05e876e 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -387,8 +387,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 
 		commit = item->commit;
 		if (commit && !parse_commit(commit)) {
+			struct pretty_print_context ctx = {0};
 			pretty_print_commit(CMIT_FMT_ONELINE, commit,
-					    &subject, 0, NULL, NULL, 0, 0);
+					    &subject, &ctx);
 			sub = subject.buf;
 		}
 
diff --git a/builtin-checkout.c b/builtin-checkout.c
index d050c37..075a49f 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -302,8 +302,9 @@ static void show_local_changes(struct object *head)
 static void describe_detached_head(char *msg, struct commit *commit)
 {
 	struct strbuf sb = STRBUF_INIT;
+	struct pretty_print_context ctx = {0};
 	parse_commit(commit);
-	pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);
+	pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx);
 	fprintf(stderr, "%s %s... %s\n", msg,
 		find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
 	strbuf_release(&sb);
diff --git a/builtin-log.c b/builtin-log.c
index 25e21ed..207a361 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -1304,8 +1304,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
 
 		if (verbose) {
 			struct strbuf buf = STRBUF_INIT;
+			struct pretty_print_context ctx = {0};
 			pretty_print_commit(CMIT_FMT_ONELINE, commit,
-			                    &buf, 0, NULL, NULL, 0, 0);
+					    &buf, &ctx);
 			printf("%c %s %s\n", sign,
 			       sha1_to_hex(commit->object.sha1), buf.buf);
 			strbuf_release(&buf);
diff --git a/builtin-merge.c b/builtin-merge.c
index b6b8428..c69a305 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -264,6 +264,7 @@ static void squash_message(void)
 	struct strbuf out = STRBUF_INIT;
 	struct commit_list *j;
 	int fd;
+	struct pretty_print_context ctx = {0};
 
 	printf("Squash commit -- not updating HEAD\n");
 	fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
@@ -285,13 +286,15 @@ static void squash_message(void)
 	if (prepare_revision_walk(&rev))
 		die("revision walk setup failed");
 
+	ctx.abbrev = rev.abbrev;
+	ctx.date_mode = rev.date_mode;
+
 	strbuf_addstr(&out, "Squashed commit of the following:\n");
 	while ((commit = get_revision(&rev)) != NULL) {
 		strbuf_addch(&out, '\n');
 		strbuf_addf(&out, "commit %s\n",
 			sha1_to_hex(commit->object.sha1));
-		pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,
-			NULL, NULL, rev.date_mode, 0);
+		pretty_print_commit(rev.commit_format, commit, &out, &ctx);
 	}
 	if (write(fd, out.buf, out.len) < 0)
 		die_errno("Writing SQUASH_MSG");
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 4ba1c12..42cc8d8 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -96,9 +96,10 @@ static void show_commit(struct commit *commit, void *data)
 
 	if (revs->verbose_header && commit->buffer) {
 		struct strbuf buf = STRBUF_INIT;
-		pretty_print_commit(revs->commit_format, commit,
-				    &buf, revs->abbrev, NULL, NULL,
-				    revs->date_mode, 0);
+		struct pretty_print_context ctx = {0};
+		ctx.abbrev = revs->abbrev;
+		ctx.date_mode = revs->date_mode;
+		pretty_print_commit(revs->commit_format, commit, &buf, &ctx);
 		if (revs->graph) {
 			if (buf.len) {
 				if (revs->commit_format != CMIT_FMT_ONELINE)
diff --git a/builtin-shortlog.c b/builtin-shortlog.c
index 4d4a3c8..8aa63c7 100644
--- a/builtin-shortlog.c
+++ b/builtin-shortlog.c
@@ -158,9 +158,12 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
 		    sha1_to_hex(commit->object.sha1));
 	if (log->user_format) {
 		struct strbuf buf = STRBUF_INIT;
-
-		pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf,
-			DEFAULT_ABBREV, "", "", DATE_NORMAL, 0);
+		struct pretty_print_context ctx = {0};
+		ctx.abbrev = DEFAULT_ABBREV;
+		ctx.subject = "";
+		ctx.after_subject = "";
+		ctx.date_mode = DATE_NORMAL;
+		pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf, &ctx);
 		insert_one_record(log, author, buf.buf);
 		strbuf_release(&buf);
 		return;
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index be95930..9f13caa 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -293,8 +293,8 @@ static void show_one_commit(struct commit *commit, int no_name)
 	struct commit_name *name = commit->util;
 
 	if (commit->object.parsed) {
-		pretty_print_commit(CMIT_FMT_ONELINE, commit,
-				    &pretty, 0, NULL, NULL, 0, 0);
+		struct pretty_print_context ctx = {0};
+		pretty_print_commit(CMIT_FMT_ONELINE, commit, &pretty, &ctx);
 		pretty_str = pretty.buf;
 	}
 	if (!prefixcmp(pretty_str, "[PATCH] "))
diff --git a/commit.h b/commit.h
index f4fc5c5..011766d 100644
--- a/commit.h
+++ b/commit.h
@@ -63,6 +63,15 @@ enum cmit_fmt {
 	CMIT_FMT_UNSPECIFIED,
 };
 
+struct pretty_print_context
+{
+	int abbrev;
+	const char *subject;
+	const char *after_subject;
+	enum date_mode date_mode;
+	int need_8bit_cte;
+};
+
 extern int non_ascii(int);
 extern int has_non_ascii(const char *text);
 struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
@@ -71,12 +80,10 @@ enum cmit_fmt {
 extern void get_commit_format(const char *arg, struct rev_info *);
 extern void format_commit_message(const struct commit *commit,
 				  const void *format, struct strbuf *sb,
-				  enum date_mode dmode);
-extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,
-                                struct strbuf *,
-                                int abbrev, const char *subject,
-                                const char *after_subject, enum date_mode,
-				int need_8bit_cte);
+				  const struct pretty_print_context *context);
+extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
+				struct strbuf *sb,
+				const struct pretty_print_context *context);
 void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
 		   const char *line, enum date_mode dmode,
 		   const char *encoding);
diff --git a/log-tree.c b/log-tree.c
index f7d54f2..f57487f 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -277,10 +277,9 @@ void show_log(struct rev_info *opt)
 	struct strbuf msgbuf = STRBUF_INIT;
 	struct log_info *log = opt->loginfo;
 	struct commit *commit = log->commit, *parent = log->parent;
-	int abbrev = opt->diffopt.abbrev;
 	int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;
-	const char *subject = NULL, *extra_headers = opt->extra_headers;
-	int need_8bit_cte = 0;
+	const char *extra_headers = opt->extra_headers;
+	struct pretty_print_context ctx = {0};
 
 	opt->loginfo = NULL;
 	if (!opt->verbose_header) {
@@ -347,8 +346,8 @@ void show_log(struct rev_info *opt)
 	 */
 
 	if (opt->commit_format == CMIT_FMT_EMAIL) {
-		log_write_email_headers(opt, commit, &subject, &extra_headers,
-					&need_8bit_cte);
+		log_write_email_headers(opt, commit, &ctx.subject, &extra_headers,
+					&ctx.need_8bit_cte);
 	} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
 		fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
 		if (opt->commit_format != CMIT_FMT_ONELINE)
@@ -405,11 +404,12 @@ void show_log(struct rev_info *opt)
 	/*
 	 * And then the pretty-printed message itself
 	 */
-	if (need_8bit_cte >= 0)
-		need_8bit_cte = has_non_ascii(opt->add_signoff);
-	pretty_print_commit(opt->commit_format, commit, &msgbuf,
-			    abbrev, subject, extra_headers, opt->date_mode,
-			    need_8bit_cte);
+	if (ctx.need_8bit_cte >= 0)
+		ctx.need_8bit_cte = has_non_ascii(opt->add_signoff);
+	ctx.date_mode = opt->date_mode;
+	ctx.abbrev = opt->diffopt.abbrev;
+	ctx.after_subject = extra_headers;
+	pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);
 
 	if (opt->add_signoff)
 		append_signoff(&msgbuf, opt->add_signoff);
diff --git a/pretty.c b/pretty.c
index f5983f8..d6d57eb 100644
--- a/pretty.c
+++ b/pretty.c
@@ -442,7 +442,7 @@ struct chunk {
 
 struct format_commit_context {
 	const struct commit *commit;
-	enum date_mode dmode;
+	const struct pretty_print_context *pretty_ctx;
 	unsigned commit_header_parsed:1;
 	unsigned commit_message_parsed:1;
 
@@ -711,11 +711,11 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 	case 'a':	/* author ... */
 		return format_person_part(sb, placeholder[1],
 				   msg + c->author.off, c->author.len,
-				   c->dmode);
+				   c->pretty_ctx->date_mode);
 	case 'c':	/* committer ... */
 		return format_person_part(sb, placeholder[1],
 				   msg + c->committer.off, c->committer.len,
-				   c->dmode);
+				   c->pretty_ctx->date_mode);
 	case 'e':	/* encoding */
 		strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
 		return 1;
@@ -741,13 +741,13 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 
 void format_commit_message(const struct commit *commit,
 			   const void *format, struct strbuf *sb,
-			   enum date_mode dmode)
+			   const struct pretty_print_context *pretty_ctx)
 {
 	struct format_commit_context context;
 
 	memset(&context, 0, sizeof(context));
 	context.commit = commit;
-	context.dmode = dmode;
+	context.pretty_ctx = pretty_ctx;
 	strbuf_expand(sb, format, format_commit_item, &context);
 }
 
@@ -900,18 +900,18 @@ void pp_remainder(enum cmit_fmt fmt,
 }
 
 void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
-			 struct strbuf *sb, int abbrev,
-			 const char *subject, const char *after_subject,
-			 enum date_mode dmode, int need_8bit_cte)
+			 struct strbuf *sb,
+			 const struct pretty_print_context *context)
 {
 	unsigned long beginning_of_body;
 	int indent = 4;
 	const char *msg = commit->buffer;
 	char *reencoded;
 	const char *encoding;
+	int need_8bit_cte = context->need_8bit_cte;
 
 	if (fmt == CMIT_FMT_USERFORMAT) {
-		format_commit_message(commit, user_format, sb, dmode);
+		format_commit_message(commit, user_format, sb, context);
 		return;
 	}
 
@@ -946,8 +946,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
 		}
 	}
 
-	pp_header(fmt, abbrev, dmode, encoding, commit, &msg, sb);
-	if (fmt != CMIT_FMT_ONELINE && !subject) {
+	pp_header(fmt, context->abbrev, context->date_mode, encoding,
+		  commit, &msg, sb);
+	if (fmt != CMIT_FMT_ONELINE && !context->subject) {
 		strbuf_addch(sb, '\n');
 	}
 
@@ -956,8 +957,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
 
 	/* These formats treat the title line specially. */
 	if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
-		pp_title_line(fmt, &msg, sb, subject,
-			      after_subject, encoding, need_8bit_cte);
+		pp_title_line(fmt, &msg, sb, context->subject,
+			      context->after_subject, encoding, need_8bit_cte);
 
 	beginning_of_body = sb->len;
 	if (fmt != CMIT_FMT_ONELINE)
-- 
1.6.5.116.gfe4b9

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 2/5] reflog-walk: refactor the branch@{num} formatting
  2009-10-16 14:20               ` [PATCH v3 0/5] Pretty formats for reflog data Thomas Rast
  2009-10-16 14:20                 ` [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
@ 2009-10-16 14:20                 ` Thomas Rast
  2009-10-16 14:20                 ` [PATCH v3 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
                                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-16 14:20 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

We'll use the same output in an upcoming commit, so refactor its
formatting (which was duplicated anyway) into a separate function.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 reflog-walk.c |   54 ++++++++++++++++++++++++++++++++----------------------
 1 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/reflog-walk.c b/reflog-walk.c
index 5623ea6..596bafe 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -241,36 +241,46 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
 	commit->object.flags &= ~(ADDED | SEEN | SHOWN);
 }
 
-void show_reflog_message(struct reflog_walk_info *info, int oneline,
+void get_reflog_selector(struct strbuf *sb,
+			 struct reflog_walk_info *reflog_info,
+			 enum date_mode dmode)
+{
+	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+	struct reflog_info *info;
+
+	if (!commit_reflog)
+		return;
+
+	strbuf_addf(sb, "%s@{", commit_reflog->reflogs->ref);
+	if (commit_reflog->flag || dmode) {
+		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+		strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));
+	} else {
+		strbuf_addf(sb, "%d", commit_reflog->reflogs->nr
+			    - 2 - commit_reflog->recno);
+	}
+
+	strbuf_addch(sb, '}');
+}
+
+void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 	enum date_mode dmode)
 {
-	if (info && info->last_commit_reflog) {
-		struct commit_reflog *commit_reflog = info->last_commit_reflog;
+	if (reflog_info && reflog_info->last_commit_reflog) {
+		struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
 		struct reflog_info *info;
+		struct strbuf selector = STRBUF_INIT;
 
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+		get_reflog_selector(&selector, reflog_info, dmode);
 		if (oneline) {
-			printf("%s@{", commit_reflog->reflogs->ref);
-			if (commit_reflog->flag || dmode)
-				printf("%s", show_date(info->timestamp,
-						       info->tz,
-						       dmode));
-			else
-				printf("%d", commit_reflog->reflogs->nr
-				       - 2 - commit_reflog->recno);
-			printf("}: %s", info->message);
+			printf("%s: %s", selector.buf, info->message);
 		}
 		else {
-			printf("Reflog: %s@{", commit_reflog->reflogs->ref);
-			if (commit_reflog->flag || dmode)
-				printf("%s", show_date(info->timestamp,
-							info->tz,
-							dmode));
-			else
-				printf("%d", commit_reflog->reflogs->nr
-				       - 2 - commit_reflog->recno);
-			printf("} (%s)\nReflog message: %s",
-			       info->email, info->message);
+			printf("Reflog: %s (%s)\nReflog message: %s",
+			       selector.buf, info->email, info->message);
 		}
+
+		strbuf_release(&selector);
 	}
 }
-- 
1.6.5.116.gfe4b9

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 3/5] Introduce new pretty formats %g[sdD] for reflog information
  2009-10-16 14:20               ` [PATCH v3 0/5] Pretty formats for reflog data Thomas Rast
  2009-10-16 14:20                 ` [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
  2009-10-16 14:20                 ` [PATCH v3 2/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
@ 2009-10-16 14:20                 ` Thomas Rast
  2009-10-17 14:48                   ` [PATCH v3.1 " Thomas Rast
  2009-10-16 14:20                 ` [PATCH v3 4/5] stash list: use new %g formats instead of sed Thomas Rast
                                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 49+ messages in thread
From: Thomas Rast @ 2009-10-16 14:20 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

Add three new --pretty=format escapes:

  %gD  long  reflog descriptor (e.g. refs/stash@{0})
  %gd  short reflog descriptor (e.g. stash@{0})
  %gs  reflog message

This is achieved by passing down the reflog info, if any, inside the
pretty_print_context struct.

We use the newly refactored get_reflog_selector(), and give it some
extra functionality to extract a shortened ref.  The shortening is
cached inside the commit_reflogs struct; the only allocation of it
happens in read_complete_reflog(), where it is initialised to 0.  Also
add another helper get_reflog_message() for the message extraction.

Note that the --format="%h %gD: %gs" tests may not work in real
repositories, as the --pretty formatter doesn't know to leave away the
": " on the last commit in an incomplete (because git-gc removed the
old part) reflog.  This equivalence is nevertheless the main goal of
this patch.

Thanks to Jeff King for reviews and the %gd testcase.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/pretty-formats.txt |    3 +++
 commit.h                         |    1 +
 log-tree.c                       |    1 +
 pretty.c                         |   17 +++++++++++++++++
 reflog-walk.c                    |   35 ++++++++++++++++++++++++++++++++---
 reflog-walk.h                    |    8 ++++++++
 t/t6006-rev-list-format.sh       |   18 ++++++++++++++++++
 7 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 2a845b1..cc0ea56 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -123,6 +123,9 @@ The placeholders are:
 - '%s': subject
 - '%f': sanitized subject line, suitable for a filename
 - '%b': body
+- '%gD': reflog selector, e.g., `refs/stash@\{1\}`
+- '%gd': shortened reflog selector, e.g., `stash@\{1\}`
+- '%gs': reflog subject
 - '%Cred': switch color to red
 - '%Cgreen': switch color to green
 - '%Cblue': switch color to blue
diff --git a/commit.h b/commit.h
index 011766d..15cb649 100644
--- a/commit.h
+++ b/commit.h
@@ -70,6 +70,7 @@ struct pretty_print_context
 	const char *after_subject;
 	enum date_mode date_mode;
 	int need_8bit_cte;
+	struct reflog_walk_info *reflog_info;
 };
 
 extern int non_ascii(int);
diff --git a/log-tree.c b/log-tree.c
index f57487f..8e782fc 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -409,6 +409,7 @@ void show_log(struct rev_info *opt)
 	ctx.date_mode = opt->date_mode;
 	ctx.abbrev = opt->diffopt.abbrev;
 	ctx.after_subject = extra_headers;
+	ctx.reflog_info = opt->reflog_info;
 	pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);
 
 	if (opt->add_signoff)
diff --git a/pretty.c b/pretty.c
index d6d57eb..fc65fca 100644
--- a/pretty.c
+++ b/pretty.c
@@ -7,6 +7,7 @@
 #include "mailmap.h"
 #include "log-tree.h"
 #include "color.h"
+#include "reflog-walk.h"
 
 static char *user_format;
 
@@ -701,6 +702,22 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 	case 'd':
 		format_decoration(sb, commit);
 		return 1;
+	case 'g':		/* reflog info */
+		switch(placeholder[1]) {
+		case 'd':	/* reflog selector */
+		case 'D':
+			if (c->pretty_ctx->reflog_info)
+				get_reflog_selector(sb,
+						    c->pretty_ctx->reflog_info,
+						    c->pretty_ctx->date_mode,
+						    (placeholder[1] == 'd'));
+			return 2;
+		case 's':	/* reflog message */
+			if (c->pretty_ctx->reflog_info)
+				get_reflog_message(sb, c->pretty_ctx->reflog_info);
+			return 2;
+		}
+		return 0;	/* unknown %g placeholder */
 	}
 
 	/* For the rest we have to parse the commit header. */
diff --git a/reflog-walk.c b/reflog-walk.c
index 596bafe..caba4f7 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -8,6 +8,7 @@
 
 struct complete_reflogs {
 	char *ref;
+	const char *short_ref;
 	struct reflog_info {
 		unsigned char osha1[20], nsha1[20];
 		char *email;
@@ -243,15 +244,26 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
 
 void get_reflog_selector(struct strbuf *sb,
 			 struct reflog_walk_info *reflog_info,
-			 enum date_mode dmode)
+			 enum date_mode dmode,
+			 int shorten)
 {
 	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
 	struct reflog_info *info;
+	const char *printed_ref;
 
 	if (!commit_reflog)
 		return;
 
-	strbuf_addf(sb, "%s@{", commit_reflog->reflogs->ref);
+	if (shorten) {
+		if (!commit_reflog->reflogs->short_ref)
+			commit_reflog->reflogs->short_ref
+				= shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);
+		printed_ref = commit_reflog->reflogs->short_ref;
+	} else {
+		printed_ref = commit_reflog->reflogs->ref;
+	}
+
+	strbuf_addf(sb, "%s@{", printed_ref);
 	if (commit_reflog->flag || dmode) {
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
 		strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));
@@ -263,6 +275,23 @@ void get_reflog_selector(struct strbuf *sb,
 	strbuf_addch(sb, '}');
 }
 
+void get_reflog_message(struct strbuf *sb,
+			struct reflog_walk_info *reflog_info)
+{
+	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+	struct reflog_info *info;
+	size_t len;
+
+	if (!commit_reflog)
+		return;
+
+	info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+	len = strlen(info->message);
+	if (len > 0)
+		len--; /* strip away trailing newline */
+	strbuf_add(sb, info->message, len);
+}
+
 void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 	enum date_mode dmode)
 {
@@ -272,7 +301,7 @@ void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 		struct strbuf selector = STRBUF_INIT;
 
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
-		get_reflog_selector(&selector, reflog_info, dmode);
+		get_reflog_selector(&selector, reflog_info, dmode, 0);
 		if (oneline) {
 			printf("%s: %s", selector.buf, info->message);
 		}
diff --git a/reflog-walk.h b/reflog-walk.h
index 74c9096..7bd2cd4 100644
--- a/reflog-walk.h
+++ b/reflog-walk.h
@@ -3,6 +3,8 @@
 
 #include "cache.h"
 
+struct reflog_walk_info;
+
 extern void init_reflog_walk(struct reflog_walk_info** info);
 extern int add_reflog_for_walk(struct reflog_walk_info *info,
 		struct commit *commit, const char *name);
@@ -10,5 +12,11 @@ extern void fake_reflog_parent(struct reflog_walk_info *info,
 		struct commit *commit);
 extern void show_reflog_message(struct reflog_walk_info *info, int,
 		enum date_mode);
+extern void get_reflog_message(struct strbuf *sb,
+		struct reflog_walk_info *reflog_info);
+extern void get_reflog_selector(struct strbuf *sb,
+		struct reflog_walk_info *reflog_info,
+		enum date_mode dmode,
+		int shorten);
 
 #endif
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index 59d1f62..7f61ab0 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -162,4 +162,22 @@ test_expect_success 'empty email' '
 	}
 '
 
+test_expect_success '"%h %gD: %gs" is same as git-reflog' '
+	git reflog >expect &&
+	git log -g --format="%h %gD: %gs" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '"%h %gD: %gs" is same as git-reflog (with date)' '
+	git reflog --date=raw >expect &&
+	git log -g --format="%h %gD: %gs" --date=raw >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '%gd shortens ref name' '
+	echo "master@{0}" >expect.gd-short &&
+	git log -g -1 --format=%gd refs/heads/master >actual.gd-short &&
+	test_cmp expect.gd-short actual.gd-short
+'
+
 test_done
-- 
1.6.5.116.gfe4b9

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 4/5] stash list: use new %g formats instead of sed
  2009-10-16 14:20               ` [PATCH v3 0/5] Pretty formats for reflog data Thomas Rast
                                   ` (2 preceding siblings ...)
  2009-10-16 14:20                 ` [PATCH v3 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
@ 2009-10-16 14:20                 ` Thomas Rast
  2009-10-16 14:20                 ` [PATCH v3 5/5] stash list: drop the default limit of 10 stashes Thomas Rast
                                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-16 14:20 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

With the new formats, we can rewrite 'git stash list' in terms of an
appropriate pretty format, instead of hand-editing with sed.  This has
the advantage that it obeys the normal settings for git-log, notably
the pager.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-stash.sh |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index 4febbbf..f8847c1 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -205,8 +205,7 @@ have_stash () {
 
 list_stash () {
 	have_stash || return 0
-	git log --no-color --pretty=oneline -g "$@" $ref_stash -- |
-	sed -n -e 's/^[.0-9a-f]* refs\///p'
+	git log --format="%gd: %gs" -g "$@" $ref_stash --
 }
 
 show_stash () {
-- 
1.6.5.116.gfe4b9

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 5/5] stash list: drop the default limit of 10 stashes
  2009-10-16 14:20               ` [PATCH v3 0/5] Pretty formats for reflog data Thomas Rast
                                   ` (3 preceding siblings ...)
  2009-10-16 14:20                 ` [PATCH v3 4/5] stash list: use new %g formats instead of sed Thomas Rast
@ 2009-10-16 14:20                 ` Thomas Rast
  2009-10-17  0:50                 ` [PATCH v3 0/5] Pretty formats for reflog data Junio C Hamano
  2009-10-17  1:18                 ` Jeff King
  6 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-16 14:20 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

'git stash list' had an undocumented limit of 10 stashes, unless other
git-log arguments were specified.  This surprised at least one user,
but possibly served to cut the output below a screenful without using
a pager.

Since the last commit, 'git stash list' will fire up a pager according
to the same rules as the 'git log' it calls, so we can drop the limit.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-stash.sh |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index f8847c1..f796c2f 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -382,11 +382,6 @@ test -n "$seen_non_option" || set "save" "$@"
 case "$1" in
 list)
 	shift
-	if test $# = 0
-	then
-		set x -n 10
-		shift
-	fi
 	list_stash "$@"
 	;;
 show)
-- 
1.6.5.116.gfe4b9

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 0/5] Pretty formats for reflog data
  2009-10-16 14:20               ` [PATCH v3 0/5] Pretty formats for reflog data Thomas Rast
                                   ` (4 preceding siblings ...)
  2009-10-16 14:20                 ` [PATCH v3 5/5] stash list: drop the default limit of 10 stashes Thomas Rast
@ 2009-10-17  0:50                 ` Junio C Hamano
  2009-10-17  1:18                 ` Jeff King
  6 siblings, 0 replies; 49+ messages in thread
From: Junio C Hamano @ 2009-10-17  0:50 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git

Thomas Rast <trast@student.ethz.ch> writes:

> Next round :-)

Very nicely done; I like it.

Thanks.

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 0/5] Pretty formats for reflog data
  2009-10-16 14:20               ` [PATCH v3 0/5] Pretty formats for reflog data Thomas Rast
                                   ` (5 preceding siblings ...)
  2009-10-17  0:50                 ` [PATCH v3 0/5] Pretty formats for reflog data Junio C Hamano
@ 2009-10-17  1:18                 ` Jeff King
  6 siblings, 0 replies; 49+ messages in thread
From: Jeff King @ 2009-10-17  1:18 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

On Fri, Oct 16, 2009 at 04:20:32PM +0200, Thomas Rast wrote:

> I tried for some time, but all attempts at interrupting the lists
> ended up terminating it again, so that the %g family list would not
> line up with the rest of the parameters.  Having the note there would
> be nice, but I think keeping the list together optically is more
> important.  However, AFAICS it really is the first character that only
> works with certain options (%m makes little sense without A...B, but
> still expands to >).

Another example is "%d", but there we load decorations on the fly the
first time it is used. I don't think that's a good idea here, since
using "%gd" shouldn't automatically imply "-g", which drastically
changes the nature of the command.

The "%m" behavior does what I would expect. If you haven't done any
limiting, then there can be no "left" or "boundary" entries.

I am tempted to do a note like the one below, but maybe the behavior is
obvious enough to users that it isn't necessary.

> Looking at it did make me notice that @{1} is invalid asciidoc and
> needs to be spelled @\{1\} though :-)

Thanks. I am often very guilty of not actually building documentation
when reviewing patches, because it is so tedious to build and examine.

---
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 6359272..43192af 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -135,6 +135,12 @@ The placeholders are:
 - '%n': newline
 - '%x00': print a byte from a hex code
 
+NOTE: Some placeholders may depend on other options given to the
+revision traversal engine. For example, the `%g*` reflog options will
+insert an empty string unless we are traversing reflog entries (e.g., by
+`git log -g`). The `%d` placeholder will use the "short" decoration
+format if `--decorate` was not already provided on the command line.
+
 * 'tformat:'
 +
 The 'tformat:' format works exactly like 'format:', except that it

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information
  2009-10-16 14:20                 ` [PATCH v3 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
@ 2009-10-17 14:48                   ` Thomas Rast
  2009-10-17 15:06                     ` Jakub Narebski
  2009-10-18  7:18                     ` Jeff King
  0 siblings, 2 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-17 14:48 UTC (permalink / raw)
  To: Jeff King, Junio C Hamano; +Cc: Jef Driesen, Nanako Shiraishi, git

Add three new --pretty=format escapes:

  %gD  long  reflog descriptor (e.g. refs/stash@{0})
  %gd  short reflog descriptor (e.g. stash@{0})
  %gs  reflog message

This is achieved by passing down the reflog info, if any, inside the
pretty_print_context struct.

We use the newly refactored get_reflog_selector(), and give it some
extra functionality to extract a shortened ref.  The shortening is
cached inside the commit_reflogs struct; the only allocation of it
happens in read_complete_reflog(), where it is initialised to 0.  Also
add another helper get_reflog_message() for the message extraction.

Note that the --format="%h %gD: %gs" tests may not work in real
repositories, as the --pretty formatter doesn't know to leave away the
": " on the last commit in an incomplete (because git-gc removed the
old part) reflog.  This equivalence is nevertheless the main goal of
this patch.

Thanks to Jeff King for reviews, the %gd testcase and documentation.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---

I wrote:
> [Tacking this on the corresponding v3 patch, but the text below is
> from <20091017011801.GA31443@coredump.intra.peff.net>.]

This sadly backfired, as I forgot to snip out the in-reply-to in the
mail itself and git-send-email apparently trusted that more.  Sorry
for the confusion.

Jeff King wrote:
> I am tempted to do a note like the one below, but maybe the behavior is
> obvious enough to users that it isn't necessary.
[...]
> +NOTE: Some placeholders may depend on other options given to the
> +revision traversal engine. For example, the `%g*` reflog options will
> +insert an empty string unless we are traversing reflog entries (e.g., by
> +`git log -g`). The `%d` placeholder will use the "short" decoration
> +format if `--decorate` was not already provided on the command line.

Sure.  I figured it was obvious enough, but since you already went to
the lengths of documenting the exact behaviour of %d, I squashed it
and adjusted the acknowledgement in the commit message accordingly.

 Documentation/pretty-formats.txt |    9 +++++++++
 commit.h                         |    1 +
 log-tree.c                       |    1 +
 pretty.c                         |   17 +++++++++++++++++
 reflog-walk.c                    |   35 ++++++++++++++++++++++++++++++++---
 reflog-walk.h                    |    8 ++++++++
 t/t6006-rev-list-format.sh       |   18 ++++++++++++++++++
 7 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 2a845b1..38b9904 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -123,6 +123,9 @@ The placeholders are:
 - '%s': subject
 - '%f': sanitized subject line, suitable for a filename
 - '%b': body
+- '%gD': reflog selector, e.g., `refs/stash@\{1\}`
+- '%gd': shortened reflog selector, e.g., `stash@\{1\}`
+- '%gs': reflog subject
 - '%Cred': switch color to red
 - '%Cgreen': switch color to green
 - '%Cblue': switch color to blue
@@ -132,6 +135,12 @@ The placeholders are:
 - '%n': newline
 - '%x00': print a byte from a hex code
 
+NOTE: Some placeholders may depend on other options given to the
+revision traversal engine. For example, the `%g*` reflog options will
+insert an empty string unless we are traversing reflog entries (e.g., by
+`git log -g`). The `%d` placeholder will use the "short" decoration
+format if `--decorate` was not already provided on the command line.
+
 * 'tformat:'
 +
 The 'tformat:' format works exactly like 'format:', except that it
diff --git a/commit.h b/commit.h
index 011766d..15cb649 100644
--- a/commit.h
+++ b/commit.h
@@ -70,6 +70,7 @@ struct pretty_print_context
 	const char *after_subject;
 	enum date_mode date_mode;
 	int need_8bit_cte;
+	struct reflog_walk_info *reflog_info;
 };
 
 extern int non_ascii(int);
diff --git a/log-tree.c b/log-tree.c
index f57487f..8e782fc 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -409,6 +409,7 @@ void show_log(struct rev_info *opt)
 	ctx.date_mode = opt->date_mode;
 	ctx.abbrev = opt->diffopt.abbrev;
 	ctx.after_subject = extra_headers;
+	ctx.reflog_info = opt->reflog_info;
 	pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);
 
 	if (opt->add_signoff)
diff --git a/pretty.c b/pretty.c
index d6d57eb..fc65fca 100644
--- a/pretty.c
+++ b/pretty.c
@@ -7,6 +7,7 @@
 #include "mailmap.h"
 #include "log-tree.h"
 #include "color.h"
+#include "reflog-walk.h"
 
 static char *user_format;
 
@@ -701,6 +702,22 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 	case 'd':
 		format_decoration(sb, commit);
 		return 1;
+	case 'g':		/* reflog info */
+		switch(placeholder[1]) {
+		case 'd':	/* reflog selector */
+		case 'D':
+			if (c->pretty_ctx->reflog_info)
+				get_reflog_selector(sb,
+						    c->pretty_ctx->reflog_info,
+						    c->pretty_ctx->date_mode,
+						    (placeholder[1] == 'd'));
+			return 2;
+		case 's':	/* reflog message */
+			if (c->pretty_ctx->reflog_info)
+				get_reflog_message(sb, c->pretty_ctx->reflog_info);
+			return 2;
+		}
+		return 0;	/* unknown %g placeholder */
 	}
 
 	/* For the rest we have to parse the commit header. */
diff --git a/reflog-walk.c b/reflog-walk.c
index 596bafe..caba4f7 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -8,6 +8,7 @@
 
 struct complete_reflogs {
 	char *ref;
+	const char *short_ref;
 	struct reflog_info {
 		unsigned char osha1[20], nsha1[20];
 		char *email;
@@ -243,15 +244,26 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
 
 void get_reflog_selector(struct strbuf *sb,
 			 struct reflog_walk_info *reflog_info,
-			 enum date_mode dmode)
+			 enum date_mode dmode,
+			 int shorten)
 {
 	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
 	struct reflog_info *info;
+	const char *printed_ref;
 
 	if (!commit_reflog)
 		return;
 
-	strbuf_addf(sb, "%s@{", commit_reflog->reflogs->ref);
+	if (shorten) {
+		if (!commit_reflog->reflogs->short_ref)
+			commit_reflog->reflogs->short_ref
+				= shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);
+		printed_ref = commit_reflog->reflogs->short_ref;
+	} else {
+		printed_ref = commit_reflog->reflogs->ref;
+	}
+
+	strbuf_addf(sb, "%s@{", printed_ref);
 	if (commit_reflog->flag || dmode) {
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
 		strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));
@@ -263,6 +275,23 @@ void get_reflog_selector(struct strbuf *sb,
 	strbuf_addch(sb, '}');
 }
 
+void get_reflog_message(struct strbuf *sb,
+			struct reflog_walk_info *reflog_info)
+{
+	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+	struct reflog_info *info;
+	size_t len;
+
+	if (!commit_reflog)
+		return;
+
+	info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+	len = strlen(info->message);
+	if (len > 0)
+		len--; /* strip away trailing newline */
+	strbuf_add(sb, info->message, len);
+}
+
 void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 	enum date_mode dmode)
 {
@@ -272,7 +301,7 @@ void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 		struct strbuf selector = STRBUF_INIT;
 
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
-		get_reflog_selector(&selector, reflog_info, dmode);
+		get_reflog_selector(&selector, reflog_info, dmode, 0);
 		if (oneline) {
 			printf("%s: %s", selector.buf, info->message);
 		}
diff --git a/reflog-walk.h b/reflog-walk.h
index 74c9096..7bd2cd4 100644
--- a/reflog-walk.h
+++ b/reflog-walk.h
@@ -3,6 +3,8 @@
 
 #include "cache.h"
 
+struct reflog_walk_info;
+
 extern void init_reflog_walk(struct reflog_walk_info** info);
 extern int add_reflog_for_walk(struct reflog_walk_info *info,
 		struct commit *commit, const char *name);
@@ -10,5 +12,11 @@ extern void fake_reflog_parent(struct reflog_walk_info *info,
 		struct commit *commit);
 extern void show_reflog_message(struct reflog_walk_info *info, int,
 		enum date_mode);
+extern void get_reflog_message(struct strbuf *sb,
+		struct reflog_walk_info *reflog_info);
+extern void get_reflog_selector(struct strbuf *sb,
+		struct reflog_walk_info *reflog_info,
+		enum date_mode dmode,
+		int shorten);
 
 #endif
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index 59d1f62..7f61ab0 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -162,4 +162,22 @@ test_expect_success 'empty email' '
 	}
 '
 
+test_expect_success '"%h %gD: %gs" is same as git-reflog' '
+	git reflog >expect &&
+	git log -g --format="%h %gD: %gs" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '"%h %gD: %gs" is same as git-reflog (with date)' '
+	git reflog --date=raw >expect &&
+	git log -g --format="%h %gD: %gs" --date=raw >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '%gd shortens ref name' '
+	echo "master@{0}" >expect.gd-short &&
+	git log -g -1 --format=%gd refs/heads/master >actual.gd-short &&
+	test_cmp expect.gd-short actual.gd-short
+'
+
 test_done
-- 
1.6.5.116.g4aaa3

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information
  2009-10-17 14:48                   ` [PATCH v3.1 " Thomas Rast
@ 2009-10-17 15:06                     ` Jakub Narebski
  2009-10-18  7:18                     ` Jeff King
  1 sibling, 0 replies; 49+ messages in thread
From: Jakub Narebski @ 2009-10-17 15:06 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jeff King, Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

Thomas Rast <trast@student.ethz.ch> writes:

> Note that the --format="%h %gD: %gs" tests may not work in real
> repositories, as the --pretty formatter doesn't know to leave away the
> ": " on the last commit in an incomplete (because git-gc removed the
> old part) reflog.  This equivalence is nevertheless the main goal of
> this patch.

Perhaps just-introduced grouping syntax would help there?  You could
for example write

  --format="%h%[all() %gD: %gs%]"

which would expand nested group if _all_ placeholders within it have
expansion.  Perhaps %[ ... %], or %[? ... %], or %[* ... %] could be
shorter versions...

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct
  2009-10-16 14:20                 ` [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
@ 2009-10-17 17:05                   ` Junio C Hamano
  2009-10-18 18:51                     ` Thomas Rast
  0 siblings, 1 reply; 49+ messages in thread
From: Junio C Hamano @ 2009-10-17 17:05 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git

Thomas Rast <trast@student.ethz.ch> writes:

> pretty_print_commit() has a bunch of rarely-used arguments, and
> introducing more of them requires yet another update of all the call
> sites.  Refactor most of them into a struct to make future extensions
> easier.
>
> The ones that stay "plain" arguments were chosen on the grounds that
> all callers put real arguments there, whereas some callers have 0/NULL
> for all arguments that were factored into the struct.
>
> We declare the struct 'const' to ensure none of the callers are bitten
> by the changed (no longer call-by-value) semantics.
>
> Signed-off-by: Thomas Rast <trast@student.ethz.ch>

Good idea, a slightly sloppy/careless execution.

The existing calls to format_commit_message() often take DATE_NORMAL to
its "enum date_mode dmode" argument, and you replaced it with a pointer to
a struct.  DATE_NORMAL happens to be "0" and the compiler does not catch
calls you forgot to convert in this patch.

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information
  2009-10-17 14:48                   ` [PATCH v3.1 " Thomas Rast
  2009-10-17 15:06                     ` Jakub Narebski
@ 2009-10-18  7:18                     ` Jeff King
  2009-10-18 10:34                       ` Nanako Shiraishi
  1 sibling, 1 reply; 49+ messages in thread
From: Jeff King @ 2009-10-18  7:18 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

On Sat, Oct 17, 2009 at 04:48:11PM +0200, Thomas Rast wrote:

> > +NOTE: Some placeholders may depend on other options given to the
> > +revision traversal engine. For example, the `%g*` reflog options will
> > +insert an empty string unless we are traversing reflog entries (e.g., by
> > +`git log -g`). The `%d` placeholder will use the "short" decoration
> > +format if `--decorate` was not already provided on the command line.
> 
> Sure.  I figured it was obvious enough, but since you already went to
> the lengths of documenting the exact behaviour of %d, I squashed it
> and adjusted the acknowledgement in the commit message accordingly.

If the consensus (or Junio's decision when applying) is that we don't
need it, I don't mind if my suggestion is scrapped (or reworded).

-Peff

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information
  2009-10-18  7:18                     ` Jeff King
@ 2009-10-18 10:34                       ` Nanako Shiraishi
  0 siblings, 0 replies; 49+ messages in thread
From: Nanako Shiraishi @ 2009-10-18 10:34 UTC (permalink / raw)
  To: Jeff King; +Cc: Thomas Rast, Junio C Hamano, Jef Driesen, Nanako Shiraishi, git

Quoting Jeff King <peff@peff.net>

> On Sat, Oct 17, 2009 at 04:48:11PM +0200, Thomas Rast wrote:
>
>> > +NOTE: Some placeholders may depend on other options given to the
>> > +revision traversal engine. For example, the `%g*` reflog options will
>> > +insert an empty string unless we are traversing reflog entries (e.g., by
>> > +`git log -g`). The `%d` placeholder will use the "short" decoration
>> > +format if `--decorate` was not already provided on the command line.
>> 
>> Sure.  I figured it was obvious enough, but since you already went to
>> the lengths of documenting the exact behaviour of %d, I squashed it
>> and adjusted the acknowledgement in the commit message accordingly.
>
> If the consensus (or Junio's decision when applying) is that we don't
> need it, I don't mind if my suggestion is scrapped (or reworded).

I think your clarification is a good addition.

-- 
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct
  2009-10-17 17:05                   ` Junio C Hamano
@ 2009-10-18 18:51                     ` Thomas Rast
  2009-10-18 22:47                       ` Junio C Hamano
  0 siblings, 1 reply; 49+ messages in thread
From: Thomas Rast @ 2009-10-18 18:51 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git

Junio C Hamano wrote:
> The existing calls to format_commit_message() often take DATE_NORMAL to
> its "enum date_mode dmode" argument, and you replaced it with a pointer to
> a struct.  DATE_NORMAL happens to be "0" and the compiler does not catch
> calls you forgot to convert in this patch.

Hmph, that's embarrassing.  Apparently I was way too focused on
pretty_print_commit...

I can devise a test that would have detected this.  Should I include
it in the reroll, or is that something we do not guard against?

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct
  2009-10-18 18:51                     ` Thomas Rast
@ 2009-10-18 22:47                       ` Junio C Hamano
  2009-10-19 15:48                         ` [PATCH v4 0/5] Pretty formats for reflog data Thomas Rast
  0 siblings, 1 reply; 49+ messages in thread
From: Junio C Hamano @ 2009-10-18 22:47 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git

Thomas Rast <trast@student.ethz.ch> writes:

> Junio C Hamano wrote:
>> The existing calls to format_commit_message() often take DATE_NORMAL to
>> its "enum date_mode dmode" argument, and you replaced it with a pointer to
>> a struct.  DATE_NORMAL happens to be "0" and the compiler does not catch
>> calls you forgot to convert in this patch.
>
> Hmph, that's embarrassing.  Apparently I was way too focused on
> pretty_print_commit...

This is nothing to be embarrassed about.  I did not notice it when I
queued the series either, and I noticed it only when I tried to look at
interactions with js/diff-verbose-submodule topic(the other series does
not hardcode the style to be DATE_NORMAL).

One solution to help the compiler catch this kind of semantic crash upon
merging or applying code based on the old format_commit_message() would
have been to change its function signature (or even the name), so that it
would not go unnoticed that DATE_NORMAL that happens to be "0" is silently
interpreted as (void *)0 == NULL.

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 0/5] Pretty formats for reflog data
  2009-10-18 22:47                       ` Junio C Hamano
@ 2009-10-19 15:48                         ` Thomas Rast
  2009-10-19 15:48                           ` [PATCH v4 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
                                             ` (4 more replies)
  0 siblings, 5 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-19 15:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git

Junio C Hamano wrote:
> 
> One solution to help the compiler catch this kind of semantic crash upon
> merging or applying code based on the old format_commit_message() would
> have been to change its function signature (or even the name), so that it
> would not go unnoticed that DATE_NORMAL that happens to be "0" is silently
> interpreted as (void *)0 == NULL.

Indeed, that would have been a good idea.  (I still don't fully see
the use of allowing an enum value as a pointer, but apparently the
standard's that way.)

I fixed the calls to format_commit_message(), but without changing the
function signature compared to the last patch.  I also decided not to
put in the test case; the easiest I could come up with was the
following:

-- 8< --
diff --git i/t/t5001-archive-attr.sh w/t/t5001-archive-attr.sh
index 426b319..0950527 100755
--- i/t/t5001-archive-attr.sh
+++ w/t/t5001-archive-attr.sh
@@ -4,7 +4,7 @@ test_description='git archive attribute tests'
 
 . ./test-lib.sh
 
-SUBSTFORMAT=%H%n
+SUBSTFORMAT=%H%ad%n
 
 test_expect_exists() {
 	test_expect_success " $1 exists" "test -e $1"
-- >8 --

which immediately fails most tests in the file because of segfaults
with the buggy series.  However, it still wouldn't catch other broken
callers, if there were any, so I left it out.

Compared to v3, I also rebased the series on current master, which
conflicted with 7f98ebc (format_commit_message(): fix function
signature, 2009-10-15) so you now need that commit to apply it.

Finally, I squashed a revert of 0a0c342 (git-stash documentation:
mention default options for 'list', 2009-10-12) into 5/5 since there
are no more default options after my patch.


Thomas Rast (5):
  Refactor pretty_print_commit arguments into a struct
  reflog-walk: refactor the branch@{num} formatting
  Introduce new pretty formats %g[sdD] for reflog information
  stash list: use new %g formats instead of sed
  stash list: drop the default limit of 10 stashes

 Documentation/git-stash.txt      |    3 +-
 Documentation/pretty-formats.txt |    9 ++++
 archive.c                        |    4 +-
 builtin-branch.c                 |    3 +-
 builtin-checkout.c               |    3 +-
 builtin-commit.c                 |    8 +++-
 builtin-log.c                    |    3 +-
 builtin-merge.c                  |    7 ++-
 builtin-rev-list.c               |    7 ++-
 builtin-shortlog.c               |    9 +++-
 builtin-show-branch.c            |    4 +-
 commit.h                         |   20 ++++++---
 git-stash.sh                     |    8 +---
 log-tree.c                       |   25 ++++++-----
 pretty.c                         |   44 ++++++++++++++------
 reflog-walk.c                    |   83 ++++++++++++++++++++++++++++----------
 reflog-walk.h                    |    8 ++++
 t/t6006-rev-list-format.sh       |   18 ++++++++
 18 files changed, 189 insertions(+), 77 deletions(-)

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v4 1/5] Refactor pretty_print_commit arguments into a struct
  2009-10-19 15:48                         ` [PATCH v4 0/5] Pretty formats for reflog data Thomas Rast
@ 2009-10-19 15:48                           ` Thomas Rast
  2009-10-19 15:48                           ` [PATCH v4 2/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
                                             ` (3 subsequent siblings)
  4 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-19 15:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git

pretty_print_commit() has a bunch of rarely-used arguments, and
introducing more of them requires yet another update of all the call
sites.  Refactor most of them into a struct to make future extensions
easier.

The ones that stay "plain" arguments were chosen on the grounds that
all callers put real arguments there, whereas some callers have 0/NULL
for all arguments that were factored into the struct.

We declare the struct 'const' to ensure none of the callers are bitten
by the changed (no longer call-by-value) semantics.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 archive.c             |    4 +++-
 builtin-branch.c      |    3 ++-
 builtin-checkout.c    |    3 ++-
 builtin-commit.c      |    8 ++++++--
 builtin-log.c         |    3 ++-
 builtin-merge.c       |    7 +++++--
 builtin-rev-list.c    |    7 ++++---
 builtin-shortlog.c    |    9 ++++++---
 builtin-show-branch.c |    4 ++--
 commit.h              |   19 +++++++++++++------
 log-tree.c            |   24 +++++++++++++-----------
 pretty.c              |   27 ++++++++++++++-------------
 12 files changed, 72 insertions(+), 46 deletions(-)

diff --git a/archive.c b/archive.c
index 0cc79d2..55b2732 100644
--- a/archive.c
+++ b/archive.c
@@ -31,6 +31,8 @@ static void format_subst(const struct commit *commit,
 {
 	char *to_free = NULL;
 	struct strbuf fmt = STRBUF_INIT;
+	struct pretty_print_context ctx = {0};
+	ctx.date_mode = DATE_NORMAL;
 
 	if (src == buf->buf)
 		to_free = strbuf_detach(buf, NULL);
@@ -48,7 +50,7 @@ static void format_subst(const struct commit *commit,
 		strbuf_add(&fmt, b + 8, c - b - 8);
 
 		strbuf_add(buf, src, b - src);
-		format_commit_message(commit, fmt.buf, buf, DATE_NORMAL);
+		format_commit_message(commit, fmt.buf, buf, &ctx);
 		len -= c + 1 - src;
 		src  = c + 1;
 	}
diff --git a/builtin-branch.c b/builtin-branch.c
index 9f57992..05e876e 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -387,8 +387,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 
 		commit = item->commit;
 		if (commit && !parse_commit(commit)) {
+			struct pretty_print_context ctx = {0};
 			pretty_print_commit(CMIT_FMT_ONELINE, commit,
-					    &subject, 0, NULL, NULL, 0, 0);
+					    &subject, &ctx);
 			sub = subject.buf;
 		}
 
diff --git a/builtin-checkout.c b/builtin-checkout.c
index d050c37..075a49f 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -302,8 +302,9 @@ static void show_local_changes(struct object *head)
 static void describe_detached_head(char *msg, struct commit *commit)
 {
 	struct strbuf sb = STRBUF_INIT;
+	struct pretty_print_context ctx = {0};
 	parse_commit(commit);
-	pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);
+	pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx);
 	fprintf(stderr, "%s %s... %s\n", msg,
 		find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
 	strbuf_release(&sb);
diff --git a/builtin-commit.c b/builtin-commit.c
index 200ffda..ac173f9 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -684,8 +684,10 @@ static int message_is_empty(struct strbuf *sb)
 	prepare_revision_walk(&revs);
 	commit = get_revision(&revs);
 	if (commit) {
+		struct pretty_print_context ctx = {0};
+		ctx.date_mode = DATE_NORMAL;
 		strbuf_release(&buf);
-		format_commit_message(commit, "%an <%ae>", &buf, DATE_NORMAL);
+		format_commit_message(commit, "%an <%ae>", &buf, &ctx);
 		return strbuf_detach(&buf, NULL);
 	}
 	die("No existing author found with '%s'", name);
@@ -942,8 +944,10 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
 		initial_commit ? " (root-commit)" : "");
 
 	if (!log_tree_commit(&rev, commit)) {
+		struct pretty_print_context ctx = {0};
+		ctx.date_mode = DATE_NORMAL;
 		struct strbuf buf = STRBUF_INIT;
-		format_commit_message(commit, format + 7, &buf, DATE_NORMAL);
+		format_commit_message(commit, format + 7, &buf, &ctx);
 		printf("%s\n", buf.buf);
 		strbuf_release(&buf);
 	}
diff --git a/builtin-log.c b/builtin-log.c
index 25e21ed..207a361 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -1304,8 +1304,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
 
 		if (verbose) {
 			struct strbuf buf = STRBUF_INIT;
+			struct pretty_print_context ctx = {0};
 			pretty_print_commit(CMIT_FMT_ONELINE, commit,
-			                    &buf, 0, NULL, NULL, 0, 0);
+					    &buf, &ctx);
 			printf("%c %s %s\n", sign,
 			       sha1_to_hex(commit->object.sha1), buf.buf);
 			strbuf_release(&buf);
diff --git a/builtin-merge.c b/builtin-merge.c
index b6b8428..c69a305 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -264,6 +264,7 @@ static void squash_message(void)
 	struct strbuf out = STRBUF_INIT;
 	struct commit_list *j;
 	int fd;
+	struct pretty_print_context ctx = {0};
 
 	printf("Squash commit -- not updating HEAD\n");
 	fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
@@ -285,13 +286,15 @@ static void squash_message(void)
 	if (prepare_revision_walk(&rev))
 		die("revision walk setup failed");
 
+	ctx.abbrev = rev.abbrev;
+	ctx.date_mode = rev.date_mode;
+
 	strbuf_addstr(&out, "Squashed commit of the following:\n");
 	while ((commit = get_revision(&rev)) != NULL) {
 		strbuf_addch(&out, '\n');
 		strbuf_addf(&out, "commit %s\n",
 			sha1_to_hex(commit->object.sha1));
-		pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,
-			NULL, NULL, rev.date_mode, 0);
+		pretty_print_commit(rev.commit_format, commit, &out, &ctx);
 	}
 	if (write(fd, out.buf, out.len) < 0)
 		die_errno("Writing SQUASH_MSG");
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 4ba1c12..42cc8d8 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -96,9 +96,10 @@ static void show_commit(struct commit *commit, void *data)
 
 	if (revs->verbose_header && commit->buffer) {
 		struct strbuf buf = STRBUF_INIT;
-		pretty_print_commit(revs->commit_format, commit,
-				    &buf, revs->abbrev, NULL, NULL,
-				    revs->date_mode, 0);
+		struct pretty_print_context ctx = {0};
+		ctx.abbrev = revs->abbrev;
+		ctx.date_mode = revs->date_mode;
+		pretty_print_commit(revs->commit_format, commit, &buf, &ctx);
 		if (revs->graph) {
 			if (buf.len) {
 				if (revs->commit_format != CMIT_FMT_ONELINE)
diff --git a/builtin-shortlog.c b/builtin-shortlog.c
index 4d4a3c8..8aa63c7 100644
--- a/builtin-shortlog.c
+++ b/builtin-shortlog.c
@@ -158,9 +158,12 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
 		    sha1_to_hex(commit->object.sha1));
 	if (log->user_format) {
 		struct strbuf buf = STRBUF_INIT;
-
-		pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf,
-			DEFAULT_ABBREV, "", "", DATE_NORMAL, 0);
+		struct pretty_print_context ctx = {0};
+		ctx.abbrev = DEFAULT_ABBREV;
+		ctx.subject = "";
+		ctx.after_subject = "";
+		ctx.date_mode = DATE_NORMAL;
+		pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf, &ctx);
 		insert_one_record(log, author, buf.buf);
 		strbuf_release(&buf);
 		return;
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index be95930..9f13caa 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -293,8 +293,8 @@ static void show_one_commit(struct commit *commit, int no_name)
 	struct commit_name *name = commit->util;
 
 	if (commit->object.parsed) {
-		pretty_print_commit(CMIT_FMT_ONELINE, commit,
-				    &pretty, 0, NULL, NULL, 0, 0);
+		struct pretty_print_context ctx = {0};
+		pretty_print_commit(CMIT_FMT_ONELINE, commit, &pretty, &ctx);
 		pretty_str = pretty.buf;
 	}
 	if (!prefixcmp(pretty_str, "[PATCH] "))
diff --git a/commit.h b/commit.h
index 95f981a..084cf55 100644
--- a/commit.h
+++ b/commit.h
@@ -63,6 +63,15 @@ enum cmit_fmt {
 	CMIT_FMT_UNSPECIFIED,
 };
 
+struct pretty_print_context
+{
+	int abbrev;
+	const char *subject;
+	const char *after_subject;
+	enum date_mode date_mode;
+	int need_8bit_cte;
+};
+
 extern int non_ascii(int);
 extern int has_non_ascii(const char *text);
 struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
@@ -71,12 +80,10 @@ enum cmit_fmt {
 extern void get_commit_format(const char *arg, struct rev_info *);
 extern void format_commit_message(const struct commit *commit,
 				  const char *format, struct strbuf *sb,
-				  enum date_mode dmode);
-extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,
-                                struct strbuf *,
-                                int abbrev, const char *subject,
-                                const char *after_subject, enum date_mode,
-				int need_8bit_cte);
+				  const struct pretty_print_context *context);
+extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
+				struct strbuf *sb,
+				const struct pretty_print_context *context);
 void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
 		   const char *line, enum date_mode dmode,
 		   const char *encoding);
diff --git a/log-tree.c b/log-tree.c
index f7d54f2..1675035 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -179,8 +179,10 @@ void get_patch_filename(struct commit *commit, int nr, const char *suffix,
 	strbuf_addf(buf, commit ? "%04d-" : "%d", nr);
 	if (commit) {
 		int max_len = start_len + FORMAT_PATCH_NAME_MAX - suffix_len;
+		struct pretty_print_context ctx = {0};
+		ctx.date_mode = DATE_NORMAL;
 
-		format_commit_message(commit, "%f", buf, DATE_NORMAL);
+		format_commit_message(commit, "%f", buf, &ctx);
 		if (max_len < buf->len)
 			strbuf_setlen(buf, max_len);
 		strbuf_addstr(buf, suffix);
@@ -277,10 +279,9 @@ void show_log(struct rev_info *opt)
 	struct strbuf msgbuf = STRBUF_INIT;
 	struct log_info *log = opt->loginfo;
 	struct commit *commit = log->commit, *parent = log->parent;
-	int abbrev = opt->diffopt.abbrev;
 	int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;
-	const char *subject = NULL, *extra_headers = opt->extra_headers;
-	int need_8bit_cte = 0;
+	const char *extra_headers = opt->extra_headers;
+	struct pretty_print_context ctx = {0};
 
 	opt->loginfo = NULL;
 	if (!opt->verbose_header) {
@@ -347,8 +348,8 @@ void show_log(struct rev_info *opt)
 	 */
 
 	if (opt->commit_format == CMIT_FMT_EMAIL) {
-		log_write_email_headers(opt, commit, &subject, &extra_headers,
-					&need_8bit_cte);
+		log_write_email_headers(opt, commit, &ctx.subject, &extra_headers,
+					&ctx.need_8bit_cte);
 	} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
 		fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
 		if (opt->commit_format != CMIT_FMT_ONELINE)
@@ -405,11 +406,12 @@ void show_log(struct rev_info *opt)
 	/*
 	 * And then the pretty-printed message itself
 	 */
-	if (need_8bit_cte >= 0)
-		need_8bit_cte = has_non_ascii(opt->add_signoff);
-	pretty_print_commit(opt->commit_format, commit, &msgbuf,
-			    abbrev, subject, extra_headers, opt->date_mode,
-			    need_8bit_cte);
+	if (ctx.need_8bit_cte >= 0)
+		ctx.need_8bit_cte = has_non_ascii(opt->add_signoff);
+	ctx.date_mode = opt->date_mode;
+	ctx.abbrev = opt->diffopt.abbrev;
+	ctx.after_subject = extra_headers;
+	pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);
 
 	if (opt->add_signoff)
 		append_signoff(&msgbuf, opt->add_signoff);
diff --git a/pretty.c b/pretty.c
index 587101f..37ad6eb 100644
--- a/pretty.c
+++ b/pretty.c
@@ -442,7 +442,7 @@ struct chunk {
 
 struct format_commit_context {
 	const struct commit *commit;
-	enum date_mode dmode;
+	const struct pretty_print_context *pretty_ctx;
 	unsigned commit_header_parsed:1;
 	unsigned commit_message_parsed:1;
 
@@ -711,11 +711,11 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 	case 'a':	/* author ... */
 		return format_person_part(sb, placeholder[1],
 				   msg + c->author.off, c->author.len,
-				   c->dmode);
+				   c->pretty_ctx->date_mode);
 	case 'c':	/* committer ... */
 		return format_person_part(sb, placeholder[1],
 				   msg + c->committer.off, c->committer.len,
-				   c->dmode);
+				   c->pretty_ctx->date_mode);
 	case 'e':	/* encoding */
 		strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
 		return 1;
@@ -741,13 +741,13 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 
 void format_commit_message(const struct commit *commit,
 			   const char *format, struct strbuf *sb,
-			   enum date_mode dmode)
+			   const struct pretty_print_context *pretty_ctx)
 {
 	struct format_commit_context context;
 
 	memset(&context, 0, sizeof(context));
 	context.commit = commit;
-	context.dmode = dmode;
+	context.pretty_ctx = pretty_ctx;
 	strbuf_expand(sb, format, format_commit_item, &context);
 }
 
@@ -900,18 +900,18 @@ void pp_remainder(enum cmit_fmt fmt,
 }
 
 void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
-			 struct strbuf *sb, int abbrev,
-			 const char *subject, const char *after_subject,
-			 enum date_mode dmode, int need_8bit_cte)
+			 struct strbuf *sb,
+			 const struct pretty_print_context *context)
 {
 	unsigned long beginning_of_body;
 	int indent = 4;
 	const char *msg = commit->buffer;
 	char *reencoded;
 	const char *encoding;
+	int need_8bit_cte = context->need_8bit_cte;
 
 	if (fmt == CMIT_FMT_USERFORMAT) {
-		format_commit_message(commit, user_format, sb, dmode);
+		format_commit_message(commit, user_format, sb, context);
 		return;
 	}
 
@@ -946,8 +946,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
 		}
 	}
 
-	pp_header(fmt, abbrev, dmode, encoding, commit, &msg, sb);
-	if (fmt != CMIT_FMT_ONELINE && !subject) {
+	pp_header(fmt, context->abbrev, context->date_mode, encoding,
+		  commit, &msg, sb);
+	if (fmt != CMIT_FMT_ONELINE && !context->subject) {
 		strbuf_addch(sb, '\n');
 	}
 
@@ -956,8 +957,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
 
 	/* These formats treat the title line specially. */
 	if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
-		pp_title_line(fmt, &msg, sb, subject,
-			      after_subject, encoding, need_8bit_cte);
+		pp_title_line(fmt, &msg, sb, context->subject,
+			      context->after_subject, encoding, need_8bit_cte);
 
 	beginning_of_body = sb->len;
 	if (fmt != CMIT_FMT_ONELINE)
-- 
1.6.5.1.137.gefbc6

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v4 2/5] reflog-walk: refactor the branch@{num} formatting
  2009-10-19 15:48                         ` [PATCH v4 0/5] Pretty formats for reflog data Thomas Rast
  2009-10-19 15:48                           ` [PATCH v4 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
@ 2009-10-19 15:48                           ` Thomas Rast
  2009-10-19 15:48                           ` [PATCH v4 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
                                             ` (2 subsequent siblings)
  4 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-19 15:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git

We'll use the same output in an upcoming commit, so refactor its
formatting (which was duplicated anyway) into a separate function.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 reflog-walk.c |   54 ++++++++++++++++++++++++++++++++----------------------
 1 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/reflog-walk.c b/reflog-walk.c
index 5623ea6..596bafe 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -241,36 +241,46 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
 	commit->object.flags &= ~(ADDED | SEEN | SHOWN);
 }
 
-void show_reflog_message(struct reflog_walk_info *info, int oneline,
+void get_reflog_selector(struct strbuf *sb,
+			 struct reflog_walk_info *reflog_info,
+			 enum date_mode dmode)
+{
+	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+	struct reflog_info *info;
+
+	if (!commit_reflog)
+		return;
+
+	strbuf_addf(sb, "%s@{", commit_reflog->reflogs->ref);
+	if (commit_reflog->flag || dmode) {
+		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+		strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));
+	} else {
+		strbuf_addf(sb, "%d", commit_reflog->reflogs->nr
+			    - 2 - commit_reflog->recno);
+	}
+
+	strbuf_addch(sb, '}');
+}
+
+void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 	enum date_mode dmode)
 {
-	if (info && info->last_commit_reflog) {
-		struct commit_reflog *commit_reflog = info->last_commit_reflog;
+	if (reflog_info && reflog_info->last_commit_reflog) {
+		struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
 		struct reflog_info *info;
+		struct strbuf selector = STRBUF_INIT;
 
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+		get_reflog_selector(&selector, reflog_info, dmode);
 		if (oneline) {
-			printf("%s@{", commit_reflog->reflogs->ref);
-			if (commit_reflog->flag || dmode)
-				printf("%s", show_date(info->timestamp,
-						       info->tz,
-						       dmode));
-			else
-				printf("%d", commit_reflog->reflogs->nr
-				       - 2 - commit_reflog->recno);
-			printf("}: %s", info->message);
+			printf("%s: %s", selector.buf, info->message);
 		}
 		else {
-			printf("Reflog: %s@{", commit_reflog->reflogs->ref);
-			if (commit_reflog->flag || dmode)
-				printf("%s", show_date(info->timestamp,
-							info->tz,
-							dmode));
-			else
-				printf("%d", commit_reflog->reflogs->nr
-				       - 2 - commit_reflog->recno);
-			printf("} (%s)\nReflog message: %s",
-			       info->email, info->message);
+			printf("Reflog: %s (%s)\nReflog message: %s",
+			       selector.buf, info->email, info->message);
 		}
+
+		strbuf_release(&selector);
 	}
 }
-- 
1.6.5.1.137.gefbc6

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v4 3/5] Introduce new pretty formats %g[sdD] for reflog information
  2009-10-19 15:48                         ` [PATCH v4 0/5] Pretty formats for reflog data Thomas Rast
  2009-10-19 15:48                           ` [PATCH v4 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
  2009-10-19 15:48                           ` [PATCH v4 2/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
@ 2009-10-19 15:48                           ` Thomas Rast
  2009-10-19 15:48                           ` [PATCH v4 4/5] stash list: use new %g formats instead of sed Thomas Rast
  2009-10-19 15:48                           ` [PATCH v4 5/5] stash list: drop the default limit of 10 stashes Thomas Rast
  4 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-19 15:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git

Add three new --pretty=format escapes:

  %gD  long  reflog descriptor (e.g. refs/stash@{0})
  %gd  short reflog descriptor (e.g. stash@{0})
  %gs  reflog message

This is achieved by passing down the reflog info, if any, inside the
pretty_print_context struct.

We use the newly refactored get_reflog_selector(), and give it some
extra functionality to extract a shortened ref.  The shortening is
cached inside the commit_reflogs struct; the only allocation of it
happens in read_complete_reflog(), where it is initialised to 0.  Also
add another helper get_reflog_message() for the message extraction.

Note that the --format="%h %gD: %gs" tests may not work in real
repositories, as the --pretty formatter doesn't know to leave away the
": " on the last commit in an incomplete (because git-gc removed the
old part) reflog.  This equivalence is nevertheless the main goal of
this patch.

Thanks to Jeff King for reviews, the %gd testcase and documentation.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/pretty-formats.txt |    9 +++++++++
 commit.h                         |    1 +
 log-tree.c                       |    1 +
 pretty.c                         |   17 +++++++++++++++++
 reflog-walk.c                    |   35 ++++++++++++++++++++++++++++++++---
 reflog-walk.h                    |    8 ++++++++
 t/t6006-rev-list-format.sh       |   18 ++++++++++++++++++
 7 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 2a845b1..38b9904 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -123,6 +123,9 @@ The placeholders are:
 - '%s': subject
 - '%f': sanitized subject line, suitable for a filename
 - '%b': body
+- '%gD': reflog selector, e.g., `refs/stash@\{1\}`
+- '%gd': shortened reflog selector, e.g., `stash@\{1\}`
+- '%gs': reflog subject
 - '%Cred': switch color to red
 - '%Cgreen': switch color to green
 - '%Cblue': switch color to blue
@@ -132,6 +135,12 @@ The placeholders are:
 - '%n': newline
 - '%x00': print a byte from a hex code
 
+NOTE: Some placeholders may depend on other options given to the
+revision traversal engine. For example, the `%g*` reflog options will
+insert an empty string unless we are traversing reflog entries (e.g., by
+`git log -g`). The `%d` placeholder will use the "short" decoration
+format if `--decorate` was not already provided on the command line.
+
 * 'tformat:'
 +
 The 'tformat:' format works exactly like 'format:', except that it
diff --git a/commit.h b/commit.h
index 084cf55..422f778 100644
--- a/commit.h
+++ b/commit.h
@@ -70,6 +70,7 @@ struct pretty_print_context
 	const char *after_subject;
 	enum date_mode date_mode;
 	int need_8bit_cte;
+	struct reflog_walk_info *reflog_info;
 };
 
 extern int non_ascii(int);
diff --git a/log-tree.c b/log-tree.c
index 1675035..0fdf159 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -411,6 +411,7 @@ void show_log(struct rev_info *opt)
 	ctx.date_mode = opt->date_mode;
 	ctx.abbrev = opt->diffopt.abbrev;
 	ctx.after_subject = extra_headers;
+	ctx.reflog_info = opt->reflog_info;
 	pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);
 
 	if (opt->add_signoff)
diff --git a/pretty.c b/pretty.c
index 37ad6eb..da15cf2 100644
--- a/pretty.c
+++ b/pretty.c
@@ -7,6 +7,7 @@
 #include "mailmap.h"
 #include "log-tree.h"
 #include "color.h"
+#include "reflog-walk.h"
 
 static char *user_format;
 
@@ -701,6 +702,22 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 	case 'd':
 		format_decoration(sb, commit);
 		return 1;
+	case 'g':		/* reflog info */
+		switch(placeholder[1]) {
+		case 'd':	/* reflog selector */
+		case 'D':
+			if (c->pretty_ctx->reflog_info)
+				get_reflog_selector(sb,
+						    c->pretty_ctx->reflog_info,
+						    c->pretty_ctx->date_mode,
+						    (placeholder[1] == 'd'));
+			return 2;
+		case 's':	/* reflog message */
+			if (c->pretty_ctx->reflog_info)
+				get_reflog_message(sb, c->pretty_ctx->reflog_info);
+			return 2;
+		}
+		return 0;	/* unknown %g placeholder */
 	}
 
 	/* For the rest we have to parse the commit header. */
diff --git a/reflog-walk.c b/reflog-walk.c
index 596bafe..caba4f7 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -8,6 +8,7 @@
 
 struct complete_reflogs {
 	char *ref;
+	const char *short_ref;
 	struct reflog_info {
 		unsigned char osha1[20], nsha1[20];
 		char *email;
@@ -243,15 +244,26 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
 
 void get_reflog_selector(struct strbuf *sb,
 			 struct reflog_walk_info *reflog_info,
-			 enum date_mode dmode)
+			 enum date_mode dmode,
+			 int shorten)
 {
 	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
 	struct reflog_info *info;
+	const char *printed_ref;
 
 	if (!commit_reflog)
 		return;
 
-	strbuf_addf(sb, "%s@{", commit_reflog->reflogs->ref);
+	if (shorten) {
+		if (!commit_reflog->reflogs->short_ref)
+			commit_reflog->reflogs->short_ref
+				= shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);
+		printed_ref = commit_reflog->reflogs->short_ref;
+	} else {
+		printed_ref = commit_reflog->reflogs->ref;
+	}
+
+	strbuf_addf(sb, "%s@{", printed_ref);
 	if (commit_reflog->flag || dmode) {
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
 		strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));
@@ -263,6 +275,23 @@ void get_reflog_selector(struct strbuf *sb,
 	strbuf_addch(sb, '}');
 }
 
+void get_reflog_message(struct strbuf *sb,
+			struct reflog_walk_info *reflog_info)
+{
+	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+	struct reflog_info *info;
+	size_t len;
+
+	if (!commit_reflog)
+		return;
+
+	info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+	len = strlen(info->message);
+	if (len > 0)
+		len--; /* strip away trailing newline */
+	strbuf_add(sb, info->message, len);
+}
+
 void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 	enum date_mode dmode)
 {
@@ -272,7 +301,7 @@ void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 		struct strbuf selector = STRBUF_INIT;
 
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
-		get_reflog_selector(&selector, reflog_info, dmode);
+		get_reflog_selector(&selector, reflog_info, dmode, 0);
 		if (oneline) {
 			printf("%s: %s", selector.buf, info->message);
 		}
diff --git a/reflog-walk.h b/reflog-walk.h
index 74c9096..7bd2cd4 100644
--- a/reflog-walk.h
+++ b/reflog-walk.h
@@ -3,6 +3,8 @@
 
 #include "cache.h"
 
+struct reflog_walk_info;
+
 extern void init_reflog_walk(struct reflog_walk_info** info);
 extern int add_reflog_for_walk(struct reflog_walk_info *info,
 		struct commit *commit, const char *name);
@@ -10,5 +12,11 @@ extern void fake_reflog_parent(struct reflog_walk_info *info,
 		struct commit *commit);
 extern void show_reflog_message(struct reflog_walk_info *info, int,
 		enum date_mode);
+extern void get_reflog_message(struct strbuf *sb,
+		struct reflog_walk_info *reflog_info);
+extern void get_reflog_selector(struct strbuf *sb,
+		struct reflog_walk_info *reflog_info,
+		enum date_mode dmode,
+		int shorten);
 
 #endif
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index 59d1f62..7f61ab0 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -162,4 +162,22 @@ test_expect_success 'empty email' '
 	}
 '
 
+test_expect_success '"%h %gD: %gs" is same as git-reflog' '
+	git reflog >expect &&
+	git log -g --format="%h %gD: %gs" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '"%h %gD: %gs" is same as git-reflog (with date)' '
+	git reflog --date=raw >expect &&
+	git log -g --format="%h %gD: %gs" --date=raw >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '%gd shortens ref name' '
+	echo "master@{0}" >expect.gd-short &&
+	git log -g -1 --format=%gd refs/heads/master >actual.gd-short &&
+	test_cmp expect.gd-short actual.gd-short
+'
+
 test_done
-- 
1.6.5.1.137.gefbc6

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v4 4/5] stash list: use new %g formats instead of sed
  2009-10-19 15:48                         ` [PATCH v4 0/5] Pretty formats for reflog data Thomas Rast
                                             ` (2 preceding siblings ...)
  2009-10-19 15:48                           ` [PATCH v4 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
@ 2009-10-19 15:48                           ` Thomas Rast
  2009-10-19 15:48                           ` [PATCH v4 5/5] stash list: drop the default limit of 10 stashes Thomas Rast
  4 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-19 15:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git

With the new formats, we can rewrite 'git stash list' in terms of an
appropriate pretty format, instead of hand-editing with sed.  This has
the advantage that it obeys the normal settings for git-log, notably
the pager.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-stash.sh |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index 4febbbf..f8847c1 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -205,8 +205,7 @@ have_stash () {
 
 list_stash () {
 	have_stash || return 0
-	git log --no-color --pretty=oneline -g "$@" $ref_stash -- |
-	sed -n -e 's/^[.0-9a-f]* refs\///p'
+	git log --format="%gd: %gs" -g "$@" $ref_stash --
 }
 
 show_stash () {
-- 
1.6.5.1.137.gefbc6

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v4 5/5] stash list: drop the default limit of 10 stashes
  2009-10-19 15:48                         ` [PATCH v4 0/5] Pretty formats for reflog data Thomas Rast
                                             ` (3 preceding siblings ...)
  2009-10-19 15:48                           ` [PATCH v4 4/5] stash list: use new %g formats instead of sed Thomas Rast
@ 2009-10-19 15:48                           ` Thomas Rast
  4 siblings, 0 replies; 49+ messages in thread
From: Thomas Rast @ 2009-10-19 15:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git

'git stash list' had an undocumented limit of 10 stashes, unless other
git-log arguments were specified.  This surprised at least one user,
but possibly served to cut the output below a screenful without using
a pager.

Since the last commit, 'git stash list' will fire up a pager according
to the same rules as the 'git log' it calls, so we can drop the limit.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/git-stash.txt |    3 +--
 git-stash.sh                |    5 -----
 2 files changed, 1 insertions(+), 7 deletions(-)

diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index fafe728..3f14b72 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -78,8 +78,7 @@ stash@{1}: On master: 9cc0589... Add git-stash
 ----------------------------------------------------------------
 +
 The command takes options applicable to the 'git-log'
-command to control what is shown and how. If no options are set, the
-default is `-n 10`. See linkgit:git-log[1].
+command to control what is shown and how. See linkgit:git-log[1].
 
 show [<stash>]::
 
diff --git a/git-stash.sh b/git-stash.sh
index f8847c1..f796c2f 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -382,11 +382,6 @@ test -n "$seen_non_option" || set "save" "$@"
 case "$1" in
 list)
 	shift
-	if test $# = 0
-	then
-		set x -n 10
-		shift
-	fi
 	list_stash "$@"
 	;;
 show)
-- 
1.6.5.1.137.gefbc6

^ permalink raw reply related	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2009-10-19 15:49 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-12 15:47 git stash list with more than 10 items? Jef Driesen
2009-10-12 17:52 ` Jeff King
2009-10-12 19:37   ` [PATCH] git-stash documentation: mention default options for 'list' Miklos Vajna
2009-10-12 19:39     ` Jeff King
2009-10-12 21:06   ` [RFC PATCH 0/5] Pretty formats for reflog data Thomas Rast
2009-10-12 21:06     ` [RFC PATCH 1/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
2009-10-12 21:06     ` [RFC PATCH 2/5] Introduce new pretty formats %g and %G for reflog information Thomas Rast
2009-10-14  4:59       ` Jeff King
2009-10-14  9:58         ` Thomas Rast
2009-10-14  9:13       ` Junio C Hamano
2009-10-12 21:06     ` [RFC PATCH 3/5] stash: Use new %g/%G formats instead of sed Thomas Rast
2009-10-14  5:00       ` Jeff King
2009-10-12 21:06     ` [RFC PATCH 4/5] stash list: drop the default limit of 10 stashes Thomas Rast
2009-10-14  5:02       ` Jeff King
2009-10-12 21:06     ` [RFC PATCH 5/5] stash: change built-in ref to 'stash' instead of 'refs/stash' Thomas Rast
2009-10-14  5:06       ` Jeff King
2009-10-15 22:41         ` [PATCH v2 0/5] Pretty formats for reflog data Thomas Rast
2009-10-15 22:41           ` [PATCH v2 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
2009-10-15 22:41           ` [PATCH v2 2/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
2009-10-15 22:41           ` [PATCH v2 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
2009-10-16  5:32             ` Jeff King
2009-10-16  8:50               ` Thomas Rast
2009-10-16 14:20               ` [PATCH v3 0/5] Pretty formats for reflog data Thomas Rast
2009-10-16 14:20                 ` [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
2009-10-17 17:05                   ` Junio C Hamano
2009-10-18 18:51                     ` Thomas Rast
2009-10-18 22:47                       ` Junio C Hamano
2009-10-19 15:48                         ` [PATCH v4 0/5] Pretty formats for reflog data Thomas Rast
2009-10-19 15:48                           ` [PATCH v4 1/5] Refactor pretty_print_commit arguments into a struct Thomas Rast
2009-10-19 15:48                           ` [PATCH v4 2/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
2009-10-19 15:48                           ` [PATCH v4 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
2009-10-19 15:48                           ` [PATCH v4 4/5] stash list: use new %g formats instead of sed Thomas Rast
2009-10-19 15:48                           ` [PATCH v4 5/5] stash list: drop the default limit of 10 stashes Thomas Rast
2009-10-16 14:20                 ` [PATCH v3 2/5] reflog-walk: refactor the branch@{num} formatting Thomas Rast
2009-10-16 14:20                 ` [PATCH v3 3/5] Introduce new pretty formats %g[sdD] for reflog information Thomas Rast
2009-10-17 14:48                   ` [PATCH v3.1 " Thomas Rast
2009-10-17 15:06                     ` Jakub Narebski
2009-10-18  7:18                     ` Jeff King
2009-10-18 10:34                       ` Nanako Shiraishi
2009-10-16 14:20                 ` [PATCH v3 4/5] stash list: use new %g formats instead of sed Thomas Rast
2009-10-16 14:20                 ` [PATCH v3 5/5] stash list: drop the default limit of 10 stashes Thomas Rast
2009-10-17  0:50                 ` [PATCH v3 0/5] Pretty formats for reflog data Junio C Hamano
2009-10-17  1:18                 ` Jeff King
2009-10-15 22:41           ` [PATCH v2 4/5] stash list: use new %g formats instead of sed Thomas Rast
2009-10-15 22:41           ` [PATCH v2 5/5] stash list: drop the default limit of 10 stashes Thomas Rast
2009-10-16  5:20           ` [PATCH v2 0/5] Pretty formats for reflog data Jeff King
2009-10-16  9:00             ` Jakub Narebski
2009-10-12 21:37     ` [RFC PATCH " Jeff King
2009-10-12 21:52       ` Thomas Rast

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.