{"thread":{"id":"36506","subject":"[PATCH] Uses git-credential for git-imap-send","startedAt":"2014-04-26T17:50:26Z","lastAt":"2014-04-29T17:19:05Z","messageCount":8,"participants":["Dan Albert","Jeff King","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"239769","messageId":"CAFVaGhudmcrh32_h3RPmR_E7e3Jo9xc6AEt5AtN2W5NVbEMg6w@mail.gmail.com","threadId":"36506","inReplyTo":null,"subject":"[PATCH] Uses git-credential for git-imap-send","fromName":"Dan Albert","fromEmail":"danalbert@google.com","sentAt":"2014-04-26T17:50:26Z","receivedAt":"2014-04-26T17:50:26Z","isPatch":true,"sender":{"key":"danalbert@google.com","avatar":null},"body":"git-imap-send was directly prompting for a password rather than using\ngit-credential. git-send-email, on the other hand, supports git-credential.\n\nThis is a necessary improvement for users that use two factor authentication, as\nthey should not be expected to remember all of their app specific passwords.\n---\n imap-send.c | 29 +++++++++++++++--------------\n 1 file changed, 15 insertions(+), 14 deletions(-)\n\ndiff --git a/imap-send.c b/imap-send.c\nindex 0bc6f7f..262fb9a 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -23,9 +23,9 @@\n  */\n\n #include \"cache.h\"\n+#include \"credential.h\"\n #include \"exec_cmd.h\"\n #include \"run-command.h\"\n-#include \"prompt.h\"\n #ifdef NO_OPENSSL\n typedef void *SSL;\n #endif\n@@ -946,6 +946,7 @@ static int auth_cram_md5(struct imap_store *ctx,\nstruct imap_cmd *cmd, const cha\n\n static struct imap_store *imap_open_store(struct imap_server_conf *srvc)\n {\n+ struct credential cred = CREDENTIAL_INIT;\n  struct imap_store *ctx;\n  struct imap *imap;\n  char *arg, *rsp;\n@@ -1101,19 +1102,11 @@ static struct imap_store\n*imap_open_store(struct imap_server_conf *srvc)\n  goto bail;\n  }\n  if (!srvc->pass) {\n- struct strbuf prompt = STRBUF_INIT;\n- strbuf_addf(&prompt, \"Password (%s@%s): \", srvc->user, srvc->host);\n- arg = git_getpass(prompt.buf);\n- strbuf_release(&prompt);\n- if (!*arg) {\n- fprintf(stderr, \"Skipping account %s@%s, no password\\n\", srvc->user,\nsrvc->host);\n- goto bail;\n- }\n- /*\n- * getpass() returns a pointer to a static buffer.  make a copy\n- * for long term storage.\n- */\n- srvc->pass = xstrdup(arg);\n+ cred.username = xstrdup(srvc->user);\n+ cred.protocol = xstrdup(\"imap\");\n+ cred.host = xstrdup(srvc->host);\n+ credential_fill(&cred);\n+ srvc->pass = xstrdup(cred.password);\n  }\n  if (CAP(NOLOGIN)) {\n  fprintf(stderr, \"Skipping account %s@%s, server forbids LOGIN\\n\",\nsrvc->user, srvc->host);\n@@ -1153,10 +1146,18 @@ static struct imap_store\n*imap_open_store(struct imap_server_conf *srvc)\n  }\n  } /* !preauth */\n\n+ if (cred.username)\n+ credential_approve(&cred);\n+ credential_clear(&cred);\n+\n  ctx->prefix = \"\";\n  return ctx;\n\n bail:\n+ if (cred.username)\n+ credential_reject(&cred);\n+ credential_clear(&cred);\n+\n  imap_close_store(ctx);\n  return NULL;\n }\n-- \n2.0.0.rc1.1.gce060f5\n"},{"id":"239771","messageId":"20140426180835.GE21493@sigill.intra.peff.net","threadId":"36506","inReplyTo":"CAFVaGhudmcrh32_h3RPmR_E7e3Jo9xc6AEt5AtN2W5NVbEMg6w@mail.gmail.com","subject":"Re: [PATCH] Uses git-credential for git-imap-send","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-04-26T18:08:35Z","receivedAt":"2014-04-26T18:08:35Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Apr 26, 2014 at 10:50:26AM -0700, Dan Albert wrote:\n\n> git-imap-send was directly prompting for a password rather than using\n> git-credential. git-send-email, on the other hand, supports\n> git-credential.\n\nYay. These sorts of conversions were definitely on my mind when I did\nthe original credential work, and have mostly been waiting on somebody\nwho cares enough about specific tools to switch them over.\n\n>  static struct imap_store *imap_open_store(struct imap_server_conf *srvc)\n>  {\n> + struct credential cred = CREDENTIAL_INIT;\n\nYour patch seems to have been whitespace-damaged in transit (there are\nhints for gmail in the format-patch and send-email manpages).\n\n> + cred.username = xstrdup(srvc->user);\n> + cred.protocol = xstrdup(\"imap\");\n> + cred.host = xstrdup(srvc->host);\n> + credential_fill(&cred);\n> + srvc->pass = xstrdup(cred.password);\n\nThe \"imap\" protocol will get passed along to any helpers. I think the\nonly one which actually cares about the specific content is the\nosxkeychain helper, which differentiates between \"imap\" and \"imaps\". I\nthink we can know which is which at this point and do:\n\n  cred.protocol = xstrdup(srvc->use_ssl ? \"imaps\" : \"imap\");\n\nOther than that, the patch looks good. Tests would be wonderful, but we\nhave no infrastructure at all, so it would involve writing a mock IMAP\nserver. Having implemented both IMAP servers and clients in a previous\nlife, I could not ask anyone to go through that pain. :)\n\n-Peff\n"},{"id":"239790","messageId":"20140427075110.GA19976@sigill.intra.peff.net","threadId":"36506","inReplyTo":"CAFVaGhuXvZhRCHRFurKNOC4tsiQ7WZnGb2CbRnoSSYg=XknJtg@mail.gmail.com","subject":"Re: [PATCH] Uses git-credential for git-imap-send","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-04-27T07:51:10Z","receivedAt":"2014-04-27T07:51:10Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Apr 26, 2014 at 11:30:11AM -0700, Dan Albert wrote:\n\n> I had resent a less broken patch after I noticed the tabs, but it seems to\n> have gotten lost. Better formatted patch at the bottom of this message.\n\nYour emails (including this one) are multipart/alternatives with an html\npart, which will cause the mailing list software to reject them.\n\nThis email also still seems whitespace-damaged to me (the leading tabs\nare collapsed to a single space).\n\nIt looks like you're using gmail to send; you might try using \"git\nsend-email\" (the example at the end of \"git help send-email\" can walk\nyou through it).\n\n> About imap vs. imaps: I actually had your exact line in before, but decided\n> that as long as its for the same host the user probably wants to use the\n> same credentials for both imap and imaps (if they for some reason had both\n> configured). Hard coding \"imap\" allows them to use either protocol with\n> only one keychain entry. The use case is a stretch, but it doesn't do any\n> harm to implement it this way.\n\nMy concerns with conflating the two are:\n\n  1. The system helper might care about the distinction and prefer imaps\n     (e.g., it might already have the credential stored for your regular\n     mail client, which uses imaps). But osxkeychain is the only helper\n     that makes the distinction, and I don't really know how OS X's\n     keychain code handles the distinction.\n\n  2. With http and https, we are careful to make the distinction,\n     because we would not want to accidentally share a credential over http\n     that was stored via https. But it's pretty easy to use an http URL\n     rather than an https one. It's probably pretty rare to accidentally\n     turn off imap SSL.\n\nSo I'd be OK with leaving it as \"imap\" for now, and waiting for somebody\nto actually come up with a real case where the distinction matters.\n\n> ---\n> \n> Uses git-credential for git-imap-send\n> \n> git-imap-send was directly prompting for a password rather than using\n> git-credential. git-send-email, on the other hand, supports git-credential.\n> \n> This is a necessary improvement for users that use two factor\n> authentication, as\n> they should not be expected to remember all of their app specific passwords.\n> \n> Signed-off-by: Dan Albert <danalbert@google.com>\n> ---\n>  imap-send.c | 29 +++++++++++++++--------------\n>  1 file changed, 15 insertions(+), 14 deletions(-)\n\nA side note on formatting your commit message: The maintainer picks up\npatches from the list with \"git am\", which will take everything up to\nthe first \"---\" as the commit message, and discard everything after up\nto the start of the diff. So in this case it would take your\ncover-letter material as the commit message, and drop your actual commit\nmessage.\n\nThe usual formats are either to put the cover letter material after the\n\"---\", like:\n\n  $COMMIT_MESSAGE\n\n  Signed-off-by: You\n  ---\n  $COVER_LETTER\n  $DIFFSTAT\n  $DIFF\n\nor to use a scissors-line \"-- >8 --\" instead of three-dash:\n\n  $COVER_LETTER\n\n  -- >8 --\n  $COMMIT_MESSAGE\n\n  ---\n  $DIFFSTAT\n  $DIFF\n\n-Peff\n"},{"id":"239807","messageId":"907d1444a8e17a43c03ee0c2bb04038bdd3372b8.1398620231.git.danalbert@google.com","threadId":"36506","inReplyTo":"20140426180835.GE21493@sigill.intra.peff.net","subject":"[PATCH] Uses git-credential for git-imap-send","fromName":"Dan Albert","fromEmail":"danalbert@google.com","sentAt":"2014-04-27T17:58:51Z","receivedAt":"2014-04-27T17:58:51Z","isPatch":true,"sender":{"key":"danalbert@google.com","avatar":null},"body":"git-imap-send was directly prompting for a password rather than using\ngit-credential. git-send-email, on the other hand, supports git-credential.\n\nThis is a necessary improvement for users that use two factor authentication, as\nthey should not be expected to remember all of their app specific passwords.\n\nSigned-off-by: Dan Albert <danalbert@google.com>\n---\n\n>> About imap vs. imaps: I actually had your exact line in before, but decided\n>> that as long as its for the same host the user probably wants to use the\n>> same credentials for both imap and imaps (if they for some reason had both\n>> configured). Hard coding \"imap\" allows them to use either protocol with\n>> only one keychain entry. The use case is a stretch, but it doesn't do any\n>> harm to implement it this way.\n>\n> My concerns with conflating the two are:\n> \n>   1. The system helper might care about the distinction and prefer imaps\n>      (e.g., it might already have the credential stored for your regular\n>      mail client, which uses imaps). But osxkeychain is the only helper\n>      that makes the distinction, and I don't really know how OS X's\n>      keychain code handles the distinction.\n> \n>   2. With http and https, we are careful to make the distinction,\n>      because we would not want to accidentally share a credential over http\n>      that was stored via https. But it's pretty easy to use an http URL\n>      rather than an https one. It's probably pretty rare to accidentally\n>      turn off imap SSL.\n> \n> So I'd be OK with leaving it as \"imap\" for now, and waiting for somebody\n> to actually come up with a real case where the distinction matters.\n\nThese are good points. I've made the change.\n\n imap-send.c | 29 +++++++++++++++--------------\n 1 file changed, 15 insertions(+), 14 deletions(-)\n\ndiff --git a/imap-send.c b/imap-send.c\nindex 0bc6f7f..112fc83 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -23,9 +23,9 @@\n  */\n \n #include \"cache.h\"\n+#include \"credential.h\"\n #include \"exec_cmd.h\"\n #include \"run-command.h\"\n-#include \"prompt.h\"\n #ifdef NO_OPENSSL\n typedef void *SSL;\n #endif\n@@ -946,6 +946,7 @@ static int auth_cram_md5(struct imap_store *ctx, struct imap_cmd *cmd, const cha\n \n static struct imap_store *imap_open_store(struct imap_server_conf *srvc)\n {\n+\tstruct credential cred = CREDENTIAL_INIT;\n \tstruct imap_store *ctx;\n \tstruct imap *imap;\n \tchar *arg, *rsp;\n@@ -1101,19 +1102,11 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc)\n \t\t\tgoto bail;\n \t\t}\n \t\tif (!srvc->pass) {\n-\t\t\tstruct strbuf prompt = STRBUF_INIT;\n-\t\t\tstrbuf_addf(&prompt, \"Password (%s@%s): \", srvc->user, srvc->host);\n-\t\t\targ = git_getpass(prompt.buf);\n-\t\t\tstrbuf_release(&prompt);\n-\t\t\tif (!*arg) {\n-\t\t\t\tfprintf(stderr, \"Skipping account %s@%s, no password\\n\", srvc->user, srvc->host);\n-\t\t\t\tgoto bail;\n-\t\t\t}\n-\t\t\t/*\n-\t\t\t * getpass() returns a pointer to a static buffer.  make a copy\n-\t\t\t * for long term storage.\n-\t\t\t */\n-\t\t\tsrvc->pass = xstrdup(arg);\n+\t\t\tcred.username = xstrdup(srvc->user);\n+\t\t\tcred.protocol = xstrdup(srvc->use_ssl ? \"imaps\" : \"imap\");\n+\t\t\tcred.host = xstrdup(srvc->host);\n+\t\t\tcredential_fill(&cred);\n+\t\t\tsrvc->pass = xstrdup(cred.password);\n \t\t}\n \t\tif (CAP(NOLOGIN)) {\n \t\t\tfprintf(stderr, \"Skipping account %s@%s, server forbids LOGIN\\n\", srvc->user, srvc->host);\n@@ -1153,10 +1146,18 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc)\n \t\t}\n \t} /* !preauth */\n \n+\tif (cred.username)\n+\t\tcredential_approve(&cred);\n+\tcredential_clear(&cred);\n+\n \tctx->prefix = \"\";\n \treturn ctx;\n \n bail:\n+\tif (cred.username)\n+\t\tcredential_reject(&cred);\n+\tcredential_clear(&cred);\n+\n \timap_close_store(ctx);\n \treturn NULL;\n }\n-- \n2.0.0.rc1.1.gce060f5\n"},{"id":"239996","messageId":"20140428192349.GC25993@sigill.intra.peff.net","threadId":"36506","inReplyTo":"907d1444a8e17a43c03ee0c2bb04038bdd3372b8.1398620231.git.danalbert@google.com","subject":"Re: [PATCH] Uses git-credential for git-imap-send","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-04-28T19:23:49Z","receivedAt":"2014-04-28T19:23:49Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Apr 27, 2014 at 10:58:51AM -0700, Dan Albert wrote:\n\n> git-imap-send was directly prompting for a password rather than using\n> git-credential. git-send-email, on the other hand, supports git-credential.\n> \n> This is a necessary improvement for users that use two factor authentication, as\n> they should not be expected to remember all of their app specific passwords.\n> \n> Signed-off-by: Dan Albert <danalbert@google.com>\n\nThanks, this version looks good to me.\n\nI noticed that we are just filling in the password here, since we'll\nalways fill cred.username from srvc->user. The lines directly above are:\n\n\tif (!srvc->user) {\n\t\tfprintf(stderr, \"Skipping server %s, no user\\n\", srvc->host);\n\t\tgoto bail;\n\t}\n\nThat comes from the imap.user config variable. I wonder if we should\njust pass it off to credential_fill() in this case, too, which will fill\nin the username if necessary.\n\nIt probably doesn't matter much, though, as nobody is complaining. And\nif we were designing from scratch, I would say that \"imap.user\" and\n\"imap.pass\" would not need to exist, as you can configure\n\"credential.imaps://host/.*\" for the same purpose. But since we would\nhave to keep supporting them anyway for compatibility, it's not worth\ntrying to transition.\n\n-Peff\n"},{"id":"240106","messageId":"c3bb0fb7f87e6ada5c73923b14d66c743a76caa6.1398739667.git.danalbert@google.com","threadId":"36506","inReplyTo":"20140428192349.GC25993@sigill.intra.peff.net","subject":"[PATCH] Uses git-credential for git-imap-send","fromName":"Dan Albert","fromEmail":"danalbert@google.com","sentAt":"2014-04-29T03:00:04Z","receivedAt":"2014-04-29T03:00:04Z","isPatch":true,"sender":{"key":"danalbert@google.com","avatar":null},"body":"git-imap-send was directly prompting for a password rather than using\ngit-credential. git-send-email, on the other hand, supports git-credential.\n\nThis is a necessary improvement for users that use two factor authentication, as\nthey should not be expected to remember all of their app specific passwords.\n\nSigned-off-by: Dan Albert <danalbert@google.com>\n---\n\n> I noticed that we are just filling in the password here, since we'll\n> always fill cred.username from srvc->user. The lines directly above are:\n> \n>         if (!srvc->user) {\n>                 fprintf(stderr, \"Skipping server %s, no user\\n\", srvc->host);\n>                 goto bail;\n>         }\n> \n> That comes from the imap.user config variable. I wonder if we should\n> just pass it off to credential_fill() in this case, too, which will fill\n> in the username if necessary.\n> \n> It probably doesn't matter much, though, as nobody is complaining. And\n> if we were designing from scratch, I would say that \"imap.user\" and\n> \"imap.pass\" would not need to exist, as you can configure\n> \"credential.imaps://host/.*\" for the same purpose. But since we would\n> have to keep supporting them anyway for compatibility, it's not worth\n> trying to transition.\n\nYeah, doubtful anyone cares, but it's simple enough to do.\n\n imap-send.c | 45 ++++++++++++++++++++++++++-------------------\n 1 file changed, 26 insertions(+), 19 deletions(-)\n\ndiff --git a/imap-send.c b/imap-send.c\nindex 0bc6f7f..5c4f336 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -23,9 +23,9 @@\n  */\n \n #include \"cache.h\"\n+#include \"credential.h\"\n #include \"exec_cmd.h\"\n #include \"run-command.h\"\n-#include \"prompt.h\"\n #ifdef NO_OPENSSL\n typedef void *SSL;\n #endif\n@@ -946,6 +946,7 @@ static int auth_cram_md5(struct imap_store *ctx, struct imap_cmd *cmd, const cha\n \n static struct imap_store *imap_open_store(struct imap_server_conf *srvc)\n {\n+\tstruct credential cred = CREDENTIAL_INIT;\n \tstruct imap_store *ctx;\n \tstruct imap *imap;\n \tchar *arg, *rsp;\n@@ -1096,25 +1097,23 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc)\n \t\t}\n #endif\n \t\timap_info(\"Logging in...\\n\");\n-\t\tif (!srvc->user) {\n-\t\t\tfprintf(stderr, \"Skipping server %s, no user\\n\", srvc->host);\n-\t\t\tgoto bail;\n-\t\t}\n-\t\tif (!srvc->pass) {\n-\t\t\tstruct strbuf prompt = STRBUF_INIT;\n-\t\t\tstrbuf_addf(&prompt, \"Password (%s@%s): \", srvc->user, srvc->host);\n-\t\t\targ = git_getpass(prompt.buf);\n-\t\t\tstrbuf_release(&prompt);\n-\t\t\tif (!*arg) {\n-\t\t\t\tfprintf(stderr, \"Skipping account %s@%s, no password\\n\", srvc->user, srvc->host);\n-\t\t\t\tgoto bail;\n-\t\t\t}\n-\t\t\t/*\n-\t\t\t * getpass() returns a pointer to a static buffer.  make a copy\n-\t\t\t * for long term storage.\n-\t\t\t */\n-\t\t\tsrvc->pass = xstrdup(arg);\n+\t\tif (!srvc->user || !srvc->pass) {\n+\t\t\tcred.protocol = xstrdup(srvc->use_ssl ? \"imaps\" : \"imap\");\n+\t\t\tcred.host = xstrdup(srvc->host);\n+\n+\t\t\tif (srvc->user)\n+\t\t\t\tcred.username = xstrdup(srvc->user);\n+\t\t\tif (srvc->pass)\n+\t\t\t\tcred.password = xstrdup(srvc->pass);\n+\n+\t\t\tcredential_fill(&cred);\n+\n+\t\t\tif (!srvc->user)\n+\t\t\t\tsrvc->user = xstrdup(cred.username);\n+\t\t\tif (!srvc->pass)\n+\t\t\t\tsrvc->pass = xstrdup(cred.password);\n \t\t}\n+\n \t\tif (CAP(NOLOGIN)) {\n \t\t\tfprintf(stderr, \"Skipping account %s@%s, server forbids LOGIN\\n\", srvc->user, srvc->host);\n \t\t\tgoto bail;\n@@ -1153,10 +1152,18 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc)\n \t\t}\n \t} /* !preauth */\n \n+\tif (cred.username)\n+\t\tcredential_approve(&cred);\n+\tcredential_clear(&cred);\n+\n \tctx->prefix = \"\";\n \treturn ctx;\n \n bail:\n+\tif (cred.username)\n+\t\tcredential_reject(&cred);\n+\tcredential_clear(&cred);\n+\n \timap_close_store(ctx);\n \treturn NULL;\n }\n-- \n2.0.0.rc1.1.gce060f5\n"},{"id":"240107","messageId":"20140429030534.GA12118@sigill.intra.peff.net","threadId":"36506","inReplyTo":"c3bb0fb7f87e6ada5c73923b14d66c743a76caa6.1398739667.git.danalbert@google.com","subject":"Re: [PATCH] Uses git-credential for git-imap-send","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-04-29T03:05:34Z","receivedAt":"2014-04-29T03:05:34Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Apr 28, 2014 at 08:00:04PM -0700, Dan Albert wrote:\n\n> > I noticed that we are just filling in the password here, since we'll\n> > always fill cred.username from srvc->user. The lines directly above are:\n> > \n> >         if (!srvc->user) {\n> >                 fprintf(stderr, \"Skipping server %s, no user\\n\", srvc->host);\n> >                 goto bail;\n> >         }\n> > \n> > That comes from the imap.user config variable. I wonder if we should\n> > just pass it off to credential_fill() in this case, too, which will fill\n> > in the username if necessary.\n> [...]\n> \n> Yeah, doubtful anyone cares, but it's simple enough to do.\n\nThanks, I think the result looks good.\n\nAcked-by: Jeff King <peff@peff.net>\n\n-Peff\n"},{"id":"240187","messageId":"xmqqmwf4kq9i.fsf@gitster.dls.corp.google.com","threadId":"36506","inReplyTo":"20140429030534.GA12118@sigill.intra.peff.net","subject":"Re: [PATCH] Uses git-credential for git-imap-send","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-04-29T17:19:05Z","receivedAt":"2014-04-29T17:19:05Z","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 Mon, Apr 28, 2014 at 08:00:04PM -0700, Dan Albert wrote:\n>\n>> > I noticed that we are just filling in the password here, since we'll\n>> > always fill cred.username from srvc->user. The lines directly above are:\n>> > \n>> >         if (!srvc->user) {\n>> >                 fprintf(stderr, \"Skipping server %s, no user\\n\", srvc->host);\n>> >                 goto bail;\n>> >         }\n>> > \n>> > That comes from the imap.user config variable. I wonder if we should\n>> > just pass it off to credential_fill() in this case, too, which will fill\n>> > in the username if necessary.\n>> [...]\n>> \n>> Yeah, doubtful anyone cares, but it's simple enough to do.\n>\n> Thanks, I think the result looks good.\n>\n> Acked-by: Jeff King <peff@peff.net>\n\nOK, luckily I haven't merged the one from the yesterday yet, so I'll\nreplace ;-)\n\nThanks for working on this, Dan, and as always thanks for reviewing,\nPeff.\n"}]}