{"thread":{"id":"42937","subject":"[PATCH] pretty format string support for reflog times","startedAt":"2016-07-27T08:23:10Z","lastAt":"2016-07-27T19:57:33Z","messageCount":20,"participants":["Phil Pennock","Jeff King","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"292301","messageId":"20160727081414.GA21451@breadbox","threadId":"42937","inReplyTo":null,"subject":"[PATCH] pretty format string support for reflog times","fromName":"Phil Pennock","fromEmail":"phil@pennock-tech.com","sentAt":"2016-07-27T08:14:14Z","receivedAt":"2016-07-27T08:23:10Z","isPatch":true,"sender":{"key":"phil@pennock-tech.com","avatar":"https://gravatar.com/avatar/a80ead7f73b7a5869a407149e17d3ee635637a7a81f87899da8549a549603a50?d=mp&s=160"},"body":"The reflog contains timestamp information, but these were not exposed to\n`--pretty`.  Four of the six author/committer format string\nsecond-letters were still available and copied, but `d`/`D` are taken\nfor reflog selector formatting.  So use `%gT` for \"time\" instead of\n\"date\" mnemonic for using `--date=...` formatting.\n\nImplementation trade-off: could use `format_person_part()` if bounce\ninformation out of the reflog as a buffer-constructed string, then parse\nit back again, _and_ then use a hacky letter override for 'T' becoming\n'd'.  That would avoid reimplementing the specification of the five\nadded timestamp rendering cases.  Instead, we allow exporting the\ntimestamp information from the reflog, and if we get it, we add the same\ndata.  No memory alloc and string construction/parsing, a small amount\nof duplication of meaning.\n\nSigned-off-by: Phil Pennock <phil@pennock-tech.com>\n---\n pretty.c                      | 36 ++++++++++++++++++++++++++++++++++++\n reflog-walk.c                 | 16 ++++++++++++++++\n reflog-walk.h                 |  3 +++\n t/t4205-log-pretty-formats.sh | 26 ++++++++++++++++++++++++++\n 4 files changed, 81 insertions(+)\n\ndiff --git a/pretty.c b/pretty.c\nindex 9fa42c2..955baf1 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -1066,6 +1066,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */\n \tconst char *msg = c->message;\n \tstruct commit_list *p;\n \tint h1, h2;\n+\tunsigned long timestamp;\n+\tint tz;\n \n \t/* these are independent of the commit */\n \tswitch (placeholder[0]) {\n@@ -1212,6 +1214,40 @@ 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\t/*\n+\t\t * all the date options except those taken for other reflog handling\n+\t\t * (so not 'd' or 'D').\n+\t\t */\n+\t\tcase 'r':\n+\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n+\t\t\t\tstrbuf_addstr(sb, show_date(timestamp, tz, DATE_MODE(RELATIVE)));\n+\t\t\t}\n+\t\t\treturn 2;\n+\t\tcase 't':\n+\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n+\t\t\t\tstrbuf_addf(sb, \"%lu\", timestamp);\n+\t\t\t}\n+\t\t\treturn 2;\n+\t\tcase 'i':\n+\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n+\t\t\t\tstrbuf_addstr(sb, show_date(timestamp, tz, DATE_MODE(ISO8601)));\n+\t\t\t}\n+\t\t\treturn 2;\n+\t\tcase 'I':\n+\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n+\t\t\t\tstrbuf_addstr(sb, show_date(timestamp, tz, DATE_MODE(ISO8601_STRICT)));\n+\t\t\t}\n+\t\t\treturn 2;\n+\t\t/*\n+\t\t * reflog d/D are taken, so we can't use those for dates\n+\t\t * but we do want to support using --date= format overrides\n+\t\t * so we steal 'T' for those ('time' instead of 'date')\n+\t\t */\n+\t\tcase 'T':\n+\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n+\t\t\t\tstrbuf_addstr(sb, show_date(timestamp, tz, &c->pretty_ctx->date_mode));\n+\t\t\t}\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..bb9cbf8 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -309,6 +309,22 @@ void get_reflog_message(struct strbuf *sb,\n \tstrbuf_add(sb, info->message, len);\n }\n \n+int get_reflog_timeinfo(unsigned long *timestamp_out,\n+\t\t\t int *tz_out,\n+\t\t\t struct reflog_walk_info *reflog_info)\n+{\n+\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n+\tstruct reflog_info *info;\n+\n+\tif (!commit_reflog)\n+\t\treturn 0;\n+\n+\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n+\t*timestamp_out = info->timestamp;\n+\t*tz_out = info->tz;\n+\treturn 1;\n+}\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;\ndiff --git a/reflog-walk.h b/reflog-walk.h\nindex 27886f7..a368c72 100644\n--- a/reflog-walk.h\n+++ b/reflog-walk.h\n@@ -19,5 +19,8 @@ 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 \t\tint shorten);\n+extern int get_reflog_timeinfo(unsigned long *timestamp_out,\n+\t\tint *tz_out,\n+\t\tstruct reflog_walk_info *reflog_info);\n \n #endif\ndiff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\nindex d9f6242..9d211ab 100755\n--- a/t/t4205-log-pretty-formats.sh\n+++ b/t/t4205-log-pretty-formats.sh\n@@ -533,4 +533,30 @@ EOF\n \ttest_cmp expected actual1\n '\n \n+refhead1_short=$(git rev-parse --short --verify HEAD@{0}) &&\n+refhead2_short=$(git rev-parse --short --verify HEAD@{1}) &&\n+\n+test_expect_success 'can access the reflog' '\n+\tgit reflog -n 2 >actual &&\n+\tcat >expected <<EOF &&\n+$refhead1_short HEAD@{0}: commit (amend): shorter\n+$refhead2_short HEAD@{1}: commit (amend): short\n+EOF\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'reflog tformat timestamps work' '\n+\tgit log -g -n 2 \\\n+\t\t--pretty=tformat:\"%h %gd / %gr %gt%n %gi %gI%n %gT : %gs\" > actual &&\n+\tcat >expected <<EOF &&\n+$refhead1_short HEAD@{0} / 11 years ago 1112912173\n+ 2005-04-07 15:16:13 -0700 2005-04-07T15:16:13-07:00\n+ Thu Apr 7 15:16:13 2005 -0700 : commit (amend): shorter\n+$refhead2_short HEAD@{1} / 11 years ago 1112912173\n+ 2005-04-07 15:16:13 -0700 2005-04-07T15:16:13-07:00\n+ Thu Apr 7 15:16:13 2005 -0700 : commit (amend): short\n+EOF\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n2.9.2.466.g8c6d1f9.dirty\n\n"},{"id":"292309","messageId":"20160727120210.GA22669@breadbox","threadId":"42937","inReplyTo":"20160727081414.GA21451@breadbox","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Phil Pennock","fromEmail":"phil@pennock-tech.com","sentAt":"2016-07-27T12:02:11Z","receivedAt":"2016-07-27T12:02:22Z","isPatch":true,"sender":{"key":"phil@pennock-tech.com","avatar":"https://gravatar.com/avatar/a80ead7f73b7a5869a407149e17d3ee635637a7a81f87899da8549a549603a50?d=mp&s=160"},"body":"On 2016-07-27 at 04:14 -0400, Phil Pennock wrote:\n>  pretty.c                      | 36 ++++++++++++++++++++++++++++++++++++\n>  reflog-walk.c                 | 16 ++++++++++++++++\n>  reflog-walk.h                 |  3 +++\n>  t/t4205-log-pretty-formats.sh | 26 ++++++++++++++++++++++++++\n>  4 files changed, 81 insertions(+)\n\nAfter sleep, I realized that while I included tests I forgot to update\nthe docs.  Those will go into a v2 of the patch; sorry about that.\n\nFeedback sought upon everything _else_ wrong with this which should be\naddressed in v2.\n\n[apologies to explicit CC'd who may see this twice; apparently the\n mobile client for this mail-provider infests messages with HTML with no\n option to disable]\n\n-Phil Pennock\n"},{"id":"292315","messageId":"20160727135820.GC14928@sigill.intra.peff.net","threadId":"42937","inReplyTo":"20160727081414.GA21451@breadbox","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T13:58:20Z","receivedAt":"2016-07-27T13:58:29Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jul 27, 2016 at 04:14:14AM -0400, Phil Pennock wrote:\n\n> The reflog contains timestamp information, but these were not exposed to\n> `--pretty`.  Four of the six author/committer format string\n> second-letters were still available and copied, but `d`/`D` are taken\n> for reflog selector formatting.  So use `%gT` for \"time\" instead of\n> \"date\" mnemonic for using `--date=...` formatting.\n\nHrm. Since Ted was not cc'd, it is not clear to me whether this is\ncoincidental or in response to the thread over in\n\n  http://thread.gmane.org/gmane.comp.version-control.git/299201\n\nTo summarize, I think the conclusion there was that we would go with at\nleast the 't' and 'r' formatters in the short term. The 'i/I' ones were\nnot something Ted cared about that much, I think, but they do make\nthings orthogonal with the other ident dates.\n\nYour '%gT' seems like a nice idea in principle, though I'm not sure it\nis all that useful due to the way that --date impacts %gd.  In other\nwords:\n\n  git log -g --format=%gd --date=rfc\n\nwill already respect --date (albeit with \"ref@{...}\" wrapped around it).\nBut even with your patch, you cannot do:\n\n  git log -g --format=\"%gd %gT\" --date=rfc\n\nto get \"HEAD@{0} ...rfc-date...\", because the presence of \"--date\" is\nthe trigger to switch the meaning of \"%gd\".\n\nSo the final solution is more like:\n\n  - a formatter for just the reflog time, respecting date\n\n  - a formatter for just the reflog index (the \"0\" in HEAD@{0})\n\n  - a formatter for the ref name (just the \"HEAD\" in HEAD@{0})\n\nAnd I'm not sure if we want to do that now with a bunch of arcane\ntwo-letter placeholders, or wait for a refactoring where they can get\nmore readable names like %(reflog-index).\n\n-Peff\n"},{"id":"292317","messageId":"1469629060.2278222.678276953.09D0768E@webmail.messagingengine.com","threadId":"42937","inReplyTo":"20160727135820.GC14928@sigill.intra.peff.net","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Phil Pennock","fromEmail":"phil@pennock-tech.com","sentAt":"2016-07-27T14:17:40Z","receivedAt":"2016-07-27T14:17:46Z","isPatch":true,"sender":{"key":"phil@pennock-tech.com","avatar":"https://gravatar.com/avatar/a80ead7f73b7a5869a407149e17d3ee635637a7a81f87899da8549a549603a50?d=mp&s=160"},"body":"On Wed, Jul 27, 2016, at 09:58, Jeff King wrote:\n> On Wed, Jul 27, 2016 at 04:14:14AM -0400, Phil Pennock wrote:\n> > The reflog contains timestamp information, but these were not exposed to\n> > `--pretty`.  Four of the six author/committer format string\n> > second-letters were still available and copied, but `d`/`D` are taken\n> > for reflog selector formatting.  So use `%gT` for \"time\" instead of\n> > \"date\" mnemonic for using `--date=...` formatting.\n> \n> Hrm. Since Ted was not cc'd, it is not clear to me whether this is\n> coincidental or in response to the thread over in\n> \n>   http://thread.gmane.org/gmane.comp.version-control.git/299201\n\nCoincidental, I was unaware of that.  Sorry for the duplication.  Please\nignore my patch, I'm not going to even try to compete with Mr Ts'o.\n\nI asked a friend who is a git developer why this wasn't available, he\nsaid it would be fairly easy to do, I asked if he was trying to suck me\ninto contributing patches to git, he said yes.  I neglected to search\narchives for myself.\n\nBesides \"two independent submissions in short space of time\" as evidence\nthat this functionality is wanted, my real-world motivator was: `go get\n$something` failed, until I told the Golang tooling to update\ndependencies too; after that I wanted to easily see when the dependency\nwas last updated on my local system and ended up having to look at the\nreflog on disk and manually convert timestamps.\n\n> To summarize, I think the conclusion there was that we would go with at\n> least the 't' and 'r' formatters in the short term.\n\n'r' and one of the non-relative renderers are the ones I put into a\n`[pretty]` item for my use.\n\n> to get \"HEAD@{0} ...rfc-date...\", because the presence of \"--date\" is\n> the trigger to switch the meaning of \"%gd\".\n\nYes, I went for completeness even though it led to some duplication, and\ntested them all. Though it looks like I didn't include the --date\nmodifications into the test-suite example.  Oops.\n\nThanks for the review and the cluebat.\n-Phil\n"},{"id":"292333","messageId":"xmqqwpk7vw30.fsf@gitster.mtv.corp.google.com","threadId":"42937","inReplyTo":"20160727135820.GC14928@sigill.intra.peff.net","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-07-27T17:18:11Z","receivedAt":"2016-07-27T17:18:19Z","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> On Wed, Jul 27, 2016 at 04:14:14AM -0400, Phil Pennock wrote:\n>\n>> The reflog contains timestamp information, but these were not exposed to\n>> `--pretty`.  Four of the six author/committer format string\n>> second-letters were still available and copied, but `d`/`D` are taken\n>> for reflog selector formatting.  So use `%gT` for \"time\" instead of\n>> \"date\" mnemonic for using `--date=...` formatting.\n>\n> Hrm. Since Ted was not cc'd, it is not clear to me whether this is\n> coincidental or in response to the thread over in\n>\n>   http://thread.gmane.org/gmane.comp.version-control.git/299201\n>\n> To summarize, I think the conclusion there was that we would go with at\n> least the 't' and 'r' formatters in the short term. The 'i/I' ones were\n> not something Ted cared about that much, I think, but they do make\n> things orthogonal with the other ident dates.\n\nI forgot about that thread after it stalled without drawing\nconclusion, after Ted asked if anybody has a strong opinion\nand saw only one response to it at\n\n  https://public-inbox.org/git/20160711164317.GB3890%40thunk.org/\n\nSo, what is the next step?  Apply\n\n  https://public-inbox.org/git/20160710055402.32684-1-tytso%40mit.edu/\n\nbut exclude %g[iI] bits out of that patch while doing so?\n\nThanks.\n\n"},{"id":"292338","messageId":"20160727173915.GA32219@sigill.intra.peff.net","threadId":"42937","inReplyTo":"xmqqwpk7vw30.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T17:39:15Z","receivedAt":"2016-07-27T17:39:22Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jul 27, 2016 at 10:18:11AM -0700, Junio C Hamano wrote:\n\n> > Hrm. Since Ted was not cc'd, it is not clear to me whether this is\n> > coincidental or in response to the thread over in\n> >\n> >   http://thread.gmane.org/gmane.comp.version-control.git/299201\n> >\n> > To summarize, I think the conclusion there was that we would go with at\n> > least the 't' and 'r' formatters in the short term. The 'i/I' ones were\n> > not something Ted cared about that much, I think, but they do make\n> > things orthogonal with the other ident dates.\n> \n> I forgot about that thread after it stalled without drawing\n> conclusion, after Ted asked if anybody has a strong opinion\n> and saw only one response to it at\n> \n>   https://public-inbox.org/git/20160711164317.GB3890%40thunk.org/\n> \n> So, what is the next step?  Apply\n> \n>   https://public-inbox.org/git/20160710055402.32684-1-tytso%40mit.edu/\n> \n> but exclude %g[iI] bits out of that patch while doing so?\n\nAfter having thought about it, I'm inclined to leave in the \"%gi\".\nThere's no real rationale for doing \"%gr\" and \"%gt\" and not \"%gi\" except\n\"well, Ted didn't need it\". And it does make it match the author and\ncommitter date-formatting (except for the 'd' formats, of course).\n\nI do think with the new \"unix\" format in jk/reflog-date, the interface\nto the reflog code could be simplified; we don't need a function to pull\nout just the timestamp any more. Something like the diff below.\n\nHowever, I see a few remaining issues with Ted's original:\n\n  - the refactored get_reflog_message() tries to return NULL, but the\n    return type of the function is void. Presumably this should just be\n    \"return\"?\n\n  - ditto, the new get_reflog_time_t returns NULL, but wants an unsigned\n    long (though this function goes away with my squash below)\n\n  - show_reflog_date can return NULL, but we blindly feed its return\n    value to strbuf_addstr(). I'm not sure under what conditions it\n    _would_ return NULL, but that would cause a segfault\n\n  - there should probably be tests in t6006 for the new formats\n\n  - my squash below cuts out the use of gm_time_t(). But I don't think\n    it should be necessary, as the reflog timestamp should already be in\n    GMT, I would think. But maybe I am missing something.\n\nI actually think Phil's patch from today is a little cleaner for most of\nthese, as it returns the values via out-parameters, and uses the return\nvalue for \"did we get anything?\".\n\n-Peff\n"},{"id":"292341","messageId":"xmqqk2g7vurb.fsf@gitster.mtv.corp.google.com","threadId":"42937","inReplyTo":"xmqqwpk7vw30.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-07-27T17:46:48Z","receivedAt":"2016-07-27T17:46:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>> Hrm. Since Ted was not cc'd, it is not clear to me whether this is\n>> coincidental or in response to the thread over in\n>>\n>>   http://thread.gmane.org/gmane.comp.version-control.git/299201\n>>\n>> To summarize, I think the conclusion there was that we would go with at\n>> least the 't' and 'r' formatters in the short term. The 'i/I' ones were\n>> not something Ted cared about that much, I think, but they do make\n>> things orthogonal with the other ident dates.\n>\n> I forgot about that thread after it stalled without drawing\n> conclusion, after Ted asked if anybody has a strong opinion\n> and saw only one response to it at\n>\n>   https://public-inbox.org/git/20160711164317.GB3890%40thunk.org/\n>\n> So, what is the next step?  Apply\n>\n>   https://public-inbox.org/git/20160710055402.32684-1-tytso%40mit.edu/\n>\n> but exclude %g[iI] bits out of that patch while doing so?\n\nFWIW, a squash to do so is trivial, but the original had two\ncompiler breakers.\n\nI am not sure about the latter, i.e. the return value from the\nget_reflog_time_t() function (which I think is misnamed, in that the\nfunction returns \"unsigned long\", not \"time_t\", and should be\nrenamed to get_reflog_time()) uses the epoch as a fallback value.\n\n\n\n reflog-walk.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex d0aa2d0..51bfe29 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -309,7 +309,7 @@ void get_reflog_message(struct strbuf *sb,\n \tsize_t len;\n \n \tif (!info)\n-\t\treturn NULL;\n+\t\treturn;\n \tlen = strlen(info->message);\n \tif (len > 0)\n \t\tlen--; /* strip away trailing newline */\n@@ -330,7 +330,7 @@ unsigned long get_reflog_time_t(struct reflog_walk_info *reflog_info)\n \tstruct reflog_info *info = get_reflog_info(reflog_info);\n \n \tif (!info)\n-\t\treturn NULL;\n+\t\treturn 0;\n \treturn gm_time_t(info->timestamp, info->tz);\n }\n \n"},{"id":"292343","messageId":"20160727175622.GA9961@sigill.intra.peff.net","threadId":"42937","inReplyTo":"20160727081414.GA21451@breadbox","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T17:56:23Z","receivedAt":"2016-07-27T17:56:31Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jul 27, 2016 at 04:14:14AM -0400, Phil Pennock wrote:\n\n> The reflog contains timestamp information, but these were not exposed to\n> `--pretty`.  Four of the six author/committer format string\n> second-letters were still available and copied, but `d`/`D` are taken\n> for reflog selector formatting.  So use `%gT` for \"time\" instead of\n> \"date\" mnemonic for using `--date=...` formatting.\n\nSo as I mentioned before, this is similar to another recent patch. But I\nkind of like this one better, so let me give this one a more thorough\nreview.\n\n> Implementation trade-off: could use `format_person_part()` if bounce\n> information out of the reflog as a buffer-constructed string, then parse\n> it back again, _and_ then use a hacky letter override for 'T' becoming\n> 'd'.  That would avoid reimplementing the specification of the five\n> added timestamp rendering cases.  Instead, we allow exporting the\n> timestamp information from the reflog, and if we get it, we add the same\n> data.  No memory alloc and string construction/parsing, a small amount\n> of duplication of meaning.\n\nI think this is a good tradeoff. Even if you handled 'd' in a hacky way\nnow, you _don't_ want to \"%g*\" to magically grow to learn new placeholders\nthat \"%a*\" does, as they might conflict with other \"%g\" formats in the\nsame way that \"%gd\" (i.e., we would need to do a hacky workaround for\n_those_ too, but nothing would warn the person adding the new\nplaceholders).\n\n> +\t\t/*\n> +\t\t * all the date options except those taken for other reflog handling\n> +\t\t * (so not 'd' or 'D').\n> +\t\t */\n> +\t\tcase 'r':\n> +\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n> +\t\t\t\tstrbuf_addstr(sb, show_date(timestamp, tz, DATE_MODE(RELATIVE)));\n> +\t\t\t}\n> +\t\t\treturn 2;\n> +\t\tcase 't':\n> +\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n> +\t\t\t\tstrbuf_addf(sb, \"%lu\", timestamp);\n> +\t\t\t}\n> +\t\t\treturn 2;\n> +\t\tcase 'i':\n> +\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n> +\t\t\t\tstrbuf_addstr(sb, show_date(timestamp, tz, DATE_MODE(ISO8601)));\n> +\t\t\t}\n> +\t\t\treturn 2;\n> +\t\tcase 'I':\n> +\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n> +\t\t\t\tstrbuf_addstr(sb, show_date(timestamp, tz, DATE_MODE(ISO8601_STRICT)));\n> +\t\t\t}\n> +\t\t\treturn 2;\n\nThese all look good. If for whatever reason we don't have a reflog\nentry, we write nothing (but still eat the placeholder), which seems\nsensible.\n\nOne alternative interface would be more like get_reflog_message(), where\nit either puts something in a strbuf or not. And then your calls would\nlook like:\n\n  get_reflog_date(sb, c->pretty_cx->reflog_info, DATE_MODE(ISO8601));\n\nor whatever. Your way here is more flexible, though, if we ever add more\ncallers.\n\n> +\t\t/*\n> +\t\t * reflog d/D are taken, so we can't use those for dates\n> +\t\t * but we do want to support using --date= format overrides\n> +\t\t * so we steal 'T' for those ('time' instead of 'date')\n> +\t\t */\n> +\t\tcase 'T':\n> +\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n> +\t\t\t\tstrbuf_addstr(sb, show_date(timestamp, tz, &c->pretty_ctx->date_mode));\n> +\t\t\t}\n> +\t\t\treturn 2;\n>  \t\t}\n\nI think we can drop this one. It's a nice direction to go eventually,\nbut without the extra placeholders I mentioned elsewhere, it doesn't buy\nus much.\n\n> +int get_reflog_timeinfo(unsigned long *timestamp_out,\n> +\t\t\t int *tz_out,\n> +\t\t\t struct reflog_walk_info *reflog_info)\n> +{\n> +\tstruct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;\n> +\tstruct reflog_info *info;\n> +\n> +\tif (!commit_reflog)\n> +\t\treturn 0;\n> +\n> +\tinfo = &commit_reflog->reflogs->items[commit_reflog->recno+1];\n> +\t*timestamp_out = info->timestamp;\n> +\t*tz_out = info->tz;\n> +\treturn 1;\n> +}\n\nOur usual error-return is \"0 is success\", \"-1 is error\".\n\nThough we don't _always_ adhere to that, and I won't be surprised if you\nsimply copied this from other nearby code.\n\n> diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\n> index d9f6242..9d211ab 100755\n> --- a/t/t4205-log-pretty-formats.sh\n> +++ b/t/t4205-log-pretty-formats.sh\n> @@ -533,4 +533,30 @@ EOF\n>  \ttest_cmp expected actual1\n>  '\n>  \n> +refhead1_short=$(git rev-parse --short --verify HEAD@{0}) &&\n> +refhead2_short=$(git rev-parse --short --verify HEAD@{1}) &&\n\nWe try to push as much as possible into a test_expect_success block,\nsince it handles things like unexpected output to stderr. I guess you\nput these outside because they are used in multiple tests. You don't\nhave to do that, because tests can affect the greater environment. But\nif you do keep something outside of a test, you _don't_ want to use\n&&-chaining, as it means that the lines below it (i.e., the next test!)\nwould simply not be run at all.\n\nBut...\n\n> +test_expect_success 'can access the reflog' '\n> +\tgit reflog -n 2 >actual &&\n> +\tcat >expected <<EOF &&\n> +$refhead1_short HEAD@{0}: commit (amend): shorter\n> +$refhead2_short HEAD@{1}: commit (amend): short\n> +EOF\n> +\ttest_cmp expected actual\n> +'\n\nI'm not sure what this is testing. Just that we have reflogs turned on\nat all? I think we can skip this, as it's implicit in the\nreflog-formatting test below.\n\nAnd then you can move your environment variables down into that test\n(though see below).\n\n> +test_expect_success 'reflog tformat timestamps work' '\n> +\tgit log -g -n 2 \\\n> +\t\t--pretty=tformat:\"%h %gd / %gr %gt%n %gi %gI%n %gT : %gs\" > actual &&\n> +\tcat >expected <<EOF &&\n> +$refhead1_short HEAD@{0} / 11 years ago 1112912173\n> + 2005-04-07 15:16:13 -0700 2005-04-07T15:16:13-07:00\n> + Thu Apr 7 15:16:13 2005 -0700 : commit (amend): shorter\n> +$refhead2_short HEAD@{1} / 11 years ago 1112912173\n> + 2005-04-07 15:16:13 -0700 2005-04-07T15:16:13-07:00\n> + Thu Apr 7 15:16:13 2005 -0700 : commit (amend): short\n> +EOF\n> +\ttest_cmp expected actual\n> +'\n\nYou can use \"<<-\" to ask the shell to strip leading tabs from the\nhere-doc. And then you can indent the contents to match the rest of the\ntest.\n\nI kind of wonder if it would be better to drop \"%h\" from your format,\ntoo. You're just testing the timestamps, and handling the shortening is\ncluttering up the test. So maybe just:\n\n  test_expect_success 'reflog tformat timestamps work' '\n\tcat >expected <<-\\EOF &&\n\tHEAD@{0}\n\t11 years ago\n\t1112912173\n\t2005-04-07 15:16:13 -0700\n\t2005-04-07T15:16:13-07:00\n\n\tHEAD@{1}\n\t11 years ago\n\t1112912173\n\t2005-04-07 15:16:13 -0700\n\t2005-04-07T15:16:13-07:00\n\tEOF\n\tgit log -g -2 --format=\"%gd%n%gr%n%gt%n%gi%n%gI%n\" >actual &&\n\ttest_cmp expected actual\n  '\n\n(I did a few more tweaks to the format to hopefully make it easier to\nread). It would probably be a more interesting test if the two reflogs\nactually had different timestamps, though.\n\nAlso, come to think of it, that \"%gr\" test is going to break in about\nyear. :-/\n\nWe do test relative date formatting via test-date, which can take a\nspecial value for \"when is now\", but you can't do so via regular\ngit-log. So the best we could do is check \"%gr\" separately and just make\nsure that it output _something_.\n\n-Peff\n"},{"id":"292344","messageId":"20160727175800.GB32219@sigill.intra.peff.net","threadId":"42937","inReplyTo":"xmqqk2g7vurb.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T17:58:00Z","receivedAt":"2016-07-27T17:58:08Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jul 27, 2016 at 10:46:48AM -0700, Junio C Hamano wrote:\n\n> I am not sure about the latter, i.e. the return value from the\n> get_reflog_time_t() function (which I think is misnamed, in that the\n> function returns \"unsigned long\", not \"time_t\", and should be\n> renamed to get_reflog_time()) uses the epoch as a fallback value.\n> [...]\n> @@ -330,7 +330,7 @@ unsigned long get_reflog_time_t(struct reflog_walk_info *reflog_info)\n>  \tstruct reflog_info *info = get_reflog_info(reflog_info);\n>  \n>  \tif (!info)\n> -\t\treturn NULL;\n> +\t\treturn 0;\n>  \treturn gm_time_t(info->timestamp, info->tz);\n>  }\n\nOur mails just crossed, but I think returning even \"0\" is not ideal. We\nshould probably write nothing to match things like \"%gd\" and \"%gs\",\nwhich just eat the placeholder and show nothing when they cannot access\nthe reflog.\n\n-Peff\n"},{"id":"292349","messageId":"xmqqfuqvvtph.fsf@gitster.mtv.corp.google.com","threadId":"42937","inReplyTo":"20160727173915.GA32219@sigill.intra.peff.net","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-07-27T18:09:30Z","receivedAt":"2016-07-27T18:09:37Z","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> I actually think Phil's patch from today is a little cleaner for most of\n> these, as it returns the values via out-parameters, and uses the return\n> value for \"did we get anything?\".\n\nTrue.  That part of the interface is indeed better done with the new\none.\n\nI am still in favor of this suggestion you earlier made:\n\n> So the final solution is more like:\n> \n>   - a formatter for just the reflog time, respecting date\n> \n>   - a formatter for just the reflog index (the \"0\" in HEAD@{0})\n> \n>   - a formatter for the ref name (just the \"HEAD\" in HEAD@{0})\n\nthough.  After all we only need three short ones while we migrate\naway to a longer %(reflog:<what>) format, right?\n\nAs to the unfortunate %gd that squats on the \"date\" other specifiers\nuse, I do not see a good/quick approach to migrate it.  If our ideal\nshort-term endgame before the longer format were to use %gd, %g# and\n%gg for the above three, we first start warning people who use %gd\nfor the historical mistaken \"reflog selector\", while telling people\nto use \"%gg@{%g#}\" instead if they truly want \"reflog selector\", and\nthen switch its meaning to \"reflog date\".  That would take a long\ntime.\n\nAs %r prefix is not taken, we can immediately deprecate %g-anything\nformat as a historical mistake and make sure we do not repeat the\nmistake of giving \"d\" to \"reflog selector\", perhaps?\n"},{"id":"292351","messageId":"20160727181334.GA24224@tower.spodhuis.org","threadId":"42937","inReplyTo":"20160727175622.GA9961@sigill.intra.peff.net","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Phil Pennock","fromEmail":"phil@pennock-tech.com","sentAt":"2016-07-27T18:13:34Z","receivedAt":"2016-07-27T18:13:42Z","isPatch":true,"sender":{"key":"phil@pennock-tech.com","avatar":"https://gravatar.com/avatar/a80ead7f73b7a5869a407149e17d3ee635637a7a81f87899da8549a549603a50?d=mp&s=160"},"body":"On 2016-07-27 at 13:56 -0400, Jeff King wrote:\n> On Wed, Jul 27, 2016 at 04:14:14AM -0400, Phil Pennock wrote:\n> > +\t\t */\n> > +\t\tcase 'T':\n> > +\t\t\tif (get_reflog_timeinfo(&timestamp, &tz, c->pretty_ctx->reflog_info)) {\n> > +\t\t\t\tstrbuf_addstr(sb, show_date(timestamp, tz, &c->pretty_ctx->date_mode));\n> > +\t\t\t}\n> > +\t\t\treturn 2;\n> >  \t\t}\n> \n> I think we can drop this one. It's a nice direction to go eventually,\n> but without the extra placeholders I mentioned elsewhere, it doesn't buy\n> us much.\n\nWill do.\n\n> Our usual error-return is \"0 is success\", \"-1 is error\".\n\nThe idea was \"boolean function\" and adding more negations elsewhere just\nmade things ugly.  I can change if you really want, as consistency wins,\nbut I'll be holding my nose as the invoker flow becomes:\n\n    if (! function_call(out_params)) {\n      use(out_params);\n    }\n\nwhich is counter-intuitive (but then, I do much less C these days and\nhave been corrupted).  So I'll hold off for now, until told otherwise.\n\n> Though we don't _always_ adhere to that, and I won't be surprised if you\n> simply copied this from other nearby code.\n\nNot _this_ one ..\n\n> > +refhead1_short=$(git rev-parse --short --verify HEAD@{0}) &&\n> > +refhead2_short=$(git rev-parse --short --verify HEAD@{1}) &&\n> \n> We try to push as much as possible into a test_expect_success block,\n> since it handles things like unexpected output to stderr. I guess you\n> put these outside because they are used in multiple tests. You don't\n> have to do that, because tests can affect the greater environment. But\n> if you do keep something outside of a test, you _don't_ want to use\n> &&-chaining, as it means that the lines below it (i.e., the next test!)\n> would simply not be run at all.\n\nThis however was matching existing style for `head1` and `head2` a\nlittle above.  I was somewhat surprised.\n\n> > +test_expect_success 'can access the reflog' '\n> > +\tgit reflog -n 2 >actual &&\n> > +\tcat >expected <<EOF &&\n> > +$refhead1_short HEAD@{0}: commit (amend): shorter\n> > +$refhead2_short HEAD@{1}: commit (amend): short\n> > +EOF\n> > +\ttest_cmp expected actual\n> > +'\n> \n> I'm not sure what this is testing. Just that we have reflogs turned on\n> at all? I think we can skip this, as it's implicit in the\n> reflog-formatting test below.\n\nDisagree: I could see no existing tests for reflog content matching an\nexpected layout (but could have missed one; I see some _using_ reflog).\nIf adding a test for minutiae of how tuning options adjust the output,\nand something changes which breaks the output more widely, the person\ninvestigating can spend a lot of time investigating a red herring,\nlooking to see what they broke in the `--pretty` handling.\n\nFirst test the basics, then test the specifics, so that if the basics\nbreak too then the developer is naturally led to the correct thing to\ninvestigate instead of their only clue being that specifics broke.\n\n> You can use \"<<-\" to ask the shell to strip leading tabs from the\n> here-doc. And then you can indent the contents to match the rest of the\n> test.\n\nYou can, but it's fragile if tabs become spaces and it isn't consistent\nwith the existing tests above.\n\n> I kind of wonder if it would be better to drop \"%h\" from your format,\n> too. You're just testing the timestamps, and handling the shortening is\n> cluttering up the test. So maybe just:\n\nThis makes a lot of sense.\n\n> (I did a few more tweaks to the format to hopefully make it easier to\n> read). It would probably be a more interesting test if the two reflogs\n> actually had different timestamps, though.\n\nIs there a way to force that, through the normalizations?\n\n> Also, come to think of it, that \"%gr\" test is going to break in about\n> year. :-/\n\nOh crap, I saw the normalization and thought everything was being set to\nspecifics, but of course the relative is against now.  Good catch,\nthanks.  How about:\n\n    | sed \"s/[1-9][0-9]* years/N years/\"\n\nand then test against \"N years\" in expected?\n\n-Phil\n"},{"id":"292352","messageId":"20160727181725.GD32219@sigill.intra.peff.net","threadId":"42937","inReplyTo":"xmqqfuqvvtph.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T18:17:26Z","receivedAt":"2016-07-27T18:17:32Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jul 27, 2016 at 11:09:30AM -0700, Junio C Hamano wrote:\n\n> I am still in favor of this suggestion you earlier made:\n> \n> > So the final solution is more like:\n> > \n> >   - a formatter for just the reflog time, respecting date\n> > \n> >   - a formatter for just the reflog index (the \"0\" in HEAD@{0})\n> > \n> >   - a formatter for the ref name (just the \"HEAD\" in HEAD@{0})\n> \n> though.  After all we only need three short ones while we migrate\n> away to a longer %(reflog:<what>) format, right?\n\nYes, I think those three would be sufficient to allow something like:\n\n  HEAD@{0} (1 month ago) ...\n\nwhere the relative time would come from \"%gT\" mixed with\n\"--date=relative\". What that doesn't allow is showing the time in\nmultiple formats with different placeholders, like:\n\n  HEAD@{0} (2016-06-25T01:23:45 -- 1 month ago) ...\n\nFor that you need either format-specific placeholders, or a generic date\nplaceholder which can specify the format, like:\n\n  %(reflog-date:relative)\n\nSo if you mean doing those on _top_ of what Phil and Ted are proposing,\nI think it is pretty flexible, but just a bit ugly. But doing it\n_instead_ would not allow the format Ted wanted.\n\n> As to the unfortunate %gd that squats on the \"date\" other specifiers\n> use, I do not see a good/quick approach to migrate it.  If our ideal\n> short-term endgame before the longer format were to use %gd, %g# and\n> %gg for the above three, we first start warning people who use %gd\n> for the historical mistaken \"reflog selector\", while telling people\n> to use \"%gg@{%g#}\" instead if they truly want \"reflog selector\", and\n> then switch its meaning to \"reflog date\".  That would take a long\n> time.\n\nI don't think it's worth the deprecation effort and confusion.\n\n> As %r prefix is not taken, we can immediately deprecate %g-anything\n> format as a historical mistake and make sure we do not repeat the\n> mistake of giving \"d\" to \"reflog selector\", perhaps?\n\nMoving to \"%r\" as a more sensible prefix for \"reflog\", while cleaning up\nhistorical mistakes, is more appealing. But if we really are planning to\nmove to \"%(reflog-*)\", then I think we can just forget about \"%r\"\nentirely.\n\nI just don't think anybody has volunteered to work on %(reflog).\n\n-Peff\n"},{"id":"292353","messageId":"20160727183203.GE32219@sigill.intra.peff.net","threadId":"42937","inReplyTo":"20160727181334.GA24224@tower.spodhuis.org","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T18:32:03Z","receivedAt":"2016-07-27T18:32:13Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jul 27, 2016 at 06:13:34PM +0000, Phil Pennock wrote:\n\n> > Our usual error-return is \"0 is success\", \"-1 is error\".\n> \n> The idea was \"boolean function\" and adding more negations elsewhere just\n> made things ugly.  I can change if you really want, as consistency wins,\n> but I'll be holding my nose as the invoker flow becomes:\n> \n>     if (! function_call(out_params)) {\n>       use(out_params);\n>     }\n> \n> which is counter-intuitive (but then, I do much less C these days and\n> have been corrupted).  So I'll hold off for now, until told otherwise.\n\nYeah, I agree the \"!\" test for \"did it work\" is counter-intuitive if you're\ncoming from other languages, but it's pretty normal for C code bases\n(especially ours).\n\n> > > +refhead1_short=$(git rev-parse --short --verify HEAD@{0}) &&\n> > > +refhead2_short=$(git rev-parse --short --verify HEAD@{1}) &&\n> > \n> > We try to push as much as possible into a test_expect_success block,\n> > since it handles things like unexpected output to stderr. I guess you\n> > put these outside because they are used in multiple tests. You don't\n> > have to do that, because tests can affect the greater environment. But\n> > if you do keep something outside of a test, you _don't_ want to use\n> > &&-chaining, as it means that the lines below it (i.e., the next test!)\n> > would simply not be run at all.\n> \n> This however was matching existing style for `head1` and `head2` a\n> little above.  I was somewhat surprised.\n\nAh. Yeah, those are wrong and bad. We should fix that.\n\n> > > +test_expect_success 'can access the reflog' '\n> > > +\tgit reflog -n 2 >actual &&\n> > > +\tcat >expected <<EOF &&\n> > > +$refhead1_short HEAD@{0}: commit (amend): shorter\n> > > +$refhead2_short HEAD@{1}: commit (amend): short\n> > > +EOF\n> > > +\ttest_cmp expected actual\n> > > +'\n> > \n> > I'm not sure what this is testing. Just that we have reflogs turned on\n> > at all? I think we can skip this, as it's implicit in the\n> > reflog-formatting test below.\n> \n> Disagree: I could see no existing tests for reflog content matching an\n> expected layout (but could have missed one; I see some _using_ reflog).\n\nI think because t4205 is mostly about testing user-formats. t1410 and\nt1411 are where I'd expect to see tests of normal output for \"git\nreflog\".\n\n> If adding a test for minutiae of how tuning options adjust the output,\n> and something changes which breaks the output more widely, the person\n> investigating can spend a lot of time investigating a red herring,\n> looking to see what they broke in the `--pretty` handling.\n> \n> First test the basics, then test the specifics, so that if the basics\n> break too then the developer is naturally led to the correct thing to\n> investigate instead of their only clue being that specifics broke.\n\nOh, I agree. I just think the basics are tested elsewhere, and this new\ntest is redundant and out-of-place. The numeric progression of the test\nscripts is supposed to follow this basic-first ordering, though it's\noften hard in practice (e.g., I think some \"git log --format\" stuff has\ncrept into the t14xx series, just because it's so darned convenient to\nuse).\n\n> > You can use \"<<-\" to ask the shell to strip leading tabs from the\n> > here-doc. And then you can indent the contents to match the rest of the\n> > test.\n> \n> You can, but it's fragile if tabs become spaces and it isn't consistent\n> with the existing tests above.\n\nYeah, looking at the other \"&&-\" cases you mentioned, I see the whole\nscript does not use \"<<-\". That is against our \"usual\" style, though\nthere are many inconsistent sins in the history of the scripts. IMHO is\nworth modernizing the whole thing.\n\nI don't buy the tabs-become-spaces argument. We use tabs for indentation\nin Git, and that's extremely unlikely to change. If your patch gets\nmunged in transit or by your editor, then the maintainer is going to\ncomplain when applying your patch.\n\n> > (I did a few more tweaks to the format to hopefully make it easier to\n> > read). It would probably be a more interesting test if the two reflogs\n> > actually had different timestamps, though.\n> \n> Is there a way to force that, through the normalizations?\n\nThe magic function you are looking for is \"test_tick()\", which advances\nGIT_COMMITTER_DATE, etc. It's called automatically from test_commit(),\nso seeing two commits with identical timestamps is an indication that\nan earlier test did a manual commit without a matching tick (probably\nbecause it did not care about the timestamps itself).\n\nIt's OK to just make your own new commits, like:\n\n  test_commit reflog-test-one &&\n  test_commit reflog-test-two &&\n  ... check the output of log -g -2 ...\n\nand test those, and then you aren't as dependent on what happened before\n(though of course if you are hard-coding the dates, somebody inserting a\nnew tick in between will screw you up; we tend to add new tests at the\nend of scripts for reasons like that).\n\n> > Also, come to think of it, that \"%gr\" test is going to break in about\n> > year. :-/\n> \n> Oh crap, I saw the normalization and thought everything was being set to\n> specifics, but of course the relative is against now.  Good catch,\n> thanks.  How about:\n> \n>     | sed \"s/[1-9][0-9]* years/N years/\"\n> \n> and then test against \"N years\" in expected?\n\nI can't think of any reason that would fail, unless somebody travels\nback in time to run the tests in 2005 (or their system clock is screwed\nup).\n\n-Peff\n"},{"id":"292354","messageId":"20160727185256.GA11657@sigill.intra.peff.net","threadId":"42937","inReplyTo":"20160727183203.GE32219@sigill.intra.peff.net","subject":"[PATCH 0/2] t4205 style fixes","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T18:52:56Z","receivedAt":"2016-07-27T18:53:05Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jul 27, 2016 at 02:32:03PM -0400, Jeff King wrote:\n\n> > This however was matching existing style for `head1` and `head2` a\n> > little above.  I was somewhat surprised.\n> \n> Ah. Yeah, those are wrong and bad. We should fix that.\n\nSo here's that fix, along with a style cleanup for the here-docs.\n\n  [1/2]: t4205: drop top-level &&-chaining\n  [2/2]: t4205: indent here documents\n\nHopefully that provides a nicer base for building your patch on top of.\n\n-Peff\n"},{"id":"292355","messageId":"20160727185501.GA6626@sigill.intra.peff.net","threadId":"42937","inReplyTo":"20160727185256.GA11657@sigill.intra.peff.net","subject":"[PATCH 1/2] t4205: drop top-level &&-chaining","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T18:55:02Z","receivedAt":"2016-07-27T18:55:12Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"The test currently does something like:\n\n  do_one() &&\n  do_two() &&\n  test_expect_success ...\n\nWe generally avoid performing actions at the top-level of\nthe script (outside of a test_expect block) for two reasons:\n\n  1. The test harness is not checking and reporting if they\n     fail.\n\n  2. Their output is not handled correctly (not hidden by\n     default, nor shown with \"-v\").\n\nUsing &&-chains seems like it should help with (1), but it\ndoesn't. If either of the commands fails, we simply skip\nrunning the follow-on test entirely, and the test harness\nhas no idea.\n\nWe can fix this by pushing that setup into its own block.\nIt _could_ go into the following test block, but since the\nresult in this case is used by multiple tests, it's more\nclear to mark it explicitly as a distinct setup step.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n t/t4205-log-pretty-formats.sh | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\nindex d9f6242..d6518fa 100755\n--- a/t/t4205-log-pretty-formats.sh\n+++ b/t/t4205-log-pretty-formats.sh\n@@ -504,8 +504,10 @@ test_expect_success 'ISO and ISO-strict date formats display the same values' '\n '\n \n # get new digests (with no abbreviations)\n-head1=$(git rev-parse --verify HEAD~0) &&\n-head2=$(git rev-parse --verify HEAD~1) &&\n+test_expect_success 'set up log decoration tests' '\n+\thead1=$(git rev-parse --verify HEAD~0) &&\n+\thead2=$(git rev-parse --verify HEAD~1)\n+'\n \n test_expect_success 'log decoration properly follows tag chain' '\n \tgit tag -a tag1 -m tag1 &&\n-- \n2.9.2.607.g98dce7b\n\n"},{"id":"292356","messageId":"20160727185523.GB6626@sigill.intra.peff.net","threadId":"42937","inReplyTo":"20160727185256.GA11657@sigill.intra.peff.net","subject":"[PATCH 2/2] t4205: indent here documents","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T18:55:23Z","receivedAt":"2016-07-27T18:55:32Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"Our usual style in the test scripts is to indent here\ndocuments with tabs, and use \"<<-\" to strip the tabs. The\nresult is easier to read.\n\nThis old test script did not do so in its inception, and\nfurther tests added onto it followed the local style. Let's\nbring it in line with our usual style.\n\nSome of the tests actually care quite a bit about\nwhitespace, but none of them do so at the beginning of the\nline (because they things like qz_to_tab_space to avoid\ndepending on the literal whitespace), so we can do a fairly\nmechanical conversion.\n\nMost of the here-docs also use interpolation, so they have\nbeen left as \"<<-EOF\". In a few cases, though, where\ninterpolation was not in use, I've converted them to\n\"<<-\\EOF\" to match our usual \"don't interpolate unless you\nneed to\" style.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n t/t4205-log-pretty-formats.sh | 392 +++++++++++++++++++++---------------------\n 1 file changed, 196 insertions(+), 196 deletions(-)\n\ndiff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\nindex d6518fa..f5435fd 100755\n--- a/t/t4205-log-pretty-formats.sh\n+++ b/t/t4205-log-pretty-formats.sh\n@@ -145,199 +145,199 @@ test_expect_success 'setup more commits' '\n \n test_expect_success 'left alignment formatting' '\n \tgit log --pretty=\"tformat:%<(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-message two                            Z\n-message one                            Z\n-add bar                                Z\n-$(commit_msg)                    Z\n-EOF\n+\tqz_to_tab_space <<-EOF >expected &&\n+\tmessage two                            Z\n+\tmessage one                            Z\n+\tadd bar                                Z\n+\t$(commit_msg)                    Z\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-message two                            Z\n-message one                            Z\n-add bar                                Z\n-$(commit_msg)                    Z\n-EOF\n+\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\tmessage two                            Z\n+\tmessage one                            Z\n+\tadd bar                                Z\n+\t$(commit_msg)                    Z\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting at the nth column' '\n \tgit log --pretty=\"tformat:%h %<|(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-$head1 message two                    Z\n-$head2 message one                    Z\n-$head3 add bar                        Z\n-$head4 $(commit_msg)            Z\n-EOF\n+\tqz_to_tab_space <<-EOF >expected &&\n+\t$head1 message two                    Z\n+\t$head2 message one                    Z\n+\t$head3 add bar                        Z\n+\t$head4 $(commit_msg)            Z\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting at the nth column' '\n \tCOLUMNS=50 git log --pretty=\"tformat:%h %<|(-10)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-$head1 message two                    Z\n-$head2 message one                    Z\n-$head3 add bar                        Z\n-$head4 $(commit_msg)            Z\n-EOF\n+\tqz_to_tab_space <<-EOF >expected &&\n+\t$head1 message two                    Z\n+\t$head2 message one                    Z\n+\t$head3 add bar                        Z\n+\t$head4 $(commit_msg)            Z\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting at the nth column. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%h %<|(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-$head1 message two                    Z\n-$head2 message one                    Z\n-$head3 add bar                        Z\n-$head4 $(commit_msg)            Z\n-EOF\n+\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\t$head1 message two                    Z\n+\t$head2 message one                    Z\n+\t$head3 add bar                        Z\n+\t$head4 $(commit_msg)            Z\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting with no padding' '\n \tgit log --pretty=\"tformat:%<(1)%s\" >actual &&\n-\tcat <<EOF >expected &&\n-message two\n-message one\n-add bar\n-$(commit_msg)\n-EOF\n+\tcat <<-EOF >expected &&\n+\tmessage two\n+\tmessage one\n+\tadd bar\n+\t$(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting with no padding. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(1)%s\" >actual &&\n-\tcat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-message two\n-message one\n-add bar\n-$(commit_msg)\n-EOF\n+\tcat <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\tmessage two\n+\tmessage one\n+\tadd bar\n+\t$(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting with trunc' '\n \tgit log --pretty=\"tformat:%<(10,trunc)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-message ..\n-message ..\n-add bar  Z\n-initial...\n-EOF\n+\tqz_to_tab_space <<-\\EOF >expected &&\n+\tmessage ..\n+\tmessage ..\n+\tadd bar  Z\n+\tinitial...\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting with trunc. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(10,trunc)%s\" >actual &&\n-\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-message ..\n-message ..\n-add bar  Z\n-initial...\n-EOF\n+\tqz_to_tab_space <<-\\EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\tmessage ..\n+\tmessage ..\n+\tadd bar  Z\n+\tinitial...\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting with ltrunc' '\n \tgit log --pretty=\"tformat:%<(10,ltrunc)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-..sage two\n-..sage one\n-add bar  Z\n-..${sample_utf8_part}lich\n-EOF\n+\tqz_to_tab_space <<-EOF >expected &&\n+\t..sage two\n+\t..sage one\n+\tadd bar  Z\n+\t..${sample_utf8_part}lich\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting with ltrunc. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(10,ltrunc)%s\" >actual &&\n-\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-..sage two\n-..sage one\n-add bar  Z\n-..${sample_utf8_part}lich\n-EOF\n+\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\t..sage two\n+\t..sage one\n+\tadd bar  Z\n+\t..${sample_utf8_part}lich\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting with mtrunc' '\n \tgit log --pretty=\"tformat:%<(10,mtrunc)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-mess.. two\n-mess.. one\n-add bar  Z\n-init..lich\n-EOF\n+\tqz_to_tab_space <<-\\EOF >expected &&\n+\tmess.. two\n+\tmess.. one\n+\tadd bar  Z\n+\tinit..lich\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left alignment formatting with mtrunc. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(10,mtrunc)%s\" >actual &&\n-\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-mess.. two\n-mess.. one\n-add bar  Z\n-init..lich\n-EOF\n+\tqz_to_tab_space <<-\\EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\tmess.. two\n+\tmess.. one\n+\tadd bar  Z\n+\tinit..lich\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'right alignment formatting' '\n \tgit log --pretty=\"tformat:%>(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-Z                            message two\n-Z                            message one\n-Z                                add bar\n-Z                    $(commit_msg)\n-EOF\n+\tqz_to_tab_space <<-EOF >expected &&\n+\tZ                            message two\n+\tZ                            message one\n+\tZ                                add bar\n+\tZ                    $(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'right alignment formatting. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%>(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-Z                            message two\n-Z                            message one\n-Z                                add bar\n-Z                    $(commit_msg)\n-EOF\n+\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\tZ                            message two\n+\tZ                            message one\n+\tZ                                add bar\n+\tZ                    $(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'right alignment formatting at the nth column' '\n \tgit log --pretty=\"tformat:%h %>|(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-$head1                      message two\n-$head2                      message one\n-$head3                          add bar\n-$head4              $(commit_msg)\n-EOF\n+\tqz_to_tab_space <<-EOF >expected &&\n+\t$head1                      message two\n+\t$head2                      message one\n+\t$head3                          add bar\n+\t$head4              $(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'right alignment formatting at the nth column' '\n \tCOLUMNS=50 git log --pretty=\"tformat:%h %>|(-10)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-$head1                      message two\n-$head2                      message one\n-$head3                          add bar\n-$head4              $(commit_msg)\n-EOF\n+\tqz_to_tab_space <<-EOF >expected &&\n+\t$head1                      message two\n+\t$head2                      message one\n+\t$head3                          add bar\n+\t$head4              $(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'right alignment formatting at the nth column. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%h %>|(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-$head1                      message two\n-$head2                      message one\n-$head3                          add bar\n-$head4              $(commit_msg)\n-EOF\n+\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\t$head1                      message two\n+\t$head2                      message one\n+\t$head3                          add bar\n+\t$head4              $(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n@@ -345,110 +345,110 @@ EOF\n # as in previous test.\n test_expect_success 'right alignment formatting at the nth column with --graph. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --graph --pretty=\"tformat:%h %>|(40)%s\" >actual &&\n-\ticonv -f utf-8 -t $test_encoding >expected <<EOF&&\n-* $head1                    message two\n-* $head2                    message one\n-* $head3                        add bar\n-* $head4            $(commit_msg)\n-EOF\n+\ticonv -f utf-8 -t $test_encoding >expected <<-EOF &&\n+\t* $head1                    message two\n+\t* $head2                    message one\n+\t* $head3                        add bar\n+\t* $head4            $(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'right alignment formatting with no padding' '\n \tgit log --pretty=\"tformat:%>(1)%s\" >actual &&\n-\tcat <<EOF >expected &&\n-message two\n-message one\n-add bar\n-$(commit_msg)\n-EOF\n+\tcat <<-EOF >expected &&\n+\tmessage two\n+\tmessage one\n+\tadd bar\n+\t$(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'right alignment formatting with no padding and with --graph' '\n \tgit log --graph --pretty=\"tformat:%>(1)%s\" >actual &&\n-\tcat <<EOF >expected &&\n-* message two\n-* message one\n-* add bar\n-* $(commit_msg)\n-EOF\n+\tcat <<-EOF >expected &&\n+\t* message two\n+\t* message one\n+\t* add bar\n+\t* $(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'right alignment formatting with no padding. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%>(1)%s\" >actual &&\n-\tcat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-message two\n-message one\n-add bar\n-$(commit_msg)\n-EOF\n+\tcat <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\tmessage two\n+\tmessage one\n+\tadd bar\n+\t$(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'center alignment formatting' '\n \tgit log --pretty=\"tformat:%><(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-Z             message two              Z\n-Z             message one              Z\n-Z               add bar                Z\n-Z         $(commit_msg)          Z\n-EOF\n+\tqz_to_tab_space <<-EOF >expected &&\n+\tZ             message two              Z\n+\tZ             message one              Z\n+\tZ               add bar                Z\n+\tZ         $(commit_msg)          Z\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'center alignment formatting. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%><(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-Z             message two              Z\n-Z             message one              Z\n-Z               add bar                Z\n-Z         $(commit_msg)          Z\n-EOF\n+\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\tZ             message two              Z\n+\tZ             message one              Z\n+\tZ               add bar                Z\n+\tZ         $(commit_msg)          Z\n+\tEOF\n \ttest_cmp expected actual\n '\n test_expect_success 'center alignment formatting at the nth column' '\n \tgit log --pretty=\"tformat:%h %><|(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-$head1           message two          Z\n-$head2           message one          Z\n-$head3             add bar            Z\n-$head4       $(commit_msg)      Z\n-EOF\n+\tqz_to_tab_space <<-EOF >expected &&\n+\t$head1           message two          Z\n+\t$head2           message one          Z\n+\t$head3             add bar            Z\n+\t$head4       $(commit_msg)      Z\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'center alignment formatting at the nth column' '\n \tCOLUMNS=70 git log --pretty=\"tformat:%h %><|(-30)%s\" >actual &&\n-\tqz_to_tab_space <<EOF >expected &&\n-$head1           message two          Z\n-$head2           message one          Z\n-$head3             add bar            Z\n-$head4       $(commit_msg)      Z\n-EOF\n+\tqz_to_tab_space <<-EOF >expected &&\n+\t$head1           message two          Z\n+\t$head2           message one          Z\n+\t$head3             add bar            Z\n+\t$head4       $(commit_msg)      Z\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'center alignment formatting at the nth column. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%h %><|(40)%s\" >actual &&\n-\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-$head1           message two          Z\n-$head2           message one          Z\n-$head3             add bar            Z\n-$head4       $(commit_msg)      Z\n-EOF\n+\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\t$head1           message two          Z\n+\t$head2           message one          Z\n+\t$head3             add bar            Z\n+\t$head4       $(commit_msg)      Z\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'center alignment formatting with no padding' '\n \tgit log --pretty=\"tformat:%><(1)%s\" >actual &&\n-\tcat <<EOF >expected &&\n-message two\n-message one\n-add bar\n-$(commit_msg)\n-EOF\n+\tcat <<-EOF >expected &&\n+\tmessage two\n+\tmessage one\n+\tadd bar\n+\t$(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n@@ -457,34 +457,34 @@ EOF\n old_head1=$(git rev-parse --verify HEAD~0)\n test_expect_success 'center alignment formatting with no padding. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%><(1)%s\" >actual &&\n-\tcat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-message two\n-message one\n-add bar\n-$(commit_msg)\n-EOF\n+\tcat <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\tmessage two\n+\tmessage one\n+\tadd bar\n+\t$(commit_msg)\n+\tEOF\n \ttest_cmp expected actual\n '\n \n test_expect_success 'left/right alignment formatting with stealing' '\n \tgit commit --amend -m short --author \"long long long <long@me.com>\" &&\n \tgit log --pretty=\"tformat:%<(10,trunc)%s%>>(10,ltrunc)% an\" >actual &&\n-\tcat <<EOF >expected &&\n-short long  long long\n-message ..   A U Thor\n-add bar      A U Thor\n-initial...   A U Thor\n-EOF\n+\tcat <<-\\EOF >expected &&\n+\tshort long  long long\n+\tmessage ..   A U Thor\n+\tadd bar      A U Thor\n+\tinitial...   A U Thor\n+\tEOF\n \ttest_cmp expected actual\n '\n test_expect_success 'left/right alignment formatting with stealing. i18n.logOutputEncoding' '\n \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(10,trunc)%s%>>(10,ltrunc)% an\" >actual &&\n-\tcat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n-short long  long long\n-message ..   A U Thor\n-add bar      A U Thor\n-initial...   A U Thor\n-EOF\n+\tcat <<-\\EOF | iconv -f utf-8 -t $test_encoding >expected &&\n+\tshort long  long long\n+\tmessage ..   A U Thor\n+\tadd bar      A U Thor\n+\tinitial...   A U Thor\n+\tEOF\n \ttest_cmp expected actual\n '\n \n@@ -515,22 +515,22 @@ test_expect_success 'log decoration properly follows tag chain' '\n \tgit tag -d tag1 &&\n \tgit commit --amend -m shorter &&\n \tgit log --no-walk --tags --pretty=\"%H %d\" --decorate=full >actual &&\n-\tcat <<EOF >expected &&\n-$head1  (tag: refs/tags/tag2)\n-$head2  (tag: refs/tags/message-one)\n-$old_head1  (tag: refs/tags/message-two)\n-EOF\n+\tcat <<-EOF >expected &&\n+\t$head1  (tag: refs/tags/tag2)\n+\t$head2  (tag: refs/tags/message-one)\n+\t$old_head1  (tag: refs/tags/message-two)\n+\tEOF\n \tsort actual >actual1 &&\n \ttest_cmp expected actual1\n '\n \n test_expect_success 'clean log decoration' '\n \tgit log --no-walk --tags --pretty=\"%H %D\" --decorate=full >actual &&\n-\tcat >expected <<EOF &&\n-$head1 tag: refs/tags/tag2\n-$head2 tag: refs/tags/message-one\n-$old_head1 tag: refs/tags/message-two\n-EOF\n+\tcat >expected <<-EOF &&\n+\t$head1 tag: refs/tags/tag2\n+\t$head2 tag: refs/tags/message-one\n+\t$old_head1 tag: refs/tags/message-two\n+\tEOF\n \tsort actual >actual1 &&\n \ttest_cmp expected actual1\n '\n-- \n2.9.2.607.g98dce7b\n"},{"id":"292357","messageId":"20160727184141.GA23975@tower.spodhuis.org","threadId":"42937","inReplyTo":"20160727183203.GE32219@sigill.intra.peff.net","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Phil Pennock","fromEmail":"phil.pennock@spodhuis.org","sentAt":"2016-07-27T18:41:41Z","receivedAt":"2016-07-27T18:58:44Z","isPatch":true,"sender":{"key":"phil.pennock@spodhuis.org","avatar":null},"body":"On 2016-07-27 at 14:32 -0400, Jeff King wrote:\n> Yeah, I agree the \"!\" test for \"did it work\" is counter-intuitive if you're\n> coming from other languages, but it's pretty normal for C code bases\n> (especially ours).\n\nFor stuff returning pointers, sure.\n\n> Ah. Yeah, those are wrong and bad. We should fix that.\n\nK, noted, will go back over this thread before I touch code and pick\nthese all up.\n\n> I don't buy the tabs-become-spaces argument. We use tabs for indentation\n> in Git, and that's extremely unlikely to change. If your patch gets\n> munged in transit or by your editor, then the maintainer is going to\n> complain when applying your patch.\n\nOkay.  (I happen to think that robustness against a cycle of developers\ndiscussing why whitespace broke patches in transit is good, but I'll\nchange this).\n\n> The magic function you are looking for is \"test_tick()\", which advances\n\nAh.  Too tired last night, didn't realize that when I switched from\nconstructing things on branches to have branch action in the reflog, to\n\"just need commits really\", to \"previous tests did this\" I lost the\n`test_tick()` invocation and for some reason when I looked at the\nresults, decided I must be missing something about resolution instead of\nrealizing that I was no longer calling `test_tick()`.\n\nWhich leads to a final point:\n\nI'm not going to write any more code today, for reasons of \"weak human\nneeds sleep and I'll make more stupid mistakes if I continue\".  So I'm\ngoing silent on this thread for the rest of today.  Not ignoring.  If\nfolks want fast progress (I haven't looked at release cycle status) I\nwon't mind cutting me out of the loop :-D but otherwise I'll look\nThu/Fri this week for any remedial work and offer a fresh patch with\nfixes from this thread, and documentation.\n\nI'm tempted to just steal the docs from Ted's patch, unless that's\nconsidered bad form?\n\n-Phil\n"},{"id":"292359","messageId":"20160727191630.GA6743@sigill.intra.peff.net","threadId":"42937","inReplyTo":"20160727184141.GA23975@tower.spodhuis.org","subject":"Re: [PATCH] pretty format string support for reflog times","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T19:16:30Z","receivedAt":"2016-07-27T19:16:37Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jul 27, 2016 at 06:41:41PM +0000, Phil Pennock wrote:\n\n> On 2016-07-27 at 14:32 -0400, Jeff King wrote:\n> > Yeah, I agree the \"!\" test for \"did it work\" is counter-intuitive if you're\n> > coming from other languages, but it's pretty normal for C code bases\n> > (especially ours).\n> \n> For stuff returning pointers, sure.\n\nI think the pattern comes more from syscalls.\n\n> > I don't buy the tabs-become-spaces argument. We use tabs for indentation\n> > in Git, and that's extremely unlikely to change. If your patch gets\n> > munged in transit or by your editor, then the maintainer is going to\n> > complain when applying your patch.\n> \n> Okay.  (I happen to think that robustness against a cycle of developers\n> discussing why whitespace broke patches in transit is good, but I'll\n> change this).\n\nWhat we've found is that if your whitespace breaks in transit, the\npatches don't apply anyway (because of wrapping, or because tab/space\nconversion breaks the context lines). So we mostly just accept the risk\nand stay militant about it.\n\n> I'm not going to write any more code today, for reasons of \"weak human\n> needs sleep and I'll make more stupid mistakes if I continue\".  So I'm\n> going silent on this thread for the rest of today.  Not ignoring.  If\n> folks want fast progress (I haven't looked at release cycle status) I\n> won't mind cutting me out of the loop :-D but otherwise I'll look\n> Thu/Fri this week for any remedial work and offer a fresh patch with\n> fixes from this thread, and documentation.\n\nSure, take your time. It's open source, so movement is generally\nmeasured in days, and sometimes weeks. Thank you for working on it!\n\n> I'm tempted to just steal the docs from Ted's patch, unless that's\n> considered bad form?\n\nI think that's fine, especially considering how short the snippet is.\nIf you pulled content from somewhere, it's normal to acknowledge it in\nthe commit message.\n\n-Peff\n"},{"id":"292360","messageId":"xmqqbn1ix4mp.fsf@gitster.mtv.corp.google.com","threadId":"42937","inReplyTo":"20160727185523.GB6626@sigill.intra.peff.net","subject":"Re: [PATCH 2/2] t4205: indent here documents","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-07-27T19:28:14Z","receivedAt":"2016-07-27T19:28:23Z","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> Our usual style in the test scripts is to indent here\n> documents with tabs, and use \"<<-\" to strip the tabs. The\n> result is easier to read.\n>\n> This old test script did not do so in its inception, and\n> further tests added onto it followed the local style. Let's\n> bring it in line with our usual style.\n>\n> Some of the tests actually care quite a bit about\n> whitespace, but none of them do so at the beginning of the\n> line (because they things like qz_to_tab_space to avoid\n\nI'll do s/they things/they use things/ here while queuing.\n\nThanks.\n\n> depending on the literal whitespace), so we can do a fairly\n> mechanical conversion.\n>\n> Most of the here-docs also use interpolation, so they have\n> been left as \"<<-EOF\". In a few cases, though, where\n> interpolation was not in use, I've converted them to\n> \"<<-\\EOF\" to match our usual \"don't interpolate unless you\n> need to\" style.\n>\n> Signed-off-by: Jeff King <peff@peff.net>\n> ---\n>  t/t4205-log-pretty-formats.sh | 392 +++++++++++++++++++++---------------------\n>  1 file changed, 196 insertions(+), 196 deletions(-)\n>\n> diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\n> index d6518fa..f5435fd 100755\n> --- a/t/t4205-log-pretty-formats.sh\n> +++ b/t/t4205-log-pretty-formats.sh\n> @@ -145,199 +145,199 @@ test_expect_success 'setup more commits' '\n>  \n>  test_expect_success 'left alignment formatting' '\n>  \tgit log --pretty=\"tformat:%<(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -message two                            Z\n> -message one                            Z\n> -add bar                                Z\n> -$(commit_msg)                    Z\n> -EOF\n> +\tqz_to_tab_space <<-EOF >expected &&\n> +\tmessage two                            Z\n> +\tmessage one                            Z\n> +\tadd bar                                Z\n> +\t$(commit_msg)                    Z\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -message two                            Z\n> -message one                            Z\n> -add bar                                Z\n> -$(commit_msg)                    Z\n> -EOF\n> +\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\tmessage two                            Z\n> +\tmessage one                            Z\n> +\tadd bar                                Z\n> +\t$(commit_msg)                    Z\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting at the nth column' '\n>  \tgit log --pretty=\"tformat:%h %<|(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -$head1 message two                    Z\n> -$head2 message one                    Z\n> -$head3 add bar                        Z\n> -$head4 $(commit_msg)            Z\n> -EOF\n> +\tqz_to_tab_space <<-EOF >expected &&\n> +\t$head1 message two                    Z\n> +\t$head2 message one                    Z\n> +\t$head3 add bar                        Z\n> +\t$head4 $(commit_msg)            Z\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting at the nth column' '\n>  \tCOLUMNS=50 git log --pretty=\"tformat:%h %<|(-10)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -$head1 message two                    Z\n> -$head2 message one                    Z\n> -$head3 add bar                        Z\n> -$head4 $(commit_msg)            Z\n> -EOF\n> +\tqz_to_tab_space <<-EOF >expected &&\n> +\t$head1 message two                    Z\n> +\t$head2 message one                    Z\n> +\t$head3 add bar                        Z\n> +\t$head4 $(commit_msg)            Z\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting at the nth column. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%h %<|(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -$head1 message two                    Z\n> -$head2 message one                    Z\n> -$head3 add bar                        Z\n> -$head4 $(commit_msg)            Z\n> -EOF\n> +\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\t$head1 message two                    Z\n> +\t$head2 message one                    Z\n> +\t$head3 add bar                        Z\n> +\t$head4 $(commit_msg)            Z\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting with no padding' '\n>  \tgit log --pretty=\"tformat:%<(1)%s\" >actual &&\n> -\tcat <<EOF >expected &&\n> -message two\n> -message one\n> -add bar\n> -$(commit_msg)\n> -EOF\n> +\tcat <<-EOF >expected &&\n> +\tmessage two\n> +\tmessage one\n> +\tadd bar\n> +\t$(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting with no padding. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(1)%s\" >actual &&\n> -\tcat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -message two\n> -message one\n> -add bar\n> -$(commit_msg)\n> -EOF\n> +\tcat <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\tmessage two\n> +\tmessage one\n> +\tadd bar\n> +\t$(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting with trunc' '\n>  \tgit log --pretty=\"tformat:%<(10,trunc)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -message ..\n> -message ..\n> -add bar  Z\n> -initial...\n> -EOF\n> +\tqz_to_tab_space <<-\\EOF >expected &&\n> +\tmessage ..\n> +\tmessage ..\n> +\tadd bar  Z\n> +\tinitial...\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting with trunc. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(10,trunc)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -message ..\n> -message ..\n> -add bar  Z\n> -initial...\n> -EOF\n> +\tqz_to_tab_space <<-\\EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\tmessage ..\n> +\tmessage ..\n> +\tadd bar  Z\n> +\tinitial...\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting with ltrunc' '\n>  \tgit log --pretty=\"tformat:%<(10,ltrunc)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -..sage two\n> -..sage one\n> -add bar  Z\n> -..${sample_utf8_part}lich\n> -EOF\n> +\tqz_to_tab_space <<-EOF >expected &&\n> +\t..sage two\n> +\t..sage one\n> +\tadd bar  Z\n> +\t..${sample_utf8_part}lich\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting with ltrunc. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(10,ltrunc)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -..sage two\n> -..sage one\n> -add bar  Z\n> -..${sample_utf8_part}lich\n> -EOF\n> +\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\t..sage two\n> +\t..sage one\n> +\tadd bar  Z\n> +\t..${sample_utf8_part}lich\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting with mtrunc' '\n>  \tgit log --pretty=\"tformat:%<(10,mtrunc)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -mess.. two\n> -mess.. one\n> -add bar  Z\n> -init..lich\n> -EOF\n> +\tqz_to_tab_space <<-\\EOF >expected &&\n> +\tmess.. two\n> +\tmess.. one\n> +\tadd bar  Z\n> +\tinit..lich\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left alignment formatting with mtrunc. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(10,mtrunc)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -mess.. two\n> -mess.. one\n> -add bar  Z\n> -init..lich\n> -EOF\n> +\tqz_to_tab_space <<-\\EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\tmess.. two\n> +\tmess.. one\n> +\tadd bar  Z\n> +\tinit..lich\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'right alignment formatting' '\n>  \tgit log --pretty=\"tformat:%>(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -Z                            message two\n> -Z                            message one\n> -Z                                add bar\n> -Z                    $(commit_msg)\n> -EOF\n> +\tqz_to_tab_space <<-EOF >expected &&\n> +\tZ                            message two\n> +\tZ                            message one\n> +\tZ                                add bar\n> +\tZ                    $(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'right alignment formatting. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%>(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -Z                            message two\n> -Z                            message one\n> -Z                                add bar\n> -Z                    $(commit_msg)\n> -EOF\n> +\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\tZ                            message two\n> +\tZ                            message one\n> +\tZ                                add bar\n> +\tZ                    $(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'right alignment formatting at the nth column' '\n>  \tgit log --pretty=\"tformat:%h %>|(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -$head1                      message two\n> -$head2                      message one\n> -$head3                          add bar\n> -$head4              $(commit_msg)\n> -EOF\n> +\tqz_to_tab_space <<-EOF >expected &&\n> +\t$head1                      message two\n> +\t$head2                      message one\n> +\t$head3                          add bar\n> +\t$head4              $(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'right alignment formatting at the nth column' '\n>  \tCOLUMNS=50 git log --pretty=\"tformat:%h %>|(-10)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -$head1                      message two\n> -$head2                      message one\n> -$head3                          add bar\n> -$head4              $(commit_msg)\n> -EOF\n> +\tqz_to_tab_space <<-EOF >expected &&\n> +\t$head1                      message two\n> +\t$head2                      message one\n> +\t$head3                          add bar\n> +\t$head4              $(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'right alignment formatting at the nth column. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%h %>|(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -$head1                      message two\n> -$head2                      message one\n> -$head3                          add bar\n> -$head4              $(commit_msg)\n> -EOF\n> +\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\t$head1                      message two\n> +\t$head2                      message one\n> +\t$head3                          add bar\n> +\t$head4              $(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n> @@ -345,110 +345,110 @@ EOF\n>  # as in previous test.\n>  test_expect_success 'right alignment formatting at the nth column with --graph. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --graph --pretty=\"tformat:%h %>|(40)%s\" >actual &&\n> -\ticonv -f utf-8 -t $test_encoding >expected <<EOF&&\n> -* $head1                    message two\n> -* $head2                    message one\n> -* $head3                        add bar\n> -* $head4            $(commit_msg)\n> -EOF\n> +\ticonv -f utf-8 -t $test_encoding >expected <<-EOF &&\n> +\t* $head1                    message two\n> +\t* $head2                    message one\n> +\t* $head3                        add bar\n> +\t* $head4            $(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'right alignment formatting with no padding' '\n>  \tgit log --pretty=\"tformat:%>(1)%s\" >actual &&\n> -\tcat <<EOF >expected &&\n> -message two\n> -message one\n> -add bar\n> -$(commit_msg)\n> -EOF\n> +\tcat <<-EOF >expected &&\n> +\tmessage two\n> +\tmessage one\n> +\tadd bar\n> +\t$(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'right alignment formatting with no padding and with --graph' '\n>  \tgit log --graph --pretty=\"tformat:%>(1)%s\" >actual &&\n> -\tcat <<EOF >expected &&\n> -* message two\n> -* message one\n> -* add bar\n> -* $(commit_msg)\n> -EOF\n> +\tcat <<-EOF >expected &&\n> +\t* message two\n> +\t* message one\n> +\t* add bar\n> +\t* $(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'right alignment formatting with no padding. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%>(1)%s\" >actual &&\n> -\tcat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -message two\n> -message one\n> -add bar\n> -$(commit_msg)\n> -EOF\n> +\tcat <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\tmessage two\n> +\tmessage one\n> +\tadd bar\n> +\t$(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'center alignment formatting' '\n>  \tgit log --pretty=\"tformat:%><(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -Z             message two              Z\n> -Z             message one              Z\n> -Z               add bar                Z\n> -Z         $(commit_msg)          Z\n> -EOF\n> +\tqz_to_tab_space <<-EOF >expected &&\n> +\tZ             message two              Z\n> +\tZ             message one              Z\n> +\tZ               add bar                Z\n> +\tZ         $(commit_msg)          Z\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'center alignment formatting. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%><(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -Z             message two              Z\n> -Z             message one              Z\n> -Z               add bar                Z\n> -Z         $(commit_msg)          Z\n> -EOF\n> +\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\tZ             message two              Z\n> +\tZ             message one              Z\n> +\tZ               add bar                Z\n> +\tZ         $(commit_msg)          Z\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  test_expect_success 'center alignment formatting at the nth column' '\n>  \tgit log --pretty=\"tformat:%h %><|(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -$head1           message two          Z\n> -$head2           message one          Z\n> -$head3             add bar            Z\n> -$head4       $(commit_msg)      Z\n> -EOF\n> +\tqz_to_tab_space <<-EOF >expected &&\n> +\t$head1           message two          Z\n> +\t$head2           message one          Z\n> +\t$head3             add bar            Z\n> +\t$head4       $(commit_msg)      Z\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'center alignment formatting at the nth column' '\n>  \tCOLUMNS=70 git log --pretty=\"tformat:%h %><|(-30)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF >expected &&\n> -$head1           message two          Z\n> -$head2           message one          Z\n> -$head3             add bar            Z\n> -$head4       $(commit_msg)      Z\n> -EOF\n> +\tqz_to_tab_space <<-EOF >expected &&\n> +\t$head1           message two          Z\n> +\t$head2           message one          Z\n> +\t$head3             add bar            Z\n> +\t$head4       $(commit_msg)      Z\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'center alignment formatting at the nth column. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%h %><|(40)%s\" >actual &&\n> -\tqz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -$head1           message two          Z\n> -$head2           message one          Z\n> -$head3             add bar            Z\n> -$head4       $(commit_msg)      Z\n> -EOF\n> +\tqz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\t$head1           message two          Z\n> +\t$head2           message one          Z\n> +\t$head3             add bar            Z\n> +\t$head4       $(commit_msg)      Z\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'center alignment formatting with no padding' '\n>  \tgit log --pretty=\"tformat:%><(1)%s\" >actual &&\n> -\tcat <<EOF >expected &&\n> -message two\n> -message one\n> -add bar\n> -$(commit_msg)\n> -EOF\n> +\tcat <<-EOF >expected &&\n> +\tmessage two\n> +\tmessage one\n> +\tadd bar\n> +\t$(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n> @@ -457,34 +457,34 @@ EOF\n>  old_head1=$(git rev-parse --verify HEAD~0)\n>  test_expect_success 'center alignment formatting with no padding. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%><(1)%s\" >actual &&\n> -\tcat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -message two\n> -message one\n> -add bar\n> -$(commit_msg)\n> -EOF\n> +\tcat <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\tmessage two\n> +\tmessage one\n> +\tadd bar\n> +\t$(commit_msg)\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n>  test_expect_success 'left/right alignment formatting with stealing' '\n>  \tgit commit --amend -m short --author \"long long long <long@me.com>\" &&\n>  \tgit log --pretty=\"tformat:%<(10,trunc)%s%>>(10,ltrunc)% an\" >actual &&\n> -\tcat <<EOF >expected &&\n> -short long  long long\n> -message ..   A U Thor\n> -add bar      A U Thor\n> -initial...   A U Thor\n> -EOF\n> +\tcat <<-\\EOF >expected &&\n> +\tshort long  long long\n> +\tmessage ..   A U Thor\n> +\tadd bar      A U Thor\n> +\tinitial...   A U Thor\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  test_expect_success 'left/right alignment formatting with stealing. i18n.logOutputEncoding' '\n>  \tgit -c i18n.logOutputEncoding=$test_encoding log --pretty=\"tformat:%<(10,trunc)%s%>>(10,ltrunc)% an\" >actual &&\n> -\tcat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> -short long  long long\n> -message ..   A U Thor\n> -add bar      A U Thor\n> -initial...   A U Thor\n> -EOF\n> +\tcat <<-\\EOF | iconv -f utf-8 -t $test_encoding >expected &&\n> +\tshort long  long long\n> +\tmessage ..   A U Thor\n> +\tadd bar      A U Thor\n> +\tinitial...   A U Thor\n> +\tEOF\n>  \ttest_cmp expected actual\n>  '\n>  \n> @@ -515,22 +515,22 @@ test_expect_success 'log decoration properly follows tag chain' '\n>  \tgit tag -d tag1 &&\n>  \tgit commit --amend -m shorter &&\n>  \tgit log --no-walk --tags --pretty=\"%H %d\" --decorate=full >actual &&\n> -\tcat <<EOF >expected &&\n> -$head1  (tag: refs/tags/tag2)\n> -$head2  (tag: refs/tags/message-one)\n> -$old_head1  (tag: refs/tags/message-two)\n> -EOF\n> +\tcat <<-EOF >expected &&\n> +\t$head1  (tag: refs/tags/tag2)\n> +\t$head2  (tag: refs/tags/message-one)\n> +\t$old_head1  (tag: refs/tags/message-two)\n> +\tEOF\n>  \tsort actual >actual1 &&\n>  \ttest_cmp expected actual1\n>  '\n>  \n>  test_expect_success 'clean log decoration' '\n>  \tgit log --no-walk --tags --pretty=\"%H %D\" --decorate=full >actual &&\n> -\tcat >expected <<EOF &&\n> -$head1 tag: refs/tags/tag2\n> -$head2 tag: refs/tags/message-one\n> -$old_head1 tag: refs/tags/message-two\n> -EOF\n> +\tcat >expected <<-EOF &&\n> +\t$head1 tag: refs/tags/tag2\n> +\t$head2 tag: refs/tags/message-one\n> +\t$old_head1 tag: refs/tags/message-two\n> +\tEOF\n>  \tsort actual >actual1 &&\n>  \ttest_cmp expected actual1\n>  '\n"},{"id":"292364","messageId":"20160727195725.GB8141@sigill.intra.peff.net","threadId":"42937","inReplyTo":"xmqqbn1ix4mp.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 2/2] t4205: indent here documents","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-27T19:57:25Z","receivedAt":"2016-07-27T19:57:33Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jul 27, 2016 at 12:28:14PM -0700, Junio C Hamano wrote:\n\n> > Some of the tests actually care quite a bit about\n> > whitespace, but none of them do so at the beginning of the\n> > line (because they things like qz_to_tab_space to avoid\n> \n> I'll do s/they things/they use things/ here while queuing.\n\nWhoops, thanks.\n\n-Peff\n"}]}