git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] pretty format string support for reflog times

From
Phil Pennock <phil@pennock-tech.com>
Date
Jul 27, 2016, 08:14 UTC
Message-ID
<20160727081414.GA21451@breadbox>

The reflog contains timestamp information, but these were not exposed to `--pretty`. Four of the six author/committer format string second-letters were still available and copied, but `d`/`D` are taken for reflog selector formatting. So use `%gT` for "time" instead of "date" mnemonic for using `--date=...` formatting.

Implementation trade-off: could use `format_person_part()` if bounce information out of the reflog as a buffer-constructed string, then parse it back again, _and_ then use a hacky letter override for 'T' becoming 'd'. That would avoid reimplementing the specification of the five added timestamp rendering cases. Instead, we allow exporting the timestamp information from the reflog, and if we get it, we add the same data. No memory alloc and string construction/parsing, a small amount of duplication of meaning.

Signed-off-by: Phil Pennock <phil@pennock-tech.com>
---
 pretty.c                      | 36 ++++++++++++++++++++++++++++++++++++
 reflog-walk.c                 | 16 ++++++++++++++++
 reflog-walk.h                 |  3 +++
 t/t4205-log-pretty-formats.sh | 26 ++++++++++++++++++++++++++
 4 files changed, 81 insertions(+)
diff --git a/pretty.c b/pretty.c
index 9fa42c2..955baf1 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1066,6 +1066,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
 	const char *msg = c->message;
 	struct commit_list *p;
 	int h1, h2;
+	unsigned long timestamp;
+	int tz;
 
 	/* these are independent of the commit */
 	switch (placeholder[0]) {
@@ -1212,6 +1214,40 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
 						    placeholder[1],
 						    c->pretty_ctx->reflog_info,
 						    &c->pretty_ctx->date_mode);
+		/*
+		 * all the date options except those taken for other reflog handling
+		 * (so not 'd' or 'D').
+		 */
+		case 'r':
+			if (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {
+				strbuf_addstr(sb, show_date(timestamp, tz, DATE_MODE(RELATIVE)));
+			}
+			return 2;
+		case 't':
+			if (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {
+				strbuf_addf(sb, "%lu", timestamp);
+			}
+			return 2;
+		case 'i':
+			if (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {
+				strbuf_addstr(sb, show_date(timestamp, tz, DATE_MODE(ISO8601)));
+			}
+			return 2;
+		case 'I':
+			if (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {
+				strbuf_addstr(sb, show_date(timestamp, tz, DATE_MODE(ISO8601_STRICT)));
+			}
+			return 2;
+		/*
+		 * reflog d/D are taken, so we can't use those for dates
+		 * but we do want to support using --date= format overrides
+		 * so we steal 'T' for those ('time' instead of 'date')
+		 */
+		case 'T':
+			if (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {
+				strbuf_addstr(sb, show_date(timestamp, tz, &c->pretty_ctx->date_mode));
+			}
+			return 2;
 		}
 		return 0;	/* unknown %g placeholder */
 	case 'N':
diff --git a/reflog-walk.c b/reflog-walk.c
index a246af2..bb9cbf8 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -309,6 +309,22 @@ void get_reflog_message(struct strbuf *sb,
 	strbuf_add(sb, info->message, len);
 }
 
+int get_reflog_timeinfo(unsigned long *timestamp_out,
+			 int *tz_out,
+			 struct reflog_walk_info *reflog_info)
+{
+	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+	struct reflog_info *info;
+
+	if (!commit_reflog)
+		return 0;
+
+	info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+	*timestamp_out = info->timestamp;
+	*tz_out = info->tz;
+	return 1;
+}
+
 const char *get_reflog_ident(struct reflog_walk_info *reflog_info)
 {
 	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
diff --git a/reflog-walk.h b/reflog-walk.h
index 27886f7..a368c72 100644
--- a/reflog-walk.h
+++ b/reflog-walk.h
@@ -19,5 +19,8 @@ extern void get_reflog_selector(struct strbuf *sb,
 		struct reflog_walk_info *reflog_info,
 		const struct date_mode *dmode, int force_date,
 		int shorten);
+extern int get_reflog_timeinfo(unsigned long *timestamp_out,
+		int *tz_out,
+		struct reflog_walk_info *reflog_info);
 
 #endif
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index d9f6242..9d211ab 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -533,4 +533,30 @@ EOF
 	test_cmp expected actual1
 '
 
+refhead1_short=$(git rev-parse --short --verify HEAD@{0}) &&
+refhead2_short=$(git rev-parse --short --verify HEAD@{1}) &&
+
+test_expect_success 'can access the reflog' '
+	git reflog -n 2 >actual &&
+	cat >expected <<EOF &&
+$refhead1_short HEAD@{0}: commit (amend): shorter
+$refhead2_short HEAD@{1}: commit (amend): short
+EOF
+	test_cmp expected actual
+'
+
+test_expect_success 'reflog tformat timestamps work' '
+	git log -g -n 2 \
+		--pretty=tformat:"%h %gd / %gr %gt%n %gi %gI%n %gT : %gs" > actual &&
+	cat >expected <<EOF &&
+$refhead1_short HEAD@{0} / 11 years ago 1112912173
+ 2005-04-07 15:16:13 -0700 2005-04-07T15:16:13-07:00
+ Thu Apr 7 15:16:13 2005 -0700 : commit (amend): shorter
+$refhead2_short HEAD@{1} / 11 years ago 1112912173
+ 2005-04-07 15:16:13 -0700 2005-04-07T15:16:13-07:00
+ Thu Apr 7 15:16:13 2005 -0700 : commit (amend): short
+EOF
+	test_cmp expected actual
+'
+
 test_done
-- 
2.9.2.466.g8c6d1f9.dirty
Next: Phil Pennock
Message 1 of 20 in “pretty format string support for reflog times”
  1. pretty format string support for reflog timesPhil Pennock, Jul 27, 2016
  2. Phil PennockJul 27, 2016
  3. Jeff KingJul 27, 2016
  4. Phil PennockJul 27, 2016
  5. Junio C HamanoJul 27, 2016
  6. Jeff KingJul 27, 2016
  7. Junio C HamanoJul 27, 2016
  8. Jeff KingJul 27, 2016
  9. Junio C HamanoJul 27, 2016
  10. Jeff KingJul 27, 2016
  11. Jeff KingJul 27, 2016
  12. Phil PennockJul 27, 2016
  13. Jeff KingJul 27, 2016
  14. 0/2 t4205 style fixesJeff King, Jul 27, 2016
  15. 1/2 t4205: drop top-level &&-chainingJeff King, Jul 27, 2016
  16. 2/2 t4205: indent here documentsJeff King, Jul 27, 2016
  17. Junio C HamanoJul 27, 2016
  18. Jeff KingJul 27, 2016
  19. Phil PennockJul 27, 2016
  20. Jeff KingJul 27, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.