{"thread":{"id":"36556","subject":"[RFD] use approxidate for \"git commit --date=xyz\"?","startedAt":"2014-04-30T21:09:10Z","lastAt":"2014-05-07T07:22:15Z","messageCount":9,"participants":["Linus Torvalds","Junio C Hamano","Jeff King","Peter Krefting"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"240371","messageId":"CA+55aFx=LizEyS6hq=av_qwRZuu_q3xPSXO-Jr4CAfXqaAuUtA@mail.gmail.com","threadId":"36556","inReplyTo":null,"subject":"[RFD] use approxidate for \"git commit --date=xyz\"?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2014-04-30T21:09:10Z","receivedAt":"2014-04-30T21:09:10Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"I just got a comment saying that\n\n    git commit --amend --date=now\n\ndoesn't work. I replied that you can use\n\n   --date=\"$(date)\"\n\nbut I do wonder if we should accept the approxidate format - we do in\nother equivalent places. Hmm?\n\nThe code uses fmt_ident(), which uses parse_date(), which in turn uses\nparse_date_basic(). Maybe parse_date() could use\n\"approxidate_careful()\" instead of \"parse_date_basic()\"?\n\n            Linus\n"},{"id":"240373","messageId":"xmqq1tweec1o.fsf@gitster.dls.corp.google.com","threadId":"36556","inReplyTo":"CA+55aFx=LizEyS6hq=av_qwRZuu_q3xPSXO-Jr4CAfXqaAuUtA@mail.gmail.com","subject":"Re: [RFD] use approxidate for \"git commit --date=xyz\"?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-04-30T21:34:59Z","receivedAt":"2014-04-30T21:34:59Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> I just got a comment saying that\n>\n>     git commit --amend --date=now\n>\n> doesn't work. I replied that you can use\n>\n>    --date=\"$(date)\"\n\nOffhand without double-checking the actual codepath I do not have\nobjection against approxidate-careful.\n\nBut why does the workflow need --date=now in the first place?\nWouldn't --reset-author do what you want better?  What is the\nsituation where you want to say that this patch has been changed\nsignificantly enough from the original to label it with the current\ntimestamp without taking the authorship?\n\n> but I do wonder if we should accept the approxidate format - we do in\n> other equivalent places. Hmm?\n>\n> The code uses fmt_ident(), which uses parse_date(), which in turn uses\n> parse_date_basic(). Maybe parse_date() could use\n> \"approxidate_careful()\" instead of \"parse_date_basic()\"?\n>\n>             Linus\n"},{"id":"240478","messageId":"20140501220639.GD14441@sigill.intra.peff.net","threadId":"36556","inReplyTo":"xmqq1tweec1o.fsf@gitster.dls.corp.google.com","subject":"Re: [RFD] use approxidate for \"git commit --date=xyz\"?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-05-01T22:06:39Z","receivedAt":"2014-05-01T22:06:39Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Apr 30, 2014 at 02:34:59PM -0700, Junio C Hamano wrote:\n\n> Linus Torvalds <torvalds@linux-foundation.org> writes:\n> \n> > I just got a comment saying that\n> >\n> >     git commit --amend --date=now\n> >\n> > doesn't work. I replied that you can use\n> >\n> >    --date=\"$(date)\"\n> \n> Offhand without double-checking the actual codepath I do not have\n> objection against approxidate-careful.\n\nThis has come up a few times on the list, but nobody ever produced a\npatch. To quote myself[1]:\n\n> I think the original rationale was that it's OK for us to allow some\n> sloppiness when _viewing_ commits, since you will generally notice the\n> problem. But when making commits, it's better to be careful, since you\n> may be setting the sha1 in stone.\n> \n> These days we have two tools that could help:\n> \n>   1. approxidate_careful will do a regular approxidate, but keep track\n>   of whether we found anything even remotely useful. That doesn't mean\n>   you can't still get unexpected results, but at least some truly\n>   useless cases return errors.\n> \n>   2. For commits with a different author and committer, we mention the\n>   author name in the post-commit summary. We could do the same with a\n>   timestamp that was given (i.e., mentioning it in a standard format)\n>   to give the user another opportunity to double-check what we parsed.\n\nI think it would make sense if we followed both of those points.\n\nShould we also loosen $GIT_AUTHOR_DATE? I'd prefer not to, as that is\nnot typically fed by the users themselves, but rather by scripts, and\nbeing robust there may be more valuable.\n\n> But why does the workflow need --date=now in the first place?\n> Wouldn't --reset-author do what you want better?  What is the\n> situation where you want to say that this patch has been changed\n> significantly enough from the original to label it with the current\n> timestamp without taking the authorship?\n\nIn some of the instances on the list, the user simply didn't know that\n--reset-author would do the trick. And I do think it's slightly\nunintuitive.\n\nHowever, the original rationale for \"--date\" was to back-date\ncommits[2], so even though there is an equivalent for \"--date=now\", it\nmight be nice to support \"--date=2.days.ago\".\n\n-Peff\n\n[1] http://article.gmane.org/gmane.comp.version-control.git/168596\n\n[2] http://article.gmane.org/gmane.comp.version-control.git/134406\n"},{"id":"240504","messageId":"20140502010328.GA30556@sigill.intra.peff.net","threadId":"36556","inReplyTo":"20140501220639.GD14441@sigill.intra.peff.net","subject":"[PATCH 0/4] approxidate for \"git commit --date=foo\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-05-02T01:03:28Z","receivedAt":"2014-05-02T01:03:28Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, May 01, 2014 at 06:06:39PM -0400, Jeff King wrote:\n\n> > I think the original rationale was that it's OK for us to allow some\n> > sloppiness when _viewing_ commits, since you will generally notice the\n> > problem. But when making commits, it's better to be careful, since you\n> > may be setting the sha1 in stone.\n> > \n> > These days we have two tools that could help:\n> > \n> >   1. approxidate_careful will do a regular approxidate, but keep track\n> >   of whether we found anything even remotely useful. That doesn't mean\n> >   you can't still get unexpected results, but at least some truly\n> >   useless cases return errors.\n> > \n> >   2. For commits with a different author and committer, we mention the\n> >   author name in the post-commit summary. We could do the same with a\n> >   timestamp that was given (i.e., mentioning it in a standard format)\n> >   to give the user another opportunity to double-check what we parsed.\n> \n> I think it would make sense if we followed both of those points.\n\nHere are patches to do so.\n\n  [1/4]: commit: use split_ident_line to compare author/committer\n  [2/4]: pretty: make show_ident_date public\n  [3/4]: commit: print \"Date\" line when the user has set date\n  [4/4]: commit: accept more date formats for \"--date\"\n\n-Peff\n"},{"id":"240505","messageId":"20140502010656.GA25413@sigill.intra.peff.net","threadId":"36556","inReplyTo":"20140502010328.GA30556@sigill.intra.peff.net","subject":"[PATCH 1/4] commit: use split_ident_line to compare author/committer","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-05-02T01:06:57Z","receivedAt":"2014-05-02T01:06:57Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"Instead of string-wise comparing the author/committer lines\nwith their timestamps truncated, we can use split_ident_line\nand ident_cmp. These functions are more robust than our\nad-hoc parsing, though in practice it should not matter, as\nwe just generated these ident lines ourselves.\n\nHowever, this will also allow us easy access to the\ntimestamp and tz fields in future patches.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n builtin/commit.c | 33 ++++++++++++++++-----------------\n 1 file changed, 16 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 9cfef6c..728cc9b 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -585,13 +585,11 @@ static void determine_author_info(struct strbuf *author_ident)\n \t}\n }\n \n-static char *cut_ident_timestamp_part(char *string)\n+static void split_ident_or_die(struct ident_split *id, const struct strbuf *buf)\n {\n-\tchar *ket = strrchr(string, '>');\n-\tif (!ket || ket[1] != ' ')\n-\t\tdie(_(\"Malformed ident string: '%s'\"), string);\n-\t*++ket = '\\0';\n-\treturn ket;\n+\tif (split_ident_line(id, buf->buf, buf->len) ||\n+\t    !sane_ident_split(id))\n+\t\tdie(_(\"Malformed ident string: '%s'\"), buf->buf);\n }\n \n static int prepare_to_commit(const char *index_file, const char *prefix,\n@@ -755,7 +753,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \tif (use_editor && include_status) {\n \t\tint ident_shown = 0;\n \t\tint saved_color_setting;\n-\t\tchar *ai_tmp, *ci_tmp;\n+\t\tstruct ident_split ci, ai;\n+\n \t\tif (whence != FROM_COMMIT) {\n \t\t\tif (cleanup_mode == CLEANUP_SCISSORS)\n \t\t\t\twt_status_add_cut_line(s->fp);\n@@ -795,21 +794,24 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL,\n \t\t\t\t\t\"%s\", only_include_assumed);\n \n-\t\tai_tmp = cut_ident_timestamp_part(author_ident->buf);\n-\t\tci_tmp = cut_ident_timestamp_part(committer_ident.buf);\n-\t\tif (strcmp(author_ident->buf, committer_ident.buf))\n+\t\tsplit_ident_or_die(&ai, author_ident);\n+\t\tsplit_ident_or_die(&ci, &committer_ident);\n+\n+\t\tif (ident_cmp(&ai, &ci))\n \t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL,\n \t\t\t\t_(\"%s\"\n-\t\t\t\t\"Author:    %s\"),\n+\t\t\t\t\"Author:    %.*s <%.*s>\"),\n \t\t\t\tident_shown++ ? \"\" : \"\\n\",\n-\t\t\t\tauthor_ident->buf);\n+\t\t\t\t(int)(ai.name_end - ai.name_begin), ai.name_begin,\n+\t\t\t\t(int)(ai.mail_end - ai.mail_begin), ai.mail_begin);\n \n \t\tif (!committer_ident_sufficiently_given())\n \t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL,\n \t\t\t\t_(\"%s\"\n-\t\t\t\t\"Committer: %s\"),\n+\t\t\t\t\"Committer: %.*s <%.*s>\"),\n \t\t\t\tident_shown++ ? \"\" : \"\\n\",\n-\t\t\t\tcommitter_ident.buf);\n+\t\t\t\t(int)(ci.name_end - ci.name_begin), ci.name_begin,\n+\t\t\t\t(int)(ci.mail_end - ci.mail_begin), ci.mail_begin);\n \n \t\tif (ident_shown)\n \t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL, \"\");\n@@ -818,9 +820,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\ts->use_color = 0;\n \t\tcommitable = run_status(s->fp, index_file, prefix, 1, s);\n \t\ts->use_color = saved_color_setting;\n-\n-\t\t*ai_tmp = ' ';\n-\t\t*ci_tmp = ' ';\n \t} else {\n \t\tunsigned char sha1[20];\n \t\tconst char *parent = \"HEAD\";\n-- \n1.9.1.656.ge8a0637\n"},{"id":"240506","messageId":"20140502010722.GB25413@sigill.intra.peff.net","threadId":"36556","inReplyTo":"20140502010328.GA30556@sigill.intra.peff.net","subject":"[PATCH 2/4] pretty: make show_ident_date public","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-05-02T01:07:22Z","receivedAt":"2014-05-02T01:07:22Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"We use this function internally to format \"Date\" lines in\ncommit logs, but other parts of the code will want it, too.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n cache.h  | 7 +++++++\n pretty.c | 4 ++--\n 2 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 107ac61..dd9e689 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1046,6 +1046,13 @@ struct ident_split {\n extern int split_ident_line(struct ident_split *, const char *, int);\n \n /*\n+ * Like show_date, but pull the timestamp and tz parameters from\n+ * the ident_split. It will also sanity-check the values and produce\n+ * a well-known sentinel date if they appear bogus.\n+ */\n+const char *show_ident_date(const struct ident_split *id, enum date_mode mode);\n+\n+/*\n  * Compare split idents for equality or strict ordering. Note that we\n  * compare only the ident part of the line, ignoring any timestamp.\n  *\ndiff --git a/pretty.c b/pretty.c\nindex 3c43db5..e1e2cad 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -393,8 +393,8 @@ static void add_rfc2047(struct strbuf *sb, const char *line, size_t len,\n \tstrbuf_addstr(sb, \"?=\");\n }\n \n-static const char *show_ident_date(const struct ident_split *ident,\n-\t\t\t\t   enum date_mode mode)\n+const char *show_ident_date(const struct ident_split *ident,\n+\t\t\t    enum date_mode mode)\n {\n \tunsigned long date = 0;\n \tlong tz = 0;\n-- \n1.9.1.656.ge8a0637\n"},{"id":"240507","messageId":"20140502011001.GC25413@sigill.intra.peff.net","threadId":"36556","inReplyTo":"20140502010328.GA30556@sigill.intra.peff.net","subject":"[PATCH 3/4] commit: print \"Date\" line when the user has set date","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-05-02T01:10:01Z","receivedAt":"2014-05-02T01:10:01Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"When we make a commit and the author is not the same as the\ncommitter (e.g., because you used \"-c $commit\" or\n\"--author=$somebody\"), we print the author's name and email\nin both the commit-message template and as part of the\ncommit summary. This is a safety check to give the user a\nchance to confirm that we are doing what they expect.\n\nThis patch brings the same safety for the \"date\" field,\nwhich may be set by \"-c\" or by using \"--date\".  Note that we\nexplicitly do not set it for $GIT_AUTHOR_DATE, as it is\nprobably not of interest when \"git commit\" is being fed its\nparameters by a script.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nNote the test updates in t3508, as cherry-picks will now print the date.\nI think that's probably a good thing, but if we don't like it, we can\ntweak author_date_is_interesting() to only check force_date.\n\nI'd also be open to using a different date format than DATE_NORMAL if\npeople care. I guess we could respect log.date.\n\n builtin/commit.c                    | 19 +++++++++++++++++++\n t/t3508-cherry-pick-many-commits.sh |  6 ++++++\n t/t7501-commit.sh                   |  5 +++++\n t/t7502-commit.sh                   |  7 +++++++\n 4 files changed, 37 insertions(+)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 728cc9b..a25661f 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -592,6 +592,11 @@ static void split_ident_or_die(struct ident_split *id, const struct strbuf *buf)\n \t\tdie(_(\"Malformed ident string: '%s'\"), buf->buf);\n }\n \n+static int author_date_is_interesting(void)\n+{\n+\treturn author_message || force_date;\n+}\n+\n static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\t\t     struct commit *current_head,\n \t\t\t     struct wt_status *s,\n@@ -805,6 +810,13 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\t\t\t(int)(ai.name_end - ai.name_begin), ai.name_begin,\n \t\t\t\t(int)(ai.mail_end - ai.mail_begin), ai.mail_begin);\n \n+\t\tif (author_date_is_interesting())\n+\t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL,\n+\t\t\t\t_(\"%s\"\n+\t\t\t\t\"Date:      %s\"),\n+\t\t\t\tident_shown++ ? \"\" : \"\\n\",\n+\t\t\t\tshow_ident_date(&ai, DATE_NORMAL));\n+\n \t\tif (!committer_ident_sufficiently_given())\n \t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL,\n \t\t\t\t_(\"%s\"\n@@ -1355,6 +1367,13 @@ static void print_summary(const char *prefix, const unsigned char *sha1,\n \t\tstrbuf_addstr(&format, \"\\n Author: \");\n \t\tstrbuf_addbuf_percentquote(&format, &author_ident);\n \t}\n+\tif (author_date_is_interesting()) {\n+\t\tstruct strbuf date = STRBUF_INIT;\n+\t\tformat_commit_message(commit, \"%ad\", &date, &pctx);\n+\t\tstrbuf_addstr(&format, \"\\n Date: \");\n+\t\tstrbuf_addbuf_percentquote(&format, &date);\n+\t\tstrbuf_release(&date);\n+\t}\n \tif (!committer_ident_sufficiently_given()) {\n \t\tstrbuf_addstr(&format, \"\\n Committer: \");\n \t\tstrbuf_addbuf_percentquote(&format, &committer_ident);\ndiff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh\nindex 19c99d7..b457333 100755\n--- a/t/t3508-cherry-pick-many-commits.sh\n+++ b/t/t3508-cherry-pick-many-commits.sh\n@@ -65,12 +65,15 @@ test_expect_success 'output to keep user entertained during multi-pick' '\n \tcat <<-\\EOF >expected &&\n \t[master OBJID] second\n \t Author: A U Thor <author@example.com>\n+\t Date: Thu Apr 7 15:14:13 2005 -0700\n \t 1 file changed, 1 insertion(+)\n \t[master OBJID] third\n \t Author: A U Thor <author@example.com>\n+\t Date: Thu Apr 7 15:15:13 2005 -0700\n \t 1 file changed, 1 insertion(+)\n \t[master OBJID] fourth\n \t Author: A U Thor <author@example.com>\n+\t Date: Thu Apr 7 15:16:13 2005 -0700\n \t 1 file changed, 1 insertion(+)\n \tEOF\n \n@@ -98,14 +101,17 @@ test_expect_success 'output during multi-pick indicates merge strategy' '\n \tTrying simple merge.\n \t[master OBJID] second\n \t Author: A U Thor <author@example.com>\n+\t Date: Thu Apr 7 15:14:13 2005 -0700\n \t 1 file changed, 1 insertion(+)\n \tTrying simple merge.\n \t[master OBJID] third\n \t Author: A U Thor <author@example.com>\n+\t Date: Thu Apr 7 15:15:13 2005 -0700\n \t 1 file changed, 1 insertion(+)\n \tTrying simple merge.\n \t[master OBJID] fourth\n \t Author: A U Thor <author@example.com>\n+\t Date: Thu Apr 7 15:16:13 2005 -0700\n \t 1 file changed, 1 insertion(+)\n \tEOF\n \ndiff --git a/t/t7501-commit.sh b/t/t7501-commit.sh\nindex d58b097..5a76823 100755\n--- a/t/t7501-commit.sh\n+++ b/t/t7501-commit.sh\n@@ -346,6 +346,11 @@ test_expect_success 'amend commit to fix date' '\n \n '\n \n+test_expect_success 'commit mentions forced date in output' '\n+\tgit commit --amend --date=2010-01-02T03:04:05 >output &&\n+\tgrep \"Date: *Sat Jan 2 03:04:05 2010\" output\n+'\n+\n test_expect_success 'commit complains about bogus date' '\n \ttest_must_fail git commit --amend --date=10.11.2010\n '\ndiff --git a/t/t7502-commit.sh b/t/t7502-commit.sh\nindex 9a3f3a1..6465cd5 100755\n--- a/t/t7502-commit.sh\n+++ b/t/t7502-commit.sh\n@@ -344,6 +344,13 @@ test_expect_success 'message shows author when it is not equal to committer' '\n \t  .git/COMMIT_EDITMSG\n '\n \n+test_expect_success 'message shows date when it is explicitly set' '\n+\tgit commit --allow-empty -e -m foo --date=\"2010-01-02T03:04:05\" &&\n+\ttest_i18ngrep \\\n+\t  \"^# Date: *Sat Jan 2 03:04:05 2010 +0000\" \\\n+\t  .git/COMMIT_EDITMSG\n+'\n+\n test_expect_success AUTOIDENT 'message shows committer when it is automatic' '\n \n \techo >>negative &&\n-- \n1.9.1.656.ge8a0637\n"},{"id":"240509","messageId":"20140502011242.GD25413@sigill.intra.peff.net","threadId":"36556","inReplyTo":"20140502010328.GA30556@sigill.intra.peff.net","subject":"[PATCH 4/4] commit: accept more date formats for \"--date\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-05-02T01:12:42Z","receivedAt":"2014-05-02T01:12:42Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"Right now we pass off the string found by \"--date\" straight\nto the fmt_ident function, which will use our strict\nparse_date to normalize it. However, this means obvious\nthings like \"--date=now\" or \"--date=2.days.ago\" will not\nwork.\n\nInstead, let's fallback to the approxidate function to\nhandle this for us. Note that we must try parse_date\nourselves first, even though approxidate will try strict\nparsing itself. The reason is that approxidate throws away\nany timezone information it sees from the strict parsing,\nand we want to preserve it. So asking for:\n\n  git commit --date=\"@1234567890 -0700\"\n\ncontinues to set the date in -0700, regardless of what the\nlocal timezone is.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n builtin/commit.c  | 27 +++++++++++++++++++++++++--\n t/t7501-commit.sh | 12 ++++++++++--\n 2 files changed, 35 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex a25661f..d1c90db 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -526,10 +526,29 @@ static int sane_ident_split(struct ident_split *person)\n \treturn 1;\n }\n \n+static int parse_force_date(const char *in, char *out, int len)\n+{\n+\tif (len < 1)\n+\t\treturn -1;\n+\t*out++ = '@';\n+\tlen--;\n+\n+\tif (parse_date(in, out, len) < 0) {\n+\t\tint errors = 0;\n+\t\tunsigned long t = approxidate_careful(in, &errors);\n+\t\tif (errors)\n+\t\t\treturn -1;\n+\t\tsnprintf(out, len, \"%lu\", t);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static void determine_author_info(struct strbuf *author_ident)\n {\n \tchar *name, *email, *date;\n \tstruct ident_split author;\n+\tchar date_buf[64];\n \n \tname = getenv(\"GIT_AUTHOR_NAME\");\n \temail = getenv(\"GIT_AUTHOR_EMAIL\");\n@@ -574,8 +593,12 @@ static void determine_author_info(struct strbuf *author_ident)\n \t\temail = xstrndup(lb + 2, rb - (lb + 2));\n \t}\n \n-\tif (force_date)\n-\t\tdate = force_date;\n+\tif (force_date) {\n+\t\tif (parse_force_date(force_date, date_buf, sizeof(date_buf)))\n+\t\t\tdie(_(\"invalid date format: %s\"), force_date);\n+\t\tdate = date_buf;\n+\t}\n+\n \tstrbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT));\n \tif (!split_ident_line(&author, author_ident->buf, author_ident->len) &&\n \t    sane_ident_split(&author)) {\ndiff --git a/t/t7501-commit.sh b/t/t7501-commit.sh\nindex 5a76823..63e0427 100755\n--- a/t/t7501-commit.sh\n+++ b/t/t7501-commit.sh\n@@ -351,8 +351,16 @@ test_expect_success 'commit mentions forced date in output' '\n \tgrep \"Date: *Sat Jan 2 03:04:05 2010\" output\n '\n \n-test_expect_success 'commit complains about bogus date' '\n-\ttest_must_fail git commit --amend --date=10.11.2010\n+test_expect_success 'commit complains about completely bogus dates' '\n+\ttest_must_fail git commit --amend --date=seventeen\n+'\n+\n+test_expect_success 'commit --date allows approxidate' '\n+\tgit commit --amend \\\n+\t\t--date=\"midnight the 12th of october, anno domini 1979\" &&\n+\techo \"Fri Oct 12 00:00:00 1979 +0000\" >expect &&\n+\tgit log -1 --format=%ad >actual &&\n+\ttest_cmp expect actual\n '\n \n test_expect_success 'sign off (1)' '\n-- \n1.9.1.656.ge8a0637\n"},{"id":"240873","messageId":"alpine.DEB.2.00.1405070817580.15517@ds9.cixit.se","threadId":"36556","inReplyTo":"xmqq1tweec1o.fsf@gitster.dls.corp.google.com","subject":"Re: [RFD] use approxidate for \"git commit --date=xyz\"?","fromName":"Peter Krefting","fromEmail":"peter@softwolves.pp.se","sentAt":"2014-05-07T07:22:15Z","receivedAt":"2014-05-07T07:22:15Z","isPatch":false,"sender":{"key":"peter@softwolves.pp.se","avatar":"https://avatars.githubusercontent.com/u/990764?v=4"},"body":"Junio C Hamano:\n\n> But why does the workflow need --date=now in the first place?\n\nI tend to do this quite a lot, after fixing up a commit using rebase, \nI notice that the commit date is when I first started fixing the \nissue, even if that was a week or so ago. I then like to reset the \ncommit date to reflect when I actually was done with it, and try \n\"commit --amend --date=now\".\n\nI just haven't been annoyed enough to patch the code to fix it (so the \ngit repository at my $dayjob does have a number of commits with the \"wrong\" \ncommit time in it [1]), but I would welcome such an addition.\n\n-- \n\\\\// Peter - http://www.softwolves.pp.se/\n\n  [1] The last such is one that took me about a week to implement:\n       AuthorDate: 2014-04-15 15:48:38 +0200\n       CommitDate: 2014-04-22 09:23:25 +0100\n      it'd look better to have the AuthorDate at the 22nd as well, imho.\n"}]}