{"thread":{"id":"66089","subject":"[PATCH] date: add --date=elapsed and %aX/%cX placeholders","startedAt":"2026-07-30T07:01:22Z","lastAt":"2026-07-30T07:01:22Z","messageCount":1,"participants":["Israel Roldan via GitGitGadget"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"549262","messageId":"pull.2368.git.git.1785394879459.gitgitgadget@gmail.com","threadId":"66089","inReplyTo":null,"subject":"[PATCH] date: add --date=elapsed and %aX/%cX placeholders","fromName":"Israel Roldan via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-07-30T07:01:19Z","receivedAt":"2026-07-30T07:01:22Z","isPatch":true,"body":"From: Israel Roldan <israel.alberto.rv@gmail.com>\n\nThe --date=human format and the %cr/%ch placeholders both produce\na localized English phrase that hides the precise amount of time\nthat has passed. A commit shown as \"2 days ago\" may in reality be\n1 day 3 hours, or 1 day 23 hours. Switching to %ct and a calculator\nsolves the problem but is not glance-friendly.\n\nAdd an uptime(1)-style elapsed-time format:\n  --date=elapsed          --date=elapsed-pad\n  39s                     39s\n  8h 7m 48s               08h 07m 48s\n  1y 11M 5d 13h 5m 13s    01y 11M 05d 13h 05m 13s\n\nThe placeholder letter is X because the obvious choice E is already\nused for the mailmap-respecting email variants (%aE, %cE, %gE).\n\nSigned-off-by: Israel Roldan <israel.alberto.rv@gmail.com>\n---\n    [RFC PATCH] date: add --date=elapsed and %aX/%cX placeholders\n    \n    \n    Motivation\n    ==========\n    \n    The --date=human format and the %cr/%ch placeholders both produce a\n    localized English phrase that hides the precise amount of time that has\n    passed. A commit shown as \"2 days ago\" may in reality be 1 day 3 hours,\n    or 1 day 23 hours. Switching to %ct and a calculator solves the problem\n    but is not glance-friendly.\n    \n    The closest external tool that solves the same problem is\n    git-log-compact by Kyle J. McKay (2016), which the maintainer declined\n    to merge into Git core because it was a heavyweight change to the\n    oneline output rather than a date format.\n    \n    \n    What this patch adds\n    ====================\n    \n    A new date format --date=elapsed and --date=elapsed-pad modelled on\n    uptime(1):\n    \n      seconds   --date=elapsed          --date=elapsed-pad\n          39    \"39s\"                   \"39s\"\n         984    \"16m 24s\"               \"16m 24s\"\n       29268    \"8h 7m 48s\"             \"08h 07m 48s\"\n     3024000    \"1M 5d 0s\"              \"01M 05d 00h 00m 00s\"\n    60527113    \"1y 11M 5d 13h 5m 13s\"  \"01y 11M 05d 13h 05m 13s\"\n    \n    \n    The padded variant zero-pads every emitted unit to at least two digits.\n    \n    A commit timestamp that is in the future is reported as \"0s\", not the\n    localized phrase \"in the future\" that show_date_relative() emits.\n    \n    Months are fixed at 30 days and years at 365 days, matching the\n    uptime(1) convention. They are consistent, and the same approximations\n    are already in use by Git's own show_date_relative() for the\n    relative-time format.\n    \n    Two new pretty-format placeholders, %aX (author) and %cX (committer):\n    \n    git log --format='%h (%aX) %s'\n    13c7afec21 (1d 2h 9s) The 8th batch\n    8c7817c361 (1y 3d 19h 5m 10s) Merge branch 'rj/meson-libexecdir-fix'\n    0e521a41b5 (11y 17d 21h 8m 40s) Merge branch 'et/http-proxyauth'\n    \n    \n    The placeholders mirror %ch and %cr, which also ignore the caller's\n    --date= and emit a fixed shape.\n    \n    \n    Open questions\n    ==============\n    \n    Q1. The placeholder letter. The natural mnemonic is E (Elapsed), but\n    %aE, %cE and %gE are already taken (mailmap-respecting email variants).\n    This patch uses X as a free letter. Would the maintainer prefer a\n    different letter? I am not attached to X.\n    \n    Q2. Should --date=elapsed-pad be its own format name, or a separate\n    --date=elapsed plus a flag? Which mirrors --date=human /\n    --date=human-local / --date=iso / --date=iso-local.\n    \n    Q3. The \"future timestamp\" behaviour. This patch clamps a future\n    timestamp to \"0s\". An alternative would be to keep the relative format's\n    \"in the future\" wording.\n    \n    Q4. %aX/%cX are hard-coded compact; padded output requires %ad/%cd\n    together with --date=elapsed-pad. Should a paired %aY/%cY for padded\n    also exist, or is the asymmetry acceptable?\n    \n    \n    Patch\n    =====\n    \n    The patch modifies the existing date_mode_type enum, adds a new\n    show_date_elapsed() helper in date.c, wires it through show_date() and\n    parse_date_format(), exposes two placeholders via format_person_part()\n    in pretty.c, handles the new format in builtin/blame.c for column width,\n    updates the documentation, and adds tests for both the date helper and\n    the pretty-format placeholder equivalence.\n    \n    The full patch is attached below.\n    \n    \n    Testing\n    =======\n    \n    $ make DEVELOPER=1 && cd t &&\n    prove --no-color ./t0006-date.sh ./t4205-log-pretty-formats.sh\n    ./t0006-date.sh ................ ok ./t4205-log-pretty-formats.sh .. ok\n    All tests successful.\n    \n    The full test suite (1054 test files, 33832 tests) also passes on this\n    machine.\n    \n    Thanks for your time. I am happy to iterate on any of the open questions\n    before posting a non-RFC version.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2368%2Fairvzxf%2Ffeature%2Fdate-elapsed-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2368/airvzxf/feature/date-elapsed-v1\nPull-Request: https://github.com/git/git/pull/2368\n\n Documentation/pretty-formats.adoc      |  4 ++\n Documentation/rev-list-options.adoc    | 13 ++++\n builtin/blame.c                        |  8 +++\n contrib/completion/git-completion.bash |  2 +-\n date.c                                 | 88 +++++++++++++++++++++++++-\n date.h                                 |  4 +-\n pretty.c                               |  3 +\n t/helper/test-date.c                   | 19 +++++-\n t/t0006-date.sh                        | 43 +++++++++++++\n t/t4205-log-pretty-formats.sh          |  6 ++\n 10 files changed, 186 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/pretty-formats.adoc b/Documentation/pretty-formats.adoc\nindex 2ae0eb11a9..9ae882b160 100644\n--- a/Documentation/pretty-formats.adoc\n+++ b/Documentation/pretty-formats.adoc\n@@ -233,6 +233,8 @@ The placeholders are:\n +%as+:: author date, short format (`YYYY-MM-DD`)\n +%ah+:: author date, human style (like the `--date=human` option of\n \tlinkgit:git-rev-list[1])\n++%aX+:: author date, elapsed (like the `--date=elapsed` option of\n+\tlinkgit:git-rev-list[1])\n +%cn+:: committer name\n +%cN+:: committer name (respecting .mailmap, see\n \tlinkgit:git-shortlog[1] or linkgit:git-blame[1])\n@@ -251,6 +253,8 @@ The placeholders are:\n +%cs+:: committer date, short format (`YYYY-MM-DD`)\n +%ch+:: committer date, human style (like the `--date=human` option of\n \tlinkgit:git-rev-list[1])\n++%cX+:: committer date, elapsed (like the `--date=elapsed` option of\n+\tlinkgit:git-rev-list[1])\n +%d+:: ref names, like the --decorate option of linkgit:git-log[1]\n +%D+:: ref names without the \" (\", \")\" wrapping.\n +%(count)+:: the number of a patch within a patch series. Used only in\ndiff --git a/Documentation/rev-list-options.adoc b/Documentation/rev-list-options.adoc\nindex fd831f0ec6..937c6096c5 100644\n--- a/Documentation/rev-list-options.adoc\n+++ b/Documentation/rev-list-options.adoc\n@@ -1174,6 +1174,19 @@ omitted.\n 1970).  As with `--raw`, this is always in UTC and therefore `-local`\n has no effect.\n \n+`--date=elapsed` shows the elapsed time between the commit and now,\n+in a compact, script-friendly, `uptime(1)`-style format. Only the\n+non-zero leading units are emitted, separated by single spaces. For\n+example \"39s\", \"16m 24s\", \"8h 7m 48s\", \"12M 30d 13h 25m 43s\",\n+\"1y 11M 5d 13h 5m 13s\". A commit timestamp that is in the future\n+is reported as \"0s\". Months are fixed at 30 days and years at 365\n+days, matching the `uptime(1)` convention.\n+\n+`--date=elapsed-pad` is like `--date=elapsed`, but every emitted\n+unit is at least two digits wide, zero-padded on the left, so\n+that columns line up across rows.  For example \"16m 24s\",\n+\"08h 07m 48s\", \"01M 05d 00h 00m 00s\", \"01y 11M 05d 13h 05m 13s\".\n+\n `--date=format:<format>` feeds the _<format>_ to your system `strftime`,\n except for `%s`, `%z`, and `%Z`, which are handled internally.\n Use `--date=format:%c` to show the date in your system locale's\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex 48d5251c6d..f3fd866e82 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -1123,6 +1123,14 @@ parse_done:\n \t\t/* If the year is shown, no time is shown */\n \t\tblame_date_width = sizeof(\"Thu Oct 19 16:00\");\n \t\tbreak;\n+\tcase DATE_ELAPSED:\n+\tcase DATE_ELAPSED_PAD:\n+\t\t/*\n+\t\t * Maximum display width of the elapsed time format,\n+\t\t * e.g. \"99y 99M 99d 99h 99m 99s\" -- a safe upper bound.\n+\t\t */\n+\t\tblame_date_width = sizeof(\"99y 99M 99d 99h 99m 99s\");\n+\t\tbreak;\n \tcase DATE_NORMAL:\n \t\tblame_date_width = sizeof(\"Thu Oct 19 16:00:04 2006 -0700\");\n \t\tbreak;\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex e875787710..4db014c7c0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2231,7 +2231,7 @@ __git_log_show_options=\"\n __git_diff_merges_opts=\"off none on first-parent 1 separate m combined c dense-combined cc remerge r\"\n \n __git_log_pretty_formats=\"oneline short medium full fuller reference email raw format: tformat: mboxrd\"\n-__git_log_date_formats=\"relative iso8601 iso8601-strict rfc2822 short local default human raw unix auto: format:\"\n+__git_log_date_formats=\"relative iso8601 iso8601-strict rfc2822 short local default human raw unix elapsed auto: format:\"\n \n # Complete porcelain (i.e. not git-rev-list) options and at least some\n # option arguments accepted by git-log.  Note that this same set of options\ndiff --git a/date.c b/date.c\nindex 014065b419..566da2fd21 100644\n--- a/date.c\n+++ b/date.c\n@@ -209,6 +209,79 @@ void show_date_relative(timestamp_t time, struct strbuf *timebuf)\n \t\t (diff + 183) / 365);\n }\n \n+/*\n+ * Print the elapsed time between `time` and now in a compact, script-friendly\n+ * \"uptime(1)\"-style format: only non-zero units are emitted, left to right,\n+ * separated by single spaces.  With `pad` set, every emitted unit is at least\n+ * two digits wide, zero-padded on the left.\n+ *\n+ *   diff < 60s          -> \"39s\"\n+ *   diff < 60m          -> \"16m 24s\"\n+ *   diff < 24h          -> \"08h 07m 48s\" (pad) / \"8h 7m 48s\" (compact)\n+ *   diff < 1y           -> \"12M 30d 13h 25m 43s\"\n+ *   diff >= 1y          -> \"01y 11M 05d 13h 05m 13s\" (pad) / \"1y 11M 5d ...\" (compact)\n+ *\n+ * A negative diff (commit timestamp is in the future) clamps to \"0s\" so the\n+ * output stays script-parseable instead of producing a localized phrase like\n+ * \"in the future\" as `show_date_relative()` does.\n+ */\n+static void show_date_elapsed(timestamp_t time, struct strbuf *timebuf, int pad)\n+{\n+\tstruct timeval now;\n+\ttimestamp_t diff, y, M, d, h, m, s;\n+\tconst char *sp = \" \";\n+\n+\tget_time(&now);\n+\tif (now.tv_sec < time)\n+\t\tdiff = 0;\n+\telse\n+\t\tdiff = now.tv_sec - time;\n+\n+#define ELAPSED_SECS_PER_MIN  (60L)\n+#define ELAPSED_SECS_PER_HOUR (60L * 60L)\n+#define ELAPSED_SECS_PER_DAY  (24L * 60L * 60L)\n+#define ELAPSED_SECS_PER_MON  (30L * 24L * 60L * 60L)        /* uptime(1) convention */\n+#define ELAPSED_SECS_PER_YEAR (365L * 24L * 60L * 60L)       /* uptime(1) convention */\n+\n+\ty  = diff / ELAPSED_SECS_PER_YEAR;\n+\tdiff %= ELAPSED_SECS_PER_YEAR;\n+\tM  = diff / ELAPSED_SECS_PER_MON;\n+\tdiff %= ELAPSED_SECS_PER_MON;\n+\td  = diff / ELAPSED_SECS_PER_DAY;\n+\tdiff %= ELAPSED_SECS_PER_DAY;\n+\th  = diff / ELAPSED_SECS_PER_HOUR;\n+\tdiff %= ELAPSED_SECS_PER_HOUR;\n+\tm  = diff / ELAPSED_SECS_PER_MIN;\n+\ts  = diff % ELAPSED_SECS_PER_MIN;\n+\n+#undef ELAPSED_SECS_PER_MIN\n+#undef ELAPSED_SECS_PER_HOUR\n+#undef ELAPSED_SECS_PER_DAY\n+#undef ELAPSED_SECS_PER_MON\n+#undef ELAPSED_SECS_PER_YEAR\n+\n+\tif (!pad && !y && !M && !d && !h && !m) {\n+\t\tstrbuf_addf(timebuf, \"%\"PRItime\"s\", s);\n+\t\treturn;\n+\t}\n+\n+\tif (pad) {\n+\t\tif (y) strbuf_addf(timebuf, \"%02\"PRItime\"y%c\", y, *sp);\n+\t\tif (y || M) strbuf_addf(timebuf, \"%02\"PRItime\"M%c\", M, *sp);\n+\t\tif (y || M || d) strbuf_addf(timebuf, \"%02\"PRItime\"d%c\", d, *sp);\n+\t\tif (y || M || d || h) strbuf_addf(timebuf, \"%02\"PRItime\"h%c\", h, *sp);\n+\t\tif (y || M || d || h || m) strbuf_addf(timebuf, \"%02\"PRItime\"m%c\", m, *sp);\n+\t\tstrbuf_addf(timebuf, \"%02\"PRItime\"s\", s);\n+\t} else {\n+\t\tif (y) strbuf_addf(timebuf, \"%\"PRItime\"y%c\", y, *sp);\n+\t\tif (M) strbuf_addf(timebuf, \"%\"PRItime\"M%c\", M, *sp);\n+\t\tif (d) strbuf_addf(timebuf, \"%\"PRItime\"d%c\", d, *sp);\n+\t\tif (h) strbuf_addf(timebuf, \"%\"PRItime\"h%c\", h, *sp);\n+\t\tif (m) strbuf_addf(timebuf, \"%\"PRItime\"m%c\", m, *sp);\n+\t\tstrbuf_addf(timebuf, \"%\"PRItime\"s\", s);\n+\t}\n+}\n+\n struct date_mode date_mode_from_type(enum date_mode_type type)\n {\n \tstruct date_mode mode = DATE_MODE_INIT;\n@@ -323,6 +396,12 @@ const char *show_date(timestamp_t time, int tz, struct date_mode mode)\n \t\treturn timebuf.buf;\n \t}\n \n+\tif (mode.type == DATE_ELAPSED || mode.type == DATE_ELAPSED_PAD) {\n+\t\tstrbuf_reset(&timebuf);\n+\t\tshow_date_elapsed(time, &timebuf, mode.type == DATE_ELAPSED_PAD);\n+\t\treturn timebuf.buf;\n+\t}\n+\n \tif (mode.local)\n \t\ttm = time_to_tm_local(time, &tmbuf);\n \telse\n@@ -1009,6 +1088,8 @@ static enum date_mode_type parse_date_type(const char *format, const char **end)\n \t\treturn DATE_RAW;\n \tif (skip_prefix(format, \"unix\", end))\n \t\treturn DATE_UNIX;\n+\tif (skip_prefix(format, \"elapsed\", end))\n+\t\treturn DATE_ELAPSED;\n \tif (skip_prefix(format, \"format\", end))\n \t\treturn DATE_STRFTIME;\n \t/*\n@@ -1038,7 +1119,12 @@ void parse_date_format(const char *format, struct date_mode *mode)\n \tmode->type = parse_date_type(format, &p);\n \tmode->local = 0;\n \n-\tif (skip_prefix(p, \"-local\", &p))\n+\tif (mode->type == DATE_ELAPSED) {\n+\t\tif (skip_prefix(p, \"-pad\", &p))\n+\t\t\tmode->type = DATE_ELAPSED_PAD;\n+\t\tif (*p)\n+\t\t\tdie(\"unknown date format %s\", format);\n+\t} else if (skip_prefix(p, \"-local\", &p))\n \t\tmode->local = 1;\n \n \tif (mode->type == DATE_STRFTIME) {\ndiff --git a/date.h b/date.h\nindex 0747864fd7..eb7f1fb6ad 100644\n--- a/date.h\n+++ b/date.h\n@@ -17,7 +17,9 @@ enum date_mode_type {\n \tDATE_RFC2822,\n \tDATE_STRFTIME,\n \tDATE_RAW,\n-\tDATE_UNIX\n+\tDATE_UNIX,\n+\tDATE_ELAPSED,\n+\tDATE_ELAPSED_PAD\n };\n \n struct date_mode {\ndiff --git a/pretty.c b/pretty.c\nindex d8a9f370f6..9ba274c64a 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -848,6 +848,9 @@ static size_t format_person_part(struct strbuf *sb, char part,\n \tcase 'h':\t/* date, human */\n \t\tstrbuf_addstr(sb, show_ident_date(&s, DATE_MODE(HUMAN)));\n \t\treturn placeholder_len;\n+\tcase 'X':\t/* date, elapsed */\n+\t\tstrbuf_addstr(sb, show_ident_date(&s, DATE_MODE(ELAPSED)));\n+\t\treturn placeholder_len;\n \tcase 's':\n \t\tstrbuf_addstr(sb, show_ident_date(&s, DATE_MODE(SHORT)));\n \t\treturn placeholder_len;\ndiff --git a/t/helper/test-date.c b/t/helper/test-date.c\nindex 87d2ad6fca..13101201d0 100644\n--- a/t/helper/test-date.c\n+++ b/t/helper/test-date.c\n@@ -11,7 +11,9 @@ static const char *const usage_msg = \"\\n\"\n \"  test-tool date timestamp [date]...\\n\"\n \"  test-tool date getnanos [start-nanos]\\n\"\n \"  test-tool date is64bit\\n\"\n-\"  test-tool date time_t-is64bit\\n\";\n+\"  test-tool date time_t-is64bit\\n\"\n+\"  test-tool date elapsed [time_t]...\\n\"\n+\"  test-tool date elapsed-pad [time_t]...\\n\";\n \n static void show_relative_dates(const char **argv)\n {\n@@ -33,6 +35,17 @@ static void show_human_dates(const char **argv)\n \t}\n }\n \n+static void show_elapsed_dates(const char **argv, int pad)\n+{\n+\tfor (; *argv; argv++) {\n+\t\ttime_t t = atoi(*argv);\n+\t\tstruct date_mode mode = DATE_MODE(ELAPSED);\n+\t\tif (pad)\n+\t\t\tmode = DATE_MODE(ELAPSED_PAD);\n+\t\tprintf(\"%s -> %s\\n\", *argv, show_date(t, 0, mode));\n+\t}\n+}\n+\n static void show_dates(const char **argv, const char *format)\n {\n \tstruct date_mode mode = DATE_MODE_INIT;\n@@ -115,6 +128,10 @@ int cmd__date(int argc UNUSED, const char **argv)\n \t\tshow_relative_dates(argv+1);\n \telse if (!strcmp(*argv, \"human\"))\n \t\tshow_human_dates(argv+1);\n+\telse if (!strcmp(*argv, \"elapsed\"))\n+\t\tshow_elapsed_dates(argv+1, 0);\n+\telse if (!strcmp(*argv, \"elapsed-pad\"))\n+\t\tshow_elapsed_dates(argv+1, 1);\n \telse if (skip_prefix(*argv, \"show:\", &x))\n \t\tshow_dates(argv+1, x);\n \telse if (!strcmp(*argv, \"parse\"))\ndiff --git a/t/t0006-date.sh b/t/t0006-date.sh\nindex 6e63130ea2..7b2bc2178b 100755\n--- a/t/t0006-date.sh\n+++ b/t/t0006-date.sh\n@@ -266,4 +266,47 @@ check_date_format_human 37500000 \"Jun 22 2008\" # 1 year, 2 months ago\n check_date_format_human 55188000 \"Dec 1 2007\" # 1 year, 9 months ago\n check_date_format_human 630000000 \"Sep 13 1989\" # 20 years ago\n \n+check_date_format_elapsed() {\n+\tt=$(($GIT_TEST_DATE_NOW - $1))\n+\tpad=$2\n+\texpect=$3\n+\tif test -n \"$pad\"\n+\tthen\n+\t\tdesc=\"elapsed-pad $t\"\n+\t\tcmd=\"elapsed-pad\"\n+\telse\n+\t\tdesc=\"elapsed $t\"\n+\t\tcmd=\"elapsed\"\n+\tfi\n+\techo \"$t -> $expect\" >expect\n+\ttest_expect_success \"$desc\" '\n+\t\tGIT_TEST_DATE_NOW=$GIT_TEST_DATE_NOW test-tool date '\"$cmd\"' $t >actual &&\n+\t\ttest_cmp expect actual\n+\t'\n+}\n+\n+# seconds-only\n+check_date_format_elapsed       5  '' \"5s\"\n+check_date_format_elapsed      39  '' \"39s\"\n+# minutes + seconds\n+check_date_format_elapsed      60  '' \"1m 0s\"\n+check_date_format_elapsed     984  '' \"16m 24s\"\n+# hours + minutes + seconds\n+check_date_format_elapsed    29268 '' \"8h 7m 48s\"\n+# months + days + hours + minutes + seconds (no year)\n+check_date_format_elapsed  3024000 '' \"1M 5d 0s\"\n+# years + everything\n+check_date_format_elapsed 37890313 '' \"1y 2M 13d 13h 5m 13s\"\n+check_date_format_elapsed 60527113 '' \"1y 11M 5d 13h 5m 13s\"\n+\n+# padded variant: same units but zero-padded to at least 2 digits\n+check_date_format_elapsed       5 1 \"05s\"\n+check_date_format_elapsed      39 1 \"39s\"\n+check_date_format_elapsed      60 1 \"01m 00s\"\n+check_date_format_elapsed     984 1 \"16m 24s\"\n+check_date_format_elapsed    29268 1 \"08h 07m 48s\"\n+check_date_format_elapsed  3024000 1 \"01M 05d 00h 00m 00s\"\n+check_date_format_elapsed 37890313 1 \"01y 02M 13d 13h 05m 13s\"\n+check_date_format_elapsed 60527113 1 \"01y 11M 05d 13h 05m 13s\"\n+\n test_done\ndiff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\nindex 4be5c51489..307be52b8f 100755\n--- a/t/t4205-log-pretty-formats.sh\n+++ b/t/t4205-log-pretty-formats.sh\n@@ -557,6 +557,12 @@ test_expect_success '--date=human %ad%cd is the same as %ah%ch' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success '--date=elapsed %ad%cd is the same as %aX%cX' '\n+\tgit log --format=%ad%n%cd --date=elapsed >expected &&\n+\tgit log --format=%aX%n%cX >actual &&\n+\ttest_cmp expected actual\n+'\n+\n # get new digests (with no abbreviations)\n test_expect_success 'set up log decoration tests' '\n \thead1=$(git rev-parse --verify HEAD~0) &&\n\nbase-commit: 13c7afec212fc97ce257d15601659314c6673d6c\n-- \ngitgitgadget\n"}]}