{"thread":{"id":"42813","subject":"[PATCH] pretty: add format specifiers: %gr, %gt, %gI, gi","startedAt":"2016-07-10T05:54:18Z","lastAt":"2016-07-12T02:01:58Z","messageCount":18,"participants":["Theodore Ts'o","Jeff King","Duy Nguyen","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"291120","messageId":"20160710055402.32684-1-tytso@mit.edu","threadId":"42813","inReplyTo":null,"subject":"[PATCH] pretty: add format specifiers: %gr, %gt, %gI, gi","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2016-07-10T05:54:02Z","receivedAt":"2016-07-10T05:54:18Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"Add new format specifiers which allow the printing of reflog\ntimestamp.  This allows us to know when operations which change HEAD\ntake place (e.g., guilt pop -a, which does the equivalent of a \"git\nreset --hard commit\"), since using %cr will display when the commit\nwas originally made, instead of when HEAD was moved to that commit.\n\nThis allows something like:\n\ngit log -g --pretty=format:'%Cred%h%Creset %gd %gs %Cgreen(%gr)%Creset %s' --abbrev-commit\n\nto provide what (for me) is a much more useful \"git reflog\" type of\nreport.\n\nSigned-off-by: Theodore Ts'o <tytso@mit.edu>\n---\n Documentation/pretty-formats.txt |  4 ++++\n cache.h                          |  1 +\n date.c                           |  2 +-\n pretty.c                         | 18 ++++++++++++++++\n reflog-walk.c                    | 45 ++++++++++++++++++++++++++++++----------\n reflog-walk.h                    |  3 +++\n 6 files changed, 61 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 29b19b9..7927754 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -156,6 +156,10 @@ endif::git-rev-list[]\n - '%gE': reflog identity email (respecting .mailmap, see\n   linkgit:git-shortlog[1] or linkgit:git-blame[1])\n - '%gs': reflog subject\n+- '%gr': reflog date, relative\n+- '%gt': reflog date, UNIX timestamp\n+- '%gi': reflog date, ISO 8601-like format\n+- '%gI': reflog date, strict ISO 8601 format\n - '%Cred': switch color to red\n - '%Cgreen': switch color to green\n - '%Cblue': switch color to blue\ndiff --git a/cache.h b/cache.h\nindex f1dc289..5dd2805 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1237,6 +1237,7 @@ struct date_mode {\n #define DATE_MODE(t) date_mode_from_type(DATE_##t)\n struct date_mode *date_mode_from_type(enum date_mode_type type);\n \n+time_t gm_time_t(unsigned long time, int tz);\n const char *show_date(unsigned long time, int timezone, const struct date_mode *mode);\n void show_date_relative(unsigned long time, int tz, const struct timeval *now,\n \t\t\tstruct strbuf *timebuf);\ndiff --git a/date.c b/date.c\nindex 4c7aa9b..f98502e 100644\n--- a/date.c\n+++ b/date.c\n@@ -39,7 +39,7 @@ static const char *weekday_names[] = {\n \t\"Sundays\", \"Mondays\", \"Tuesdays\", \"Wednesdays\", \"Thursdays\", \"Fridays\", \"Saturdays\"\n };\n \n-static time_t gm_time_t(unsigned long time, int tz)\n+time_t gm_time_t(unsigned long time, int tz)\n {\n \tint minutes;\n \ndiff --git a/pretty.c b/pretty.c\nindex 330a5e0..eb1f44e 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -1212,6 +1212,24 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */\n \t\t\t\t\t\t    placeholder[1],\n \t\t\t\t\t\t    c->pretty_ctx->reflog_info,\n \t\t\t\t\t\t    &c->pretty_ctx->date_mode);\n+\t\tcase 'r':\t/* date, relative */\n+\t\t\tstrbuf_addstr(sb,\n+\t\t\t\tshow_reflog_date(c->pretty_ctx->reflog_info,\n+\t\t\t\t\tDATE_MODE(RELATIVE)));\n+\t\t\treturn 2;\n+\t\tcase 'i':\t/* date, ISO 8601-like */\n+\t\t\tstrbuf_addstr(sb,\n+\t\t\t\tshow_reflog_date(c->pretty_ctx->reflog_info,\n+\t\t\t\t\tDATE_MODE(ISO8601)));\n+\t\t\treturn 2;\n+\t\tcase 'I':\t/* date, ISO 8601 strict */\n+\t\t\tstrbuf_addstr(sb,\n+\t\t\t\tshow_reflog_date(c->pretty_ctx->reflog_info,\n+\t\t\t\t\tDATE_MODE(ISO8601_STRICT)));\n+\t\t\treturn 2;\n+\t\tcase 't':\n+\t\t\tstrbuf_addf(sb, \"%lu\", get_reflog_time_t(c->pretty_ctx->reflog_info));\n+\t\t\treturn 2;\n \t\t}\n \t\treturn 0;\t/* unknown %g placeholder */\n \tcase 'N':\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex a246af2..d0aa2d0 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -292,17 +292,24 @@ void get_reflog_selector(struct strbuf *sb,\n \tstrbuf_addch(sb, '}');\n }\n \n-void get_reflog_message(struct strbuf *sb,\n-\t\t\tstruct reflog_walk_info *reflog_info)\n+static struct reflog_info *get_reflog_info(struct reflog_walk_info *reflog_info)\n {\n \tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n-\tstruct reflog_info *info;\n-\tsize_t len;\n \n \tif (!commit_reflog)\n-\t\treturn;\n+\t\treturn NULL;\n+\n+\treturn &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+}\n \n-\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+void get_reflog_message(struct strbuf *sb,\n+\t\t\tstruct reflog_walk_info *reflog_info)\n+{\n+\tstruct reflog_info *info = get_reflog_info(reflog_info);\n+\tsize_t len;\n+\n+\tif (!info)\n+\t\treturn NULL;\n \tlen = strlen(info->message);\n \tif (len > 0)\n \t\tlen--; /* strip away trailing newline */\n@@ -311,16 +318,32 @@ void get_reflog_message(struct strbuf *sb,\n \n const char *get_reflog_ident(struct reflog_walk_info *reflog_info)\n {\n-\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n-\tstruct reflog_info *info;\n+\tstruct reflog_info *info = get_reflog_info(reflog_info);\n \n-\tif (!commit_reflog)\n+\tif (!info)\n \t\treturn NULL;\n-\n-\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n \treturn info->email;\n }\n \n+unsigned long get_reflog_time_t(struct reflog_walk_info *reflog_info)\n+{\n+\tstruct reflog_info *info = get_reflog_info(reflog_info);\n+\n+\tif (!info)\n+\t\treturn NULL;\n+\treturn gm_time_t(info->timestamp, info->tz);\n+}\n+\n+const char *show_reflog_date(struct reflog_walk_info *reflog_info,\n+\t\t\t     const struct date_mode *mode)\n+{\n+\tstruct reflog_info *info = get_reflog_info(reflog_info);\n+\n+\tif (!info)\n+\t\treturn NULL;\n+\treturn show_date(info->timestamp, info->tz, mode);\n+}\n+\n void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,\n \t\t\t const struct date_mode *dmode, int force_date)\n {\ndiff --git a/reflog-walk.h b/reflog-walk.h\nindex 27886f7..aaccc58 100644\n--- a/reflog-walk.h\n+++ b/reflog-walk.h\n@@ -15,6 +15,9 @@ extern void show_reflog_message(struct reflog_walk_info *info, int,\n extern void get_reflog_message(struct strbuf *sb,\n \t\tstruct reflog_walk_info *reflog_info);\n extern const char *get_reflog_ident(struct reflog_walk_info *reflog_info);\n+extern unsigned long get_reflog_time_t(struct reflog_walk_info *reflog_info);\n+extern const char *show_reflog_date(struct reflog_walk_info *reflog_info,\n+\t\t\t\t    const struct date_mode *mode);\n extern void get_reflog_selector(struct strbuf *sb,\n \t\tstruct reflog_walk_info *reflog_info,\n \t\tconst struct date_mode *dmode, int force_date,\n-- \n2.9.0.243.g5c589a7.dirty\n\n"},{"id":"291121","messageId":"20160710061644.GA19640@sigill.intra.peff.net","threadId":"42813","inReplyTo":"20160710055402.32684-1-tytso@mit.edu","subject":"Re: [PATCH] pretty: add format specifiers: %gr, %gt, %gI, gi","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-10T06:16:45Z","receivedAt":"2016-07-10T06:20:11Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Jul 10, 2016 at 01:54:02AM -0400, Theodore Ts'o wrote:\n\n> Add new format specifiers which allow the printing of reflog\n> timestamp.  This allows us to know when operations which change HEAD\n> take place (e.g., guilt pop -a, which does the equivalent of a \"git\n> reset --hard commit\"), since using %cr will display when the commit\n> was originally made, instead of when HEAD was moved to that commit.\n\nHrm. You can already get dates like:\n\n  git log --date=relative -g --format=%gd\n\n(or --date=iso, or whatever). But:\n\n  1. It's always branch@{...date...}, not just ...date...\n\n  2. It takes over %gd, so this:\n\n> git log -g --pretty=format:'%Cred%h%Creset %gd %gs %Cgreen(%gr)%Creset %s' --abbrev-commit\n\ncan't be done (you cannot show both HEAD@{0} and \"5 minutes ago\").\n\nSo the status quo definitely isn't as flexible as it could be. I'm just\nnot excited about adding a bunch more obscure two-character codes that\ndon't even cover all of the possible date formats (I know we have the\nsame problem for the author/committer timestamps, but we are stuck with\nthose for historical reasons).\n\nI wonder if a better approach would be:\n\n  1. In the short term, add specific designators for the fields you'd\n     want. One for HEAD@{n} that is unaffected by date, as %gd is (or\n     even one for the branch-name and one for \"n\"). And one for the\n     reflog date, by itself, in whatever format --date= asked for.\n\n     That would let you do your format above, though it does not let you\n     show the reflog date in multiple formats.\n\n  2. In the long term, teach log's pretty formatter to handle less\n     obscure syntax, that can include arguments. The pretty-printer in\n     for-each-ref can already do \"%(authordate:relative)\", and accepts\n     any date-format that git knows about. We should do the same here.\n\nI dunno. Your patch does not make either of those paths _harder_, and it\nis not like there isn't precedent. It just bloats the user-visible\ninterface with stuff that would later become redundant (but that we\ncan't get rid of because of backwards compatibility).\n\n-Peff\n"},{"id":"291137","messageId":"20160710142622.GE26097@thunk.org","threadId":"42813","inReplyTo":"20160710061644.GA19640@sigill.intra.peff.net","subject":"Re: [PATCH] pretty: add format specifiers: %gr, %gt, %gI, gi","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2016-07-10T14:26:22Z","receivedAt":"2016-07-10T14:26:30Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Sun, Jul 10, 2016 at 02:16:45AM -0400, Jeff King wrote:\n> I wonder if a better approach would be:\n> \n>   1. In the short term, add specific designators for the fields you'd\n>      want. One for HEAD@{n} that is unaffected by date, as %gd is (or\n>      even one for the branch-name and one for \"n\"). And one for the\n>      reflog date, by itself, in whatever format --date= asked for.\n> \n>      That would let you do your format above, though it does not let you\n>      show the reflog date in multiple formats.\n\nHrm, maybe.  I didn't realize that %gd and %gD displayed something\nvery different if --date is specified.  Is this documented?  I looked\neverywhere, and the closest I could find is a mention in the\ndescription of -g that if you specify commit@{now}, the output will\nuse commit@{timestamp} notation --- but that's different from\n--date=xxx, and it doesn't actually specify which pretty-printer\nformat string this affects, although I suppose that's not that hard to\ninfer.\n\nOne other thing I'll note in passing is that the --date notation\ndoesn't support Unix timestamps.  So you can't actually do the\nequivalent of %gt as proposed in this patch.\n\nI'm not sure what designators we'd use for a HEAD@{n} that is\nuneffected by date, and as far as which arbitrary two-letter code for\n\"reflog date in the default date format\", we can't use %gd (ala %ad or\n%cd), since it's already spoken for.  %gr, %gt, etc., at least have\nthe advantage that they are somewhat orthogonal to %ar/%at, %cr/%ct,\netc.\n\nSo I definitely understand the concern about the PP format string\nbeing somewhat creaky, and obscure.  It's not entirely clearly to me\nthat adding the new designators actually doesn't add more bloat or\nnon-orthogonality.  I suppose we could add %gb for branch name, and\n%gU for the HEAD@{n} nUm --- since %gn and %gN are already spoken for\n--- and then use %gt for the reflog date in the default date format.\nSo that only adds three new two-letter formats, instead of the four in\nmy patch.\n\n(BTW, I really only care about %gt and %gr --- so if the concern is\nbloat, we could just add those two specifiers.  I just added %gi and\n%gI because it wasn't hard, and I thought orthoganlity was better\nwhere it was possible.)\n\n>   2. In the long term, teach log's pretty formatter to handle less\n>      obscure syntax, that can include arguments. The pretty-printer in\n>      for-each-ref can already do \"%(authordate:relative)\", and accepts\n>      any date-format that git knows about. We should do the same here.\n\nSee the above comment about our currently not supporting Unix time as\none of the date-formats.  So if the goal was to make the proposed new\npretty formatter be a superset of the percent expansion rules, there\nisn't really a clean way of doing %at.\n\nOne possibility is %{authordate:format:%s} --- but it suffers from two\ndrawbacks:\n\n(a) It's kind of ugly/obscure, since it gets us back to using\nnot-so-human-friendly percent expansions.\n\n(b) It's not portable, since apparently %s isn't one of the strftime\nformats which is guaranteed by the Single Unix Specification or the\nC99 standard.  (Maybe it is implemented in all of the platforms we\ncare about (e.g., Windows, MacOS, etc.), though.)\n\n\nOne other long-term thought.  Maybe past a certain point, we should\njust make it easy to get the data from git-log into a perl or pythons\nscript, where it becomes possible to do conditionals, more flexible\npadding rules, etc.  So some kind of --format=yaml or --format=json\nsort of thing.  Some interesting ideas of how we could do this can be\nfound here:\n\n\thttps://cloud.google.com/sdk/gcloud/reference/topic/formats\n\n... although I doubt whether git would ever want to do the equivalent of:\n\ngcloud compute images list  --format='table[box,title=Images](name:sort=1,family)'\n\nwhich will print something like this:\n\n+------------------------------------------------------------+\n|                           Images                           |\n+------------------------------------------+-----------------+\n|                   NAME                   |      FAMILY     |\n+------------------------------------------+-----------------+\n| centos-6-v20160629                       | centos-6        |\n| centos-7-v20160629                       | centos-7        |\n| coreos-alpha-1097-0-0-v20160702          | coreos-alpha    |\n| coreos-beta-1068-3-0-v20160627           | coreos-beta     |\n| coreos-stable-1010-6-0-v20160628         | coreos-stable   |\n| debian-8-jessie-v20160629                | debian-8        |\n| freebsd-101-release-amd64-20150101032704 |                 |\n| opensuse-13-2-v20160222                  |                 |\n| opensuse-leap-42-1-v20160302             |                 |\n| rhel-6-v20160629                         | rhel-6          |\n| rhel-7-v20160629                         | rhel-7          |\n| sles-11-sp4-v20160301                    |                 |\n| sles-12-sp1-v20160301                    |                 |\n| ubuntu-1204-precise-v20160627            | ubuntu-1204-lts |\n| ubuntu-1404-trusty-v20160627             | ubuntu-1404-lts |\n| ubuntu-1510-wily-v20160627               | ubuntu-1510     |\n| ubuntu-1604-xenial-v20160627             | ubuntu-1604-lts |\n| windows-server-2008-r2-dc-v20160623      | windows-2008-r2 |\n| windows-server-2012-r2-dc-v20160623      | windows-2012-r2 |\n| xfstests-201607030209                    | xfstests        |\n+------------------------------------------+-----------------+\n\nand will even use fancy graphics characters if you're using a terminal\nwhich supports them.  :-)\n\n\t\t\t\t\t\t- Ted\n\n"},{"id":"291142","messageId":"CACsJy8CSqjTztFu1fOXqyS1jXjt=D_pgAC4MXpnECAcu+dRu2w@mail.gmail.com","threadId":"42813","inReplyTo":"20160710142622.GE26097@thunk.org","subject":"Re: [PATCH] pretty: add format specifiers: %gr, %gt, %gI, gi","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-07-10T16:05:31Z","receivedAt":"2016-07-10T16:06:08Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sun, Jul 10, 2016 at 4:26 PM, Theodore Ts'o <tytso@mit.edu> wrote:\n> One other long-term thought.  Maybe past a certain point, we should\n> just make it easy to get the data from git-log into a perl or pythons\n> script, where it becomes possible to do conditionals, more flexible\n> padding rules, etc.  So some kind of --format=yaml or --format=json\n> sort of thing.\n\nI thought libgit2 would already give you all the information you need.\n\n> Some interesting ideas of how we could do this can be\n> found here:\n>\n>         https://cloud.google.com/sdk/gcloud/reference/topic/formats\n>\n> ... although I doubt whether git would ever want to do the equivalent of:\n>\n> gcloud compute images list  --format='table[box,title=Images](name:sort=1,family)'\n>\n> which will print something like this:\n>\n> +------------------------------------------------------------+\n> |                           Images                           |\n> +------------------------------------------+-----------------+\n> |                   NAME                   |      FAMILY     |\n> +------------------------------------------+-----------------+\n> | centos-6-v20160629                       | centos-6        |\n> | centos-7-v20160629                       | centos-7        |\n> | coreos-alpha-1097-0-0-v20160702          | coreos-alpha    |\n> | coreos-beta-1068-3-0-v20160627           | coreos-beta     |\n> | coreos-stable-1010-6-0-v20160628         | coreos-stable   |\n> | debian-8-jessie-v20160629                | debian-8        |\n> | freebsd-101-release-amd64-20150101032704 |                 |\n> | opensuse-13-2-v20160222                  |                 |\n> | opensuse-leap-42-1-v20160302             |                 |\n> | rhel-6-v20160629                         | rhel-6          |\n> | rhel-7-v20160629                         | rhel-7          |\n> | sles-11-sp4-v20160301                    |                 |\n> | sles-12-sp1-v20160301                    |                 |\n> | ubuntu-1204-precise-v20160627            | ubuntu-1204-lts |\n> | ubuntu-1404-trusty-v20160627             | ubuntu-1404-lts |\n> | ubuntu-1510-wily-v20160627               | ubuntu-1510     |\n> | ubuntu-1604-xenial-v20160627             | ubuntu-1604-lts |\n> | windows-server-2008-r2-dc-v20160623      | windows-2008-r2 |\n> | windows-server-2012-r2-dc-v20160623      | windows-2012-r2 |\n> | xfstests-201607030209                    | xfstests        |\n> +------------------------------------------+-----------------+\n>\n> and will even use fancy graphics characters if you're using a terminal\n> which supports them.  :-)\n\nPutting everything in columns is my thing :) We can do something like\nthat. It should not be so hard to put titles on top and draw some\nlines, I think, if you set fixed column widths. I'm just not sure if\nit will be really helpful. What sort of use case do you have in mind\n(besides git-log --oneline with customizable columns)?\n-- \nDuy\n"},{"id":"291153","messageId":"20160710232809.GM26097@thunk.org","threadId":"42813","inReplyTo":"CACsJy8CSqjTztFu1fOXqyS1jXjt=D_pgAC4MXpnECAcu+dRu2w@mail.gmail.com","subject":"Re: [PATCH] pretty: add format specifiers: %gr, %gt, %gI, gi","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2016-07-10T23:28:09Z","receivedAt":"2016-07-10T23:28:19Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Sun, Jul 10, 2016 at 06:05:31PM +0200, Duy Nguyen wrote:\n> On Sun, Jul 10, 2016 at 4:26 PM, Theodore Ts'o <tytso@mit.edu> wrote:\n> > One other long-term thought.  Maybe past a certain point, we should\n> > just make it easy to get the data from git-log into a perl or pythons\n> > script, where it becomes possible to do conditionals, more flexible\n> > padding rules, etc.  So some kind of --format=yaml or --format=json\n> > sort of thing.\n> \n> I thought libgit2 would already give you all the information you need.\n\nlibgit2 isn't really all that useful if you are writing a shell\nscript.  Even from perl or python, setting up SWIG bindings and then\nlinking libgit2 into perl or python isn't exactly the most convenient\nthing in the world.\n\nAlso, my original use case was something I could drop into\n~/.gitconfig as an git alias, although I don't object to having a\nseparate shell script if that was the only way to do what I wanted.\n\n> Putting everything in columns is my thing :) We can do something like\n> that. It should not be so hard to put titles on top and draw some\n> lines, I think, if you set fixed column widths. I'm just not sure if\n> it will be really helpful. What sort of use case do you have in mind\n> (besides git-log --oneline with customizable columns)?\n\nI didn't; it was the example of something which was over the top.  :-)\n\nThat being said, it is nice if you can have columns where the\npretty-printer auto-sizes the column widths.  Most databases which\nhave a REP loop for SQL statements will do this, as does gcloud's\n--format='table[box]...' scheme.  That unfortunately means a two-pass\nscheme, although I could imagine something which looks at the first N\ncommits to be printed, figured out column widths, and then either\ntruncates or autowraps if there are commits after the first N which\nhave require a field wider than what was autosized.\n\nIt may be too much to think that all of this should be in git's core\nimplementation, though.  This is where it might be simpler to easily\nget the information into perl or python, and then do the final\nformatting in perl/pyhton.  Hence my suggestion for some kind of yaml\nor json format.  Although I suppose a CPAN or Python Module that\ndlopen's libgit2 could also work, so long as it was super-easy for\nsomeone who just wants to create a git-log like report can just do so\nwithout having to create their own C program or C language bindings to\nlibgit2....\n\n\t\t\t\t\t- Ted\n"},{"id":"291154","messageId":"20160711050201.GA18031@sigill.intra.peff.net","threadId":"42813","inReplyTo":"20160710142622.GE26097@thunk.org","subject":"Re: [PATCH] pretty: add format specifiers: %gr, %gt, %gI, gi","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-11T05:02:02Z","receivedAt":"2016-07-11T05:02:18Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Jul 10, 2016 at 10:26:22AM -0400, Theodore Ts'o wrote:\n\n> On Sun, Jul 10, 2016 at 02:16:45AM -0400, Jeff King wrote:\n> > I wonder if a better approach would be:\n> > \n> >   1. In the short term, add specific designators for the fields you'd\n> >      want. One for HEAD@{n} that is unaffected by date, as %gd is (or\n> >      even one for the branch-name and one for \"n\"). And one for the\n> >      reflog date, by itself, in whatever format --date= asked for.\n> > \n> >      That would let you do your format above, though it does not let you\n> >      show the reflog date in multiple formats.\n> \n> Hrm, maybe.  I didn't realize that %gd and %gD displayed something\n> very different if --date is specified.  Is this documented?  I looked\n> everywhere, and the closest I could find is a mention in the\n> description of -g that if you specify commit@{now}, the output will\n> use commit@{timestamp} notation --- but that's different from\n> --date=xxx, and it doesn't actually specify which pretty-printer\n> format string this affects, although I suppose that's not that hard to\n> infer.\n\nI couldn't find anything beyond the bit that you mentioned. So no\nexplanation of \"--date\", and no mention that  \"%gd\" is affected by the\nusual \"-g\" output rules. I have two patches to improve that.\n\n> One other thing I'll note in passing is that the --date notation\n> doesn't support Unix timestamps.  So you can't actually do the\n> equivalent of %gt as proposed in this patch.\n\nWe have \"--date=raw\", but that's not _quite_ the same, as it includes\nthe timezone. I think we should have \"--date=unix\" for this case. Patch\nto follow.\n\n> I'm not sure what designators we'd use for a HEAD@{n} that is\n> uneffected by date, and as far as which arbitrary two-letter code for\n> \"reflog date in the default date format\", we can't use %gd (ala %ad or\n> %cd), since it's already spoken for.  %gr, %gt, etc., at least have\n> the advantage that they are somewhat orthogonal to %ar/%at, %cr/%ct,\n> etc.\n\nYeah, I'd have hoped for %gd, as well. One thing I think we should move\ntowards in the long run is giving more readable names to our\nplaceholders for git-log, the way for-each-ref and cat-file do (but\nkeeping the existing ones for compatibility and as a shorthand).\n\nSo ideally the answer in the long run is:\n\n  %(reflog-ref)@{%(reflog-index)}\n\nor possibly:\n\n  %(reflog:index)\n\nfor the whole thing. Or something like that. I haven't thought that hard\nabout the exact syntax.\n\nBut anyway, I don't necessarily expect you to dig into that much larger\ntopic.\n\n> So I definitely understand the concern about the PP format string\n> being somewhat creaky, and obscure.  It's not entirely clearly to me\n> that adding the new designators actually doesn't add more bloat or\n> non-orthogonality.  I suppose we could add %gb for branch name, and\n> %gU for the HEAD@{n} nUm --- since %gn and %gN are already spoken for\n> --- and then use %gt for the reflog date in the default date format.\n> So that only adds three new two-letter formats, instead of the four in\n> my patch.\n> \n> (BTW, I really only care about %gt and %gr --- so if the concern is\n> bloat, we could just add those two specifiers.  I just added %gi and\n> %gI because it wasn't hard, and I thought orthoganlity was better\n> where it was possible.)\n\nTo me it's less about the number, and more the issue that:\n\n  1. It's half-implemented. Why can we do format X, but not format Y\n     (for that matter, why can you do %ct, but there is no --date format\n     that matches it?). That sort of non-orthogonality ends up\n     frustrating for users and makes git look creaky and poorly thought\n     out.\n\n  2. Every shorthand we pick, especially for things that aren't commonly\n     used, eats up the namespace. If I were designing from scratch, I'd\n     say the reflog selector shouldn't be %gd; that should be reserved\n     for symmetry with %ad and %cd.\n\n     I think your patch is not really an offender here, though; if\n     anything it's helping symmetry.\n\n> One possibility is %{authordate:format:%s} --- but it suffers from two\n> drawbacks:\n\nYeah, I agree that's pretty horrid. We should have \"Unix timestamp\" as a\nfirst-class format.\n\n> One other long-term thought.  Maybe past a certain point, we should\n> just make it easy to get the data from git-log into a perl or pythons\n> script, where it becomes possible to do conditionals, more flexible\n> padding rules, etc.  So some kind of --format=yaml or --format=json\n> sort of thing.  Some interesting ideas of how we could do this can be\n> found here:\n\nI do like that idea, though I think that's a somewhat orthogonal\nconcept, just because this kind of pretty-format stuff is used in two\nways. One, to easily get it into another script which will do something\nclever with it. And two, to make nicer formats for everyday use for\nthings like \"git log\", \"git branch -v\", and so on.\n\nThe two needs only intersect when your plan is to get it into a perl\nscript which will do the nice formatting. :)\n\nSo I think --format=json is a great idea for getting it into a separate\nscript, but it doesn't help people much who just want to customize their\ngit-log output. As an aside, there was talk and some patches long ago\nabout having a json-format for a lot of different commands. E.g., not\njust \"git log\", but \"git status --porcelain\", etc.  I like the general\nidea; line-oriented is convenient with the usual shell tools, but the\nquoting is sometimes a nightmare (and I think the \"status --porcelain\"\noutput is even context-sensitive, which is horrible to parse). If you're\ninterested, I think this is the probably the most relevant thread:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/144642\n\nFor pretty formats themselves (and possibly other script-ish bits, like\ncommit selection), I had experimental patches at one point to embed a\nlua interpreter:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/206335\n\nAgain, I don't expect you to pick up and run with either of those idea\n(but I'd love it if you did!). Just adding to the discussion. :)\n\n> ... although I doubt whether git would ever want to do the equivalent of:\n> \n> gcloud compute images list  --format='table[box,title=Images](name:sort=1,family)'\n> \n> which will print something like this:\n\nThat's neat, though I think I'd really prefer just making it easy to get\nthe data out of git in a structured way, and then applying some cool\njson-formatting script to it. Surely \"turn this json into a table\" is a\nthing that could be solved once for everybody (I don't work with it\nenough to know, but maybe \"jq\" can do that already).\n\n\nBut let's get back to reality for a moment. Here are some patches that\naddress the issues you brought up above.\n\n  [1/5]: doc/rev-list-options: clarify \"commit@{Nth}\" for \"-g\" option\n  [2/5]: doc/rev-list-options: explain \"-g\" output formats\n  [3/5]: doc/pretty-formats: describe index/time formats for %gd\n  [4/5]: date: document and test \"raw-local\" mode\n  [5/5]: date: add \"unix\" format\n\nThe next step is either:\n\n  - add specific reflog-time-formats, as your patch does\n\n  - add a generic reflog-date placeholder, so you can do:\n\n      git log --date=unix --format='%gT'\n\n    or whatever. That still doesn't give you multiple date types in a\n    single invocation, though. It's probably not much code to do so, but\n    designing the syntax and supporting existing placeholders would be\n    some work.\n\nI'm on the fence, so I'll let you decide how you want to proceed. I can\nlive with \"%gr\" and \"%gt\", as they are at least symmetric with their\nauthor/committer counterparts.\n\n-Peff\n"},{"id":"291155","messageId":"20160711050327.GA32514@sigill.intra.peff.net","threadId":"42813","inReplyTo":"20160711050201.GA18031@sigill.intra.peff.net","subject":"[PATCH 1/5] doc/rev-list-options: clarify \"commit@{Nth}\" for \"-g\" option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-11T05:03:28Z","receivedAt":"2016-07-11T05:03:35Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"When \"log -g\" shows \"HEAD@{1}\", \"HEAD@{2}\", etc, calling\nthat \"commit@{Nth}\" is not really accurate. The \"HEAD\" part\nis really the refname. By saying \"commit\", a reader may\nmisunderstand that to mean something related to the specific\ncommit we are showing, not the ref whose reflog we are\ntraversing.\n\nWhile we're here, let's also switch these instances to use\nliteral backticks, as our style guide recommends. As a\nbonus, that lets us drop some asciidoc quoting.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n Documentation/rev-list-options.txt | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex 4f009d4..6720ff3 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -252,9 +252,9 @@ list.\n +\n With `--pretty` format other than `oneline` (for obvious reasons),\n this causes the output to have two extra lines of information\n-taken from the reflog.  By default, 'commit@\\{Nth}' notation is\n+taken from the reflog.  By default, `ref@{Nth}` notation is\n used in the output.  When the starting commit is specified as\n-'commit@\\{now}', output also uses 'commit@\\{timestamp}' notation\n+`ref@{now}`, output also uses `ref@{timestamp}` notation\n instead.  Under `--pretty=oneline`, the commit message is\n prefixed with this information on the same line.\n This option cannot be combined with `--reverse`.\n-- \n2.9.0.406.g77f030d\n\n"},{"id":"291156","messageId":"20160711050451.GB32514@sigill.intra.peff.net","threadId":"42813","inReplyTo":"20160711050201.GA18031@sigill.intra.peff.net","subject":"[PATCH 2/5] doc/rev-list-options: explain \"-g\" output formats","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-11T05:04:51Z","receivedAt":"2016-07-11T05:04:59Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"We document that asking for HEAD@{now} will switch the\noutput to show HEAD@{timestamp}, but not that specifying\n`--date` has a similar effect, or that it can be overridden\nwith HEAD@{0}. Let's do so.\n\nThese rules come from 794151e (reflog-walk: always make\nHEAD@{0} show indexed selectors, 2012-05-04), though that is\nsimply the culmination of years of these heuristics growing\norganically.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n Documentation/rev-list-options.txt | 23 +++++++++++++++++++----\n 1 file changed, 19 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex 6720ff3..5267ee1 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -252,10 +252,25 @@ list.\n +\n With `--pretty` format other than `oneline` (for obvious reasons),\n this causes the output to have two extra lines of information\n-taken from the reflog.  By default, `ref@{Nth}` notation is\n-used in the output.  When the starting commit is specified as\n-`ref@{now}`, output also uses `ref@{timestamp}` notation\n-instead.  Under `--pretty=oneline`, the commit message is\n+taken from the reflog.  The reflog designator in the output may be shown\n+as `ref@{Nth}` (where `Nth` is the reverse-chronological index in the\n+reflog) or as `ref@{timestamp}` (with the timestamp for that entry),\n+depending on a few rules:\n++\n+--\n+1. If the starting point is specified as `ref@{Nth}`, show the index\n+format.\n++\n+2. If the starting point was specified as `ref@{now}`, show the\n+timestamp format.\n++\n+3. If neither was used, but `--date` was given on the command line, show\n+the timestamp in the format requested by `--date`.\n++\n+4. Otherwise, show the index format.\n+--\n++\n+Under `--pretty=oneline`, the commit message is\n prefixed with this information on the same line.\n This option cannot be combined with `--reverse`.\n See also linkgit:git-reflog[1].\n-- \n2.9.0.406.g77f030d\n\n"},{"id":"291157","messageId":"20160711050513.GC32514@sigill.intra.peff.net","threadId":"42813","inReplyTo":"20160711050201.GA18031@sigill.intra.peff.net","subject":"[PATCH 3/5] doc/pretty-formats: describe index/time formats for %gd","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-11T05:05:13Z","receivedAt":"2016-07-11T05:05:21Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"The \"reflog selector\" format changes based on a series of\nheuristics, and that applies equally to both stock \"log -g\"\noutput, as well as \"--format=%gd\". The documentation for\n\"%gd\" doesn't cover this. Let's mention the multiple formats\nand refer the user back to the \"-g\" section for the complete\nrules.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n Documentation/pretty-formats.txt | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 29b19b9..36a300a 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -147,8 +147,11 @@ endif::git-rev-list[]\n   \"U\" for a good signature with unknown validity and \"N\" for no signature\n - '%GS': show the name of the signer for a signed commit\n - '%GK': show the key used to sign a signed commit\n-- '%gD': reflog selector, e.g., `refs/stash@{1}`\n-- '%gd': shortened reflog selector, e.g., `stash@{1}`\n+- '%gD': reflog selector, e.g., `refs/stash@{1}` or\n+  `refs/stash@{2 minutes ago`}; the format follows the rules described\n+  for the `-g` option\n+- '%gd': shortened reflog selector, e.g., `stash@{1}` or\n+  `stash@{2 minutes ago}`\n - '%gn': reflog identity name\n - '%gN': reflog identity name (respecting .mailmap, see\n   linkgit:git-shortlog[1] or linkgit:git-blame[1])\n-- \n2.9.0.406.g77f030d\n\n"},{"id":"291158","messageId":"20160711050617.GD32514@sigill.intra.peff.net","threadId":"42813","inReplyTo":"20160711050201.GA18031@sigill.intra.peff.net","subject":"[PATCH 4/5] date: document and test \"raw-local\" mode","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-11T05:06:17Z","receivedAt":"2016-07-11T05:06:25Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"The \"raw\" format shows a Unix epoch timestamp, but with a\ntimezone tacked on. The timestamp is not _in_ that zone, but\nit is extra information about the time (by default, the zone\nthe author was in).\n\nThe documentation claims that \"raw-local\" does not work. It\ndoes, but the end result is rather subtle. Let's describe it\nin better detail, and test to make sure it works (namely,\nthe epoch time doesn't change, but the zone does).\n\nWhile we are rewording the documentation in this area, let's\nnot use the phrase \"does not work\" for the remaining option,\n\"--relative\". It's vague; do we accept it or not? We do\naccept it, but it has no effect (which is a reasonable\noutcome).\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n Documentation/rev-list-options.txt | 9 ++++++---\n t/t0006-date.sh                    | 1 +\n 2 files changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex 5267ee1..a6059d1 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -725,8 +725,8 @@ include::pretty-options.txt[]\n \t`iso-local`), the user's local time zone is used instead.\n +\n `--date=relative` shows dates relative to the current time,\n-e.g. ``2 hours ago''. The `-local` option cannot be used with\n-`--raw` or `--relative`.\n+e.g. ``2 hours ago''. The `-local` option has no effect for\n+`--relative`.\n +\n `--date=local` is an alias for `--date=default-local`.\n +\n@@ -746,7 +746,10 @@ format, often found in email messages.\n +\n `--date=short` shows only the date, but not the time, in `YYYY-MM-DD` format.\n +\n-`--date=raw` shows the date in the internal raw Git format `%s %z` format.\n+`--date=raw` shows the date in the internal raw Git format `%s %z`\n+format. Note that the `-local` option does not affect the\n+seconds-since-epoch value (which is always measured in UTC), but does\n+switch the accompanying timezone value.\n +\n `--date=format:...` feeds the format `...` to your system `strftime`.\n Use `--date=format:%c` to show the date in your system locale's\ndiff --git a/t/t0006-date.sh b/t/t0006-date.sh\nindex 04ce535..276366e 100755\n--- a/t/t0006-date.sh\n+++ b/t/t0006-date.sh\n@@ -47,6 +47,7 @@ check_show short \"$TIME\" '2016-06-15'\n check_show default \"$TIME\" 'Wed Jun 15 16:13:20 2016 +0200'\n check_show raw \"$TIME\" '1466000000 +0200'\n check_show iso-local \"$TIME\" '2016-06-15 14:13:20 +0000'\n+check_show raw-local \"$TIME\" '1466000000 +0000'\n \n # arbitrary time absurdly far in the future\n FUTURE=\"5758122296 -0400\"\n-- \n2.9.0.406.g77f030d\n\n"},{"id":"291159","messageId":"20160711050730.GE32514@sigill.intra.peff.net","threadId":"42813","inReplyTo":"20160711050201.GA18031@sigill.intra.peff.net","subject":"[PATCH 5/5] date: add \"unix\" format","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-11T05:07:30Z","receivedAt":"2016-07-11T05:07:38Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"We already have \"--date=raw\", which is a Unix epoch\ntimestamp plus a contextual timezone (either the author's or\nthe local). But one may not care about the timezone and just\nwant the epoch timestamp by itself. It's not hard to parse\nthe two apart, but if you are using a pretty-print format,\nyou may want git to show the \"finished\" form that the user\nwill see.\n\nWe can accomodate this by adding a new date format, \"unix\",\nwhich is basically \"raw\" without the timezone.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n Documentation/rev-list-options.txt | 4 ++++\n builtin/blame.c                    | 3 +++\n cache.h                            | 3 ++-\n date.c                             | 8 ++++++++\n t/t0006-date.sh                    | 2 ++\n 5 files changed, 19 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex a6059d1..0fa4c8b 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -751,6 +751,10 @@ format. Note that the `-local` option does not affect the\n seconds-since-epoch value (which is always measured in UTC), but does\n switch the accompanying timezone value.\n +\n+`--date=unix` shows the date as a Unix epoch timestamp (seconds since\n+1970).  As with `--raw`, this is always in UTC and therefore `-local`\n+has no effect.\n++\n `--date=format:...` feeds the format `...` to your system `strftime`.\n Use `--date=format:%c` to show the date in your system locale's\n preferred format.  See the `strftime` manual for a complete list of\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex 1e214bd..1486541 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -2626,6 +2626,9 @@ parse_done:\n \tcase DATE_RAW:\n \t\tblame_date_width = sizeof(\"1161298804 -0700\");\n \t\tbreak;\n+\tcase DATE_UNIX:\n+\t\tblame_date_width = sizeof(\"1161298804\");\n+\t\tbreak;\n \tcase DATE_SHORT:\n \t\tblame_date_width = sizeof(\"2006-10-19\");\n \t\tbreak;\ndiff --git a/cache.h b/cache.h\nindex f1dc289..ebbf6b7 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1223,7 +1223,8 @@ struct date_mode {\n \t\tDATE_ISO8601_STRICT,\n \t\tDATE_RFC2822,\n \t\tDATE_STRFTIME,\n-\t\tDATE_RAW\n+\t\tDATE_RAW,\n+\t\tDATE_UNIX\n \t} type;\n \tconst char *strftime_fmt;\n \tint local;\ndiff --git a/date.c b/date.c\nindex 4c7aa9b..a996331 100644\n--- a/date.c\n+++ b/date.c\n@@ -177,6 +177,12 @@ const char *show_date(unsigned long time, int tz, const struct date_mode *mode)\n \tstruct tm *tm;\n \tstatic struct strbuf timebuf = STRBUF_INIT;\n \n+\tif (mode->type == DATE_UNIX) {\n+\t\tstrbuf_reset(&timebuf);\n+\t\tstrbuf_addf(&timebuf, \"%lu\", time);\n+\t\treturn timebuf.buf;\n+\t}\n+\n \tif (mode->local)\n \t\ttz = local_tzoffset(time);\n \n@@ -792,6 +798,8 @@ static enum date_mode_type parse_date_type(const char *format, const char **end)\n \t\treturn DATE_NORMAL;\n \tif (skip_prefix(format, \"raw\", end))\n \t\treturn DATE_RAW;\n+\tif (skip_prefix(format, \"unix\", end))\n+\t\treturn DATE_UNIX;\n \tif (skip_prefix(format, \"format\", end))\n \t\treturn DATE_STRFTIME;\n \ndiff --git a/t/t0006-date.sh b/t/t0006-date.sh\nindex 276366e..886821d 100755\n--- a/t/t0006-date.sh\n+++ b/t/t0006-date.sh\n@@ -46,8 +46,10 @@ check_show rfc2822 \"$TIME\" 'Wed, 15 Jun 2016 16:13:20 +0200'\n check_show short \"$TIME\" '2016-06-15'\n check_show default \"$TIME\" 'Wed Jun 15 16:13:20 2016 +0200'\n check_show raw \"$TIME\" '1466000000 +0200'\n+check_show unix \"$TIME\" '1466000000'\n check_show iso-local \"$TIME\" '2016-06-15 14:13:20 +0000'\n check_show raw-local \"$TIME\" '1466000000 +0000'\n+check_show unix-local \"$TIME\" '1466000000'\n \n # arbitrary time absurdly far in the future\n FUTURE=\"5758122296 -0400\"\n-- \n2.9.0.406.g77f030d\n"},{"id":"291171","messageId":"20160711164317.GB3890@thunk.org","threadId":"42813","inReplyTo":"20160711050201.GA18031@sigill.intra.peff.net","subject":"Re: [PATCH] pretty: add format specifiers: %gr, %gt, %gI, gi","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2016-07-11T16:43:17Z","receivedAt":"2016-07-11T16:43:25Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Mon, Jul 11, 2016 at 01:02:02AM -0400, Jeff King wrote:\n> Yeah, I'd have hoped for %gd, as well. One thing I think we should move\n> towards in the long run is giving more readable names to our\n> placeholders for git-log, the way for-each-ref and cat-file do (but\n> keeping the existing ones for compatibility and as a shorthand).\n> \n> So ideally the answer in the long run is:\n> \n>   %(reflog-ref)@{%(reflog-index)}\n> \n> or possibly:\n> \n>   %(reflog:index)\n> \n> for the whole thing. Or something like that. I haven't thought that hard\n> about the exact syntax.\n\nYes, FWIW, I agree that long term, using % followed by one or two\ncharacters is just a mess, and using some kind of human-readable\nformat is going to make a lot of sense.  I can imagine a few places\nwhere I might still want to type --format=%at in some kind of ad-hoc\nshell command, but in most places, if you're using a complex --format\nspecifier, it's going either in a shell script or in a .gitconfig\nfile, where being verbose is probably more of an advantage than a\ndisadvantage.\n\n>   1. It's half-implemented. Why can we do format X, but not format Y\n>      (for that matter, why can you do %ct, but there is no --date format\n>      that matches it?). That sort of non-orthogonality ends up\n>      frustrating for users and makes git look creaky and poorly thought\n>      out.\n\nGit *is* creaky and not thought-out in advance; that's just the nature\nof how most successful open source projects grow; might as well be\nproud of it.  :-)   As Greg K-H has said: \"We believe in evolution, and\nnot intelligent design.\"  :-)\n\n> > ... although I doubt whether git would ever want to do the equivalent of:\n> > \n> > gcloud compute images list  --format='table[box,title=Images](name:sort=1,family)'\n> > \n> > which will print something like this:\n> \n> That's neat, though I think I'd really prefer just making it easy to get\n> the data out of git in a structured way, and then applying some cool\n> json-formatting script to it. Surely \"turn this json into a table\" is a\n> thing that could be solved once for everybody (I don't work with it\n> enough to know, but maybe \"jq\" can do that already).\n\nOh, agreed.  I used that as over-the-top example of something we\nprobably wouldn't want to put in the git core.  jq can't, but I'm sure\nthere must be some JSON tool out there which can.\n\n> But let's get back to reality for a moment. Here are some patches that\n> address the issues you brought up above.\n> \n>   [1/5]: doc/rev-list-options: clarify \"commit@{Nth}\" for \"-g\" option\n>   [2/5]: doc/rev-list-options: explain \"-g\" output formats\n>   [3/5]: doc/pretty-formats: describe index/time formats for %gd\n>   [4/5]: date: document and test \"raw-local\" mode\n>   [5/5]: date: add \"unix\" format\n> \n> The next step is either:\n> \n>   - add specific reflog-time-formats, as your patch does\n> \n>   - add a generic reflog-date placeholder, so you can do:\n> \n>       git log --date=unix --format='%gT'\n> \n>     or whatever. That still doesn't give you multiple date types in a\n>     single invocation, though. It's probably not much code to do so, but\n>     designing the syntax and supporting existing placeholders would be\n>     some work.\n> \n> I'm on the fence, so I'll let you decide how you want to proceed. I can\n> live with \"%gr\" and \"%gt\", as they are at least symmetric with their\n> author/committer counterparts.\n\nI'm on the fence myself.  I can live with either, since either way the\nlong message command line will be going in .gitconfig.  I have a\nslight preference for %gr and %gt, as %gT isn't orthogonal with\n%ad/%cd, but I could be easily pursuaded otherwise.\n\nDoes anyone else have a strong opinion?\n\n\t\t\t\t\t\t- Ted\n"},{"id":"291172","messageId":"20160711164834.GC3890@thunk.org","threadId":"42813","inReplyTo":"20160711050513.GC32514@sigill.intra.peff.net","subject":"Re: [PATCH 3/5] doc/pretty-formats: describe index/time formats for %gd","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2016-07-11T16:48:34Z","receivedAt":"2016-07-11T16:48:46Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Mon, Jul 11, 2016 at 01:05:13AM -0400, Jeff King wrote:\n> The \"reflog selector\" format changes based on a series of\n> heuristics, and that applies equally to both stock \"log -g\"\n> output, as well as \"--format=%gd\". The documentation for\n> \"%gd\" doesn't cover this. Let's mention the multiple formats\n> and refer the user back to the \"-g\" section for the complete\n> rules.\n\nIs it worth mentioning that the shortening only happens if the user\nspecifies a selector with '/' in it in the first place?  I was\nconfused when I was first playing with these selectors because %gd and\n%gD are identical if you run\n\n\tgit reflog --format=%gd -3 master\n\tgit reflog --format=%gD -3 master\n\nand are only different if you run:\n\n\tgit reflog --format=%gd -3 refs/heads/master\n\tgit reflog --format=%gD -3 refs/heads/master\n\n\t\t\t\t\t- Ted\n\t\t\t\t\t\n"},{"id":"291173","messageId":"20160711165000.GD3890@thunk.org","threadId":"42813","inReplyTo":"20160711050617.GD32514@sigill.intra.peff.net","subject":"Re: [PATCH 4/5] date: document and test \"raw-local\" mode","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2016-07-11T16:50:00Z","receivedAt":"2016-07-11T16:50:09Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Mon, Jul 11, 2016 at 01:06:17AM -0400, Jeff King wrote:\n> \n> The documentation claims that \"raw-local\" does not work. It\n> does, but the end result is rather subtle. Let's describe it\n> in better detail, and test to make sure it works (namely,\n> the epoch time doesn't change, but the zone does).\n\nMaybe add an editorial statement that in most cases this isn't\nparticularly useful?  Documenting raw-local implies that someone might\nwant to consider using it, and it's not clear to me folks should ever\ntry --- they're more likely to confuse themselves more than anything\nelse.\n\n\t\t\t\t\t- Ted\n"},{"id":"291194","messageId":"xmqqa8ho9eny.fsf@gitster.mtv.corp.google.com","threadId":"42813","inReplyTo":"20160711164317.GB3890@thunk.org","subject":"Re: [PATCH] pretty: add format specifiers: %gr, %gt, %gI, gi","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-07-11T19:07:45Z","receivedAt":"2016-07-11T19:07:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Theodore Ts'o <tytso@mit.edu> writes:\n\n>> I'm on the fence, so I'll let you decide how you want to proceed. I can\n>> live with \"%gr\" and \"%gt\", as they are at least symmetric with their\n>> author/committer counterparts.\n>\n> I'm on the fence myself.  I can live with either, since either way the\n> long message command line will be going in .gitconfig.  I have a\n> slight preference for %gr and %gt, as %gT isn't orthogonal with\n> %ad/%cd, but I could be easily pursuaded otherwise.\n>\n> Does anyone else have a strong opinion?\n\nI am fine with %gr/%gt, with the understanding that the step beyond\nthat would not be to add %gT but to do %(reflog:...), and giving\nsimilar longform to other things like %ad so that we can move things\nin the \"maybe cumbersome to type but more readable\" direction.\n\n"},{"id":"291226","messageId":"20160712000841.GB26163@sigill.intra.peff.net","threadId":"42813","inReplyTo":"20160711164834.GC3890@thunk.org","subject":"Re: [PATCH 3/5] doc/pretty-formats: describe index/time formats for %gd","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-12T00:08:42Z","receivedAt":"2016-07-12T00:08:56Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Jul 11, 2016 at 12:48:34PM -0400, Theodore Ts'o wrote:\n\n> On Mon, Jul 11, 2016 at 01:05:13AM -0400, Jeff King wrote:\n> > The \"reflog selector\" format changes based on a series of\n> > heuristics, and that applies equally to both stock \"log -g\"\n> > output, as well as \"--format=%gd\". The documentation for\n> > \"%gd\" doesn't cover this. Let's mention the multiple formats\n> > and refer the user back to the \"-g\" section for the complete\n> > rules.\n> \n> Is it worth mentioning that the shortening only happens if the user\n> specifies a selector with '/' in it in the first place?  I was\n> confused when I was first playing with these selectors because %gd and\n> %gD are identical if you run\n> \n> \tgit reflog --format=%gd -3 master\n> \tgit reflog --format=%gD -3 master\n> \n> and are only different if you run:\n> \n> \tgit reflog --format=%gd -3 refs/heads/master\n> \tgit reflog --format=%gD -3 refs/heads/master\n\nYeah, I noticed that \"shortened\" is not really defined when I was\nwriting this.\n\nMaybe this on top of the other documentation patches?\n\n-- >8 --\nSubject: [PATCH] doc/pretty-formats: explain shortening of %gd\n\nThe actual shortening rules aren't that interesting and\nprobably not worth getting into (I gloss over them here as\n\"shortened for human readability\"). But the fact that %gD\nshows whatever you gave on the command line is subtle and\nworth mentioning. Since most people will feed a shortened\nrefname in the first place, it otherwise makes it hard to\nunderstand the difference between the two.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n Documentation/pretty-formats.txt | 9 ++++++---\n 1 file changed, 6 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 36a300a..b95d67e 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -149,9 +149,12 @@ endif::git-rev-list[]\n - '%GK': show the key used to sign a signed commit\n - '%gD': reflog selector, e.g., `refs/stash@{1}` or\n   `refs/stash@{2 minutes ago`}; the format follows the rules described\n-  for the `-g` option\n-- '%gd': shortened reflog selector, e.g., `stash@{1}` or\n-  `stash@{2 minutes ago}`\n+  for the `-g` option. The portion before the `@` is the refname as\n+  given on the command line (so `git log -g refs/heads/master` would\n+  yield `refs/heads/master@{0}`).\n+- '%gd': shortened reflog selector; same as `%gD`, but the refname\n+  portion is shortened for human readability (so `refs/heads/master`\n+  becomes just `master`).\n - '%gn': reflog identity name\n - '%gN': reflog identity name (respecting .mailmap, see\n   linkgit:git-shortlog[1] or linkgit:git-blame[1])\n-- \n2.9.0.406.g77f030d\n\n"},{"id":"291227","messageId":"20160712001626.GC26163@sigill.intra.peff.net","threadId":"42813","inReplyTo":"20160711165000.GD3890@thunk.org","subject":"Re: [PATCH 4/5] date: document and test \"raw-local\" mode","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-12T00:16:26Z","receivedAt":"2016-07-12T00:16:34Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Jul 11, 2016 at 12:50:00PM -0400, Theodore Ts'o wrote:\n\n> On Mon, Jul 11, 2016 at 01:06:17AM -0400, Jeff King wrote:\n> > \n> > The documentation claims that \"raw-local\" does not work. It\n> > does, but the end result is rather subtle. Let's describe it\n> > in better detail, and test to make sure it works (namely,\n> > the epoch time doesn't change, but the zone does).\n> \n> Maybe add an editorial statement that in most cases this isn't\n> particularly useful?  Documenting raw-local implies that someone might\n> want to consider using it, and it's not clear to me folks should ever\n> try --- they're more likely to confuse themselves more than anything\n> else.\n\nI waffled on making such a statement. I agree it's unlikely to be that\nuseful in practice. The most plausible scenario I could come up with is\na program or script that asks for \"--date=raw\" because it's going to\nformat the date later. Somebody using that program may prefer their\nlocal timestamps. Normally you'd just say \"--date=iso-local\" or whatever\nformat you prefer, but because this is transiting through the other\nprogram which only understands --date=raw, you have to keep using that\nformat.\n\nI hoped that the explanation I added would prevent confusion, or at\nleast be an improvement over the existing documentation of \"doesn't\nwork\".\n\n-Peff\n"},{"id":"291233","messageId":"xmqqtwfv7gxd.fsf@gitster.mtv.corp.google.com","threadId":"42813","inReplyTo":"20160712000841.GB26163@sigill.intra.peff.net","subject":"Re: [PATCH 3/5] doc/pretty-formats: describe index/time formats for %gd","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-07-12T02:01:50Z","receivedAt":"2016-07-12T02:01:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Maybe this on top of the other documentation patches?\n>\n> -- >8 --\n> Subject: [PATCH] doc/pretty-formats: explain shortening of %gd\n>\n> The actual shortening rules aren't that interesting and\n> probably not worth getting into (I gloss over them here as\n> \"shortened for human readability\"). But the fact that %gD\n> shows whatever you gave on the command line is subtle and\n> worth mentioning. Since most people will feed a shortened\n> refname in the first place, it otherwise makes it hard to\n> understand the difference between the two.\n>\n> Signed-off-by: Jeff King <peff@peff.net>\n> ---\n>  Documentation/pretty-formats.txt | 9 ++++++---\n>  1 file changed, 6 insertions(+), 3 deletions(-)\n>\n> diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\n> index 36a300a..b95d67e 100644\n> --- a/Documentation/pretty-formats.txt\n> +++ b/Documentation/pretty-formats.txt\n> @@ -149,9 +149,12 @@ endif::git-rev-list[]\n>  - '%GK': show the key used to sign a signed commit\n>  - '%gD': reflog selector, e.g., `refs/stash@{1}` or\n>    `refs/stash@{2 minutes ago`}; the format follows the rules described\n> -  for the `-g` option\n> -- '%gd': shortened reflog selector, e.g., `stash@{1}` or\n> -  `stash@{2 minutes ago}`\n> +  for the `-g` option. The portion before the `@` is the refname as\n> +  given on the command line (so `git log -g refs/heads/master` would\n> +  yield `refs/heads/master@{0}`).\n> +- '%gd': shortened reflog selector; same as `%gD`, but the refname\n> +  portion is shortened for human readability (so `refs/heads/master`\n> +  becomes just `master`).\n\nSounds about the right amount of detail to me.  Thanks.\n\n>  - '%gn': reflog identity name\n>  - '%gN': reflog identity name (respecting .mailmap, see\n>    linkgit:git-shortlog[1] or linkgit:git-blame[1])\n"}]}