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

[PATCH] pretty: add format specifiers: %gr, %gt, %gI, gi

From
Theodore Ts'o <tytso@mit.edu>
Date
Jul 10, 2016, 05:54 UTC
Message-ID
<20160710055402.32684-1-tytso@mit.edu>

Add new format specifiers which allow the printing of reflog timestamp. This allows us to know when operations which change HEAD take place (e.g., guilt pop -a, which does the equivalent of a "git reset --hard commit"), since using %cr will display when the commit was originally made, instead of when HEAD was moved to that commit.

This allows something like:
git log -g --pretty=format:'%Cred%h%Creset %gd %gs %Cgreen(%gr)%Creset %s' --abbrev-commit

to provide what (for me) is a much more useful "git reflog" type of report.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
 Documentation/pretty-formats.txt |  4 ++++
 cache.h                          |  1 +
 date.c                           |  2 +-
 pretty.c                         | 18 ++++++++++++++++
 reflog-walk.c                    | 45 ++++++++++++++++++++++++++++++----------
 reflog-walk.h                    |  3 +++
 6 files changed, 61 insertions(+), 12 deletions(-)
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 29b19b9..7927754 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -156,6 +156,10 @@ endif::git-rev-list[]
 - '%gE': reflog identity email (respecting .mailmap, see
   linkgit:git-shortlog[1] or linkgit:git-blame[1])
 - '%gs': reflog subject
+- '%gr': reflog date, relative
+- '%gt': reflog date, UNIX timestamp
+- '%gi': reflog date, ISO 8601-like format
+- '%gI': reflog date, strict ISO 8601 format
 - '%Cred': switch color to red
 - '%Cgreen': switch color to green
 - '%Cblue': switch color to blue
diff --git a/cache.h b/cache.h
index f1dc289..5dd2805 100644
--- a/cache.h
+++ b/cache.h
@@ -1237,6 +1237,7 @@ struct date_mode {
 #define DATE_MODE(t) date_mode_from_type(DATE_##t)
 struct date_mode *date_mode_from_type(enum date_mode_type type);
 
+time_t gm_time_t(unsigned long time, int tz);
 const char *show_date(unsigned long time, int timezone, const struct date_mode *mode);
 void show_date_relative(unsigned long time, int tz, const struct timeval *now,
 			struct strbuf *timebuf);
diff --git a/date.c b/date.c
index 4c7aa9b..f98502e 100644
--- a/date.c
+++ b/date.c
@@ -39,7 +39,7 @@ static const char *weekday_names[] = {
 	"Sundays", "Mondays", "Tuesdays", "Wednesdays", "Thursdays", "Fridays", "Saturdays"
 };
 
-static time_t gm_time_t(unsigned long time, int tz)
+time_t gm_time_t(unsigned long time, int tz)
 {
 	int minutes;
 
diff --git a/pretty.c b/pretty.c
index 330a5e0..eb1f44e 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1212,6 +1212,24 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
 						    placeholder[1],
 						    c->pretty_ctx->reflog_info,
 						    &c->pretty_ctx->date_mode);
+		case 'r':	/* date, relative */
+			strbuf_addstr(sb,
+				show_reflog_date(c->pretty_ctx->reflog_info,
+					DATE_MODE(RELATIVE)));
+			return 2;
+		case 'i':	/* date, ISO 8601-like */
+			strbuf_addstr(sb,
+				show_reflog_date(c->pretty_ctx->reflog_info,
+					DATE_MODE(ISO8601)));
+			return 2;
+		case 'I':	/* date, ISO 8601 strict */
+			strbuf_addstr(sb,
+				show_reflog_date(c->pretty_ctx->reflog_info,
+					DATE_MODE(ISO8601_STRICT)));
+			return 2;
+		case 't':
+			strbuf_addf(sb, "%lu", get_reflog_time_t(c->pretty_ctx->reflog_info));
+			return 2;
 		}
 		return 0;	/* unknown %g placeholder */
 	case 'N':
diff --git a/reflog-walk.c b/reflog-walk.c
index a246af2..d0aa2d0 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -292,17 +292,24 @@ void get_reflog_selector(struct strbuf *sb,
 	strbuf_addch(sb, '}');
 }
 
-void get_reflog_message(struct strbuf *sb,
-			struct reflog_walk_info *reflog_info)
+static struct reflog_info *get_reflog_info(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;
+		return NULL;
+
+	return &commit_reflog->reflogs->items[commit_reflog->recno+1];
+}
 
-	info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+void get_reflog_message(struct strbuf *sb,
+			struct reflog_walk_info *reflog_info)
+{
+	struct reflog_info *info = get_reflog_info(reflog_info);
+	size_t len;
+
+	if (!info)
+		return NULL;
 	len = strlen(info->message);
 	if (len > 0)
 		len--; /* strip away trailing newline */
@@ -311,16 +318,32 @@ void get_reflog_message(struct strbuf *sb,
 
 const char *get_reflog_ident(struct reflog_walk_info *reflog_info)
 {
-	struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
-	struct reflog_info *info;
+	struct reflog_info *info = get_reflog_info(reflog_info);
 
-	if (!commit_reflog)
+	if (!info)
 		return NULL;
-
-	info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
 	return info->email;
 }
 
+unsigned long get_reflog_time_t(struct reflog_walk_info *reflog_info)
+{
+	struct reflog_info *info = get_reflog_info(reflog_info);
+
+	if (!info)
+		return NULL;
+	return gm_time_t(info->timestamp, info->tz);
+}
+
+const char *show_reflog_date(struct reflog_walk_info *reflog_info,
+			     const struct date_mode *mode)
+{
+	struct reflog_info *info = get_reflog_info(reflog_info);
+
+	if (!info)
+		return NULL;
+	return show_date(info->timestamp, info->tz, mode);
+}
+
 void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 			 const struct date_mode *dmode, int force_date)
 {
diff --git a/reflog-walk.h b/reflog-walk.h
index 27886f7..aaccc58 100644
--- a/reflog-walk.h
+++ b/reflog-walk.h
@@ -15,6 +15,9 @@ extern void show_reflog_message(struct reflog_walk_info *info, int,
 extern void get_reflog_message(struct strbuf *sb,
 		struct reflog_walk_info *reflog_info);
 extern const char *get_reflog_ident(struct reflog_walk_info *reflog_info);
+extern unsigned long get_reflog_time_t(struct reflog_walk_info *reflog_info);
+extern const char *show_reflog_date(struct reflog_walk_info *reflog_info,
+				    const struct date_mode *mode);
 extern void get_reflog_selector(struct strbuf *sb,
 		struct reflog_walk_info *reflog_info,
 		const struct date_mode *dmode, int force_date,
-- 
2.9.0.243.g5c589a7.dirty
Next: Jeff King
Message 1 of 18 in “pretty: add format specifiers: %gr, %gt, %gI, gi”
  1. pretty: add format specifiers: %gr, %gt, %gI, giTheodore Ts'o, Jul 10, 2016
  2. Jeff KingJul 10, 2016
  3. Theodore Ts'oJul 10, 2016
  4. Duy NguyenJul 10, 2016
  5. Theodore Ts'oJul 10, 2016
  6. Jeff KingJul 11, 2016
  7. 1/5 doc/rev-list-options: clarify "commit@{Nth}" for "-g" optionJeff King, Jul 11, 2016
  8. 2/5 doc/rev-list-options: explain "-g" output formatsJeff King, Jul 11, 2016
  9. 3/5 doc/pretty-formats: describe index/time formats for %gdJeff King, Jul 11, 2016
  10. Theodore Ts'oJul 11, 2016
  11. Jeff KingJul 12, 2016
  12. Junio C HamanoJul 12, 2016
  13. 4/5 date: document and test "raw-local" modeJeff King, Jul 11, 2016
  14. Theodore Ts'oJul 11, 2016
  15. Jeff KingJul 12, 2016
  16. 5/5 date: add "unix" formatJeff King, Jul 11, 2016
  17. Theodore Ts'oJul 11, 2016
  18. Junio C HamanoJul 11, 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.