{"thread":{"id":"59258","subject":"Feature request: Add --mtime option to git archive","startedAt":"2023-02-16T19:41:47Z","lastAt":"2023-02-22T23:24:12Z","messageCount":16,"participants":["Raul E Rangel","Jeff King","Junio C Hamano","Raul Rangel","René Scharfe","demerphq","brian m. carlson"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"472220","messageId":"Y+6G9n6cWRT9EKyl@google.com","threadId":"59258","inReplyTo":null,"subject":"Feature request: Add --mtime option to git archive","fromName":"Raul E Rangel","fromEmail":"rrangel@chromium.org","sentAt":"2023-02-16T19:41:42Z","receivedAt":"2023-02-16T19:41:47Z","isPatch":false,"sender":{"key":"rrangel@chromium.org","avatar":null},"body":"When generating a tarball with `git archive <tree>`, `git archive` will\nuse the current time as the mtime. This results in a non-hermetic\ntarball. Could we should add a --mtime option that allows passing in\nthe time? \n\nThanks!\n"},{"id":"472228","messageId":"Y+6akicTFG9n0eZy@coredump.intra.peff.net","threadId":"59258","inReplyTo":"Y+6G9n6cWRT9EKyl@google.com","subject":"Re: Feature request: Add --mtime option to git archive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2023-02-16T21:05:22Z","receivedAt":"2023-02-16T21:05:28Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Feb 16, 2023 at 12:41:42PM -0700, Raul E Rangel wrote:\n\n> When generating a tarball with `git archive <tree>`, `git archive` will\n> use the current time as the mtime. This results in a non-hermetic\n> tarball. Could we should add a --mtime option that allows passing in\n> the time? \n\nThat seems like a very reasonable feature to have. Just to sketch out\nthe implementation, in case anybody wants to work on it:\n\n  - options are read first in cmd_archive(), but it passes unknown ones\n    on to write_archive(), which is where we parse the interesting ones.\n\n  - that relies on parse_archive_args() in archive.c. So we'd want a new\n    option in opts[] there, and to write the value into a new field in\n    the archiver_args struct.\n\n  - the time is filled in via parse_treeish_arg(), where we use\n    time(NULL) if there's no commit. And there we'd just use the value\n    from archiver_args.\n\n    If there is a commit and they've specified --mtime, what should\n    happen? Quietly ignore it? Override the commit's timestamp? Complain\n    and bail?\n\n  - I didn't look at how this might interact with \"git archive\n    --remote\". I think it might just all work, as we just ship the\n    options to the other side, which parses them itself using the same\n    code.\n\n-Peff\n"},{"id":"472229","messageId":"xmqq5yc1p7yn.fsf@gitster.g","threadId":"59258","inReplyTo":"Y+6akicTFG9n0eZy@coredump.intra.peff.net","subject":"Re: Feature request: Add --mtime option to git archive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-02-16T22:21:36Z","receivedAt":"2023-02-16T22:21:40Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Thu, Feb 16, 2023 at 12:41:42PM -0700, Raul E Rangel wrote:\n>\n>> When generating a tarball with `git archive <tree>`, `git archive` will\n>> use the current time as the mtime. This results in a non-hermetic\n>> tarball. Could we should add a --mtime option that allows passing in\n>> the time? \n>\n> That seems like a very reasonable feature to have. Just to sketch out\n> the implementation, in case anybody wants to work on it: ...\n\nThere has been a discussion on not just \"fix mtime\" but coming up\nwith a lot more stable tar archive format specification.\n\nThe first link is about documenting the status quo.  The second one\nis about the proposed format that aims to be stable.\n\nhttps://lore.kernel.org/git/20230203080629.31492-1-ray@ameretat.dev/\nhttps://lore.kernel.org/git/20230205221728.4179674-2-sandals@crustytoothpaste.net/\n\n"},{"id":"472243","messageId":"Y+7PcqpYhF5ZuApG@coredump.intra.peff.net","threadId":"59258","inReplyTo":"xmqq5yc1p7yn.fsf@gitster.g","subject":"Re: Feature request: Add --mtime option to git archive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2023-02-17T00:50:58Z","receivedAt":"2023-02-17T00:51:24Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Feb 16, 2023 at 02:21:36PM -0800, Junio C Hamano wrote:\n\n> >> When generating a tarball with `git archive <tree>`, `git archive` will\n> >> use the current time as the mtime. This results in a non-hermetic\n> >> tarball. Could we should add a --mtime option that allows passing in\n> >> the time? \n> >\n> > That seems like a very reasonable feature to have. Just to sketch out\n> > the implementation, in case anybody wants to work on it: ...\n> \n> There has been a discussion on not just \"fix mtime\" but coming up\n> with a lot more stable tar archive format specification.\n\nYes, I think in brian's proposal the mtime would always be 0. I don't\nmind that either (and really, I doubt anybody would really want to set\n--mtime to anything but a fixed, known value anyway). This is a much\nsmaller change that could be done in the meantime with less effort, but\nI guess we'd be stuck with --mtime forever, then.\n\nA similar option in is to simply start using \"0\" in the meantime, like:\n\ndiff --git a/archive.c b/archive.c\nindex 81ff76fce9..48d89785c3 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -470,7 +470,7 @@ static void parse_treeish_arg(const char **argv,\n \t\tarchive_time = commit->date;\n \t} else {\n \t\tcommit_oid = NULL;\n-\t\tarchive_time = time(NULL);\n+\t\tarchive_time = 0;\n \t}\n \n \ttree = parse_tree_indirect(&oid);\n\nNobody will complain about changing the byte-for-byte format, since by definition it\nwas already changing once per second (cue somebody complaining that they\nhave been using LD_PRELOAD tricks to simulate --mtime).\n\nI do wonder if people would complain (both with the patch above and with\nbrian's proposal) that the resulting tarballs extract everything with a\ndate in 1970. That's not functionally a problem, but it looks kind of\nweird in \"ls -l\".\n\n-Peff\n"},{"id":"472245","messageId":"xmqqpma9m4i1.fsf@gitster.g","threadId":"59258","inReplyTo":"Y+7PcqpYhF5ZuApG@coredump.intra.peff.net","subject":"Re: Feature request: Add --mtime option to git archive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-02-17T02:04:38Z","receivedAt":"2023-02-17T02:04:43Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> A similar option in is to simply start using \"0\" in the meantime, like:\n>\n> diff --git a/archive.c b/archive.c\n> index 81ff76fce9..48d89785c3 100644\n> --- a/archive.c\n> +++ b/archive.c\n> @@ -470,7 +470,7 @@ static void parse_treeish_arg(const char **argv,\n>  \t\tarchive_time = commit->date;\n>  \t} else {\n>  \t\tcommit_oid = NULL;\n> -\t\tarchive_time = time(NULL);\n> +\t\tarchive_time = 0;\n>  \t}\n>  \n>  \ttree = parse_tree_indirect(&oid);\n>\n> Nobody will complain about changing the byte-for-byte format, since by definition it\n> was already changing once per second (cue somebody complaining that they\n> have been using LD_PRELOAD tricks to simulate --mtime).\n>\n> I do wonder if people would complain (both with the patch above and with\n> brian's proposal) that the resulting tarballs extract everything with a\n> date in 1970. That's not functionally a problem, but it looks kind of\n> weird in \"ls -l\".\n\nAnd owned by root:root ;-)\n\nI am sure people would complain.  What matters is if these\ncomplaints have merit, and in this case, I doubt it.  I especially\nlike your \"it has been already changing once per second\" reasoning\nfor this change.\n"},{"id":"472256","messageId":"CAHQZ30Dq1_vdJj_hakqXKFUbuqn9ysNsw-zzN83RmUVbibA3Gw@mail.gmail.com","threadId":"59258","inReplyTo":"xmqqpma9m4i1.fsf@gitster.g","subject":"Re: Feature request: Add --mtime option to git archive","fromName":"Raul Rangel","fromEmail":"rrangel@chromium.org","sentAt":"2023-02-17T15:43:03Z","receivedAt":"2023-02-17T15:43:20Z","isPatch":false,"sender":{"key":"rrangel@chromium.org","avatar":null},"body":"On Thu, Feb 16, 2023 at 7:04 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Jeff King <peff@peff.net> writes:\n>\n> > A similar option in is to simply start using \"0\" in the meantime, like:\n> >\n> > diff --git a/archive.c b/archive.c\n> > index 81ff76fce9..48d89785c3 100644\n> > --- a/archive.c\n> > +++ b/archive.c\n> > @@ -470,7 +470,7 @@ static void parse_treeish_arg(const char **argv,\n> >               archive_time = commit->date;\n> >       } else {\n> >               commit_oid = NULL;\n> > -             archive_time = time(NULL);\n> > +             archive_time = 0;\n> >       }\n> >\n> >       tree = parse_tree_indirect(&oid);\n> >\n> > Nobody will complain about changing the byte-for-byte format, since by definition it\n> > was already changing once per second (cue somebody complaining that they\n> > have been using LD_PRELOAD tricks to simulate --mtime).\n> >\n> > I do wonder if people would complain (both with the patch above and with\n> > brian's proposal) that the resulting tarballs extract everything with a\n> > date in 1970. That's not functionally a problem, but it looks kind of\n> > weird in \"ls -l\".\n>\n> And owned by root:root ;-)\n\nI fully support both of those easy changes. Only reason I proposed\n--mtime was that https://reproducible-builds.org/docs/archives/\nrecommends setting SOURCE_DATE_EPOCH, but honestly for my purposes I\nwould always use 0 and root:root.\n\n>\n> I am sure people would complain.  What matters is if these\n> complaints have merit, and in this case, I doubt it.  I especially\n> like your \"it has been already changing once per second\" reasoning\n> for this change.\n"},{"id":"472264","messageId":"Y+/iu7j+NsS/3sAX@coredump.intra.peff.net","threadId":"59258","inReplyTo":"xmqqpma9m4i1.fsf@gitster.g","subject":"Re: Feature request: Add --mtime option to git archive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2023-02-17T20:25:31Z","receivedAt":"2023-02-17T20:26:39Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Feb 16, 2023 at 06:04:38PM -0800, Junio C Hamano wrote:\n\n> > I do wonder if people would complain (both with the patch above and with\n> > brian's proposal) that the resulting tarballs extract everything with a\n> > date in 1970. That's not functionally a problem, but it looks kind of\n> > weird in \"ls -l\".\n> \n> And owned by root:root ;-)\n\nYeah, though I think it's pretty standard these days to use\n--no-same-owner or equivalent (and it's the default for non-root users).\nAnd ditto for modes. I wondered if there was an equivalent for\ntimestamps. It looks like \"-m\" works (it just sets everything to the\ncurrent timestamp at time of extraction), but I don't know how portable\nthat is (and POSIX is no help with tar, as usual).\n\n-Peff\n"},{"id":"472265","messageId":"83635ee4-02a2-dea7-38fa-c7b65c30c897@web.de","threadId":"59258","inReplyTo":"CAHQZ30Dq1_vdJj_hakqXKFUbuqn9ysNsw-zzN83RmUVbibA3Gw@mail.gmail.com","subject":"Re: Feature request: Add --mtime option to git archive","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2023-02-17T20:31:45Z","receivedAt":"2023-02-17T20:32:13Z","isPatch":false,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 17.02.23 um 16:43 schrieb Raul Rangel:\n> On Thu, Feb 16, 2023 at 7:04 PM Junio C Hamano <gitster@pobox.com> wrote:\n>>\n>> Jeff King <peff@peff.net> writes:\n>>\n>>> A similar option in is to simply start using \"0\" in the meantime, like:\n>>>\n>>> diff --git a/archive.c b/archive.c\n>>> index 81ff76fce9..48d89785c3 100644\n>>> --- a/archive.c\n>>> +++ b/archive.c\n>>> @@ -470,7 +470,7 @@ static void parse_treeish_arg(const char **argv,\n>>>               archive_time = commit->date;\n>>>       } else {\n>>>               commit_oid = NULL;\n>>> -             archive_time = time(NULL);\n>>> +             archive_time = 0;\n>>>       }\n>>>\n>>>       tree = parse_tree_indirect(&oid);\n>>>\n>>> Nobody will complain about changing the byte-for-byte format, since by definition it\n>>> was already changing once per second (cue somebody complaining that they\n>>> have been using LD_PRELOAD tricks to simulate --mtime).\n\nAnd how are you now going to tell the current time on a remote git\nserver? ;)\n\n>>> I do wonder if people would complain (both with the patch above and with\n>>> brian's proposal) that the resulting tarballs extract everything with a\n>>> date in 1970. That's not functionally a problem, but it looks kind of\n>>> weird in \"ls -l\".\n\nYes, 21st century artifacts being sent back in time looks a bit strange.\nGNU tar and bsdtar provide option -m to ignore mtimes when extracting.\n\n>> And owned by root:root ;-)\n>\n> I fully support both of those easy changes. Only reason I proposed\n> --mtime was that https://reproducible-builds.org/docs/archives/\n> recommends setting SOURCE_DATE_EPOCH, but honestly for my purposes I\n> would always use 0 and root:root.\n\ngit archive already records root as user and group.\n\n>> I am sure people would complain.  What matters is if these\n>> complaints have merit, and in this case, I doubt it.  I especially\n>> like your \"it has been already changing once per second\" reasoning\n>> for this change.\n\nI find it quite convincing as well.\n\nRené\n\n"},{"id":"472291","messageId":"CANgJU+VaF7-SJgGPqYGEV5VcJd_nTt2SMOQ5u9mNZ_wsArKT6g@mail.gmail.com","threadId":"59258","inReplyTo":"xmqqpma9m4i1.fsf@gitster.g","subject":"Re: Feature request: Add --mtime option to git archive","fromName":"demerphq","fromEmail":"demerphq@gmail.com","sentAt":"2023-02-18T03:04:12Z","receivedAt":"2023-02-18T03:04:27Z","isPatch":false,"sender":{"key":"demerphq@gmail.com","avatar":null},"body":"On Fri, 17 Feb 2023 at 03:39, Junio C Hamano <gitster@pobox.com> wrote:\n> > I do wonder if people would complain (both with the patch above and with\n> > brian's proposal) that the resulting tarballs extract everything with a\n> > date in 1970. That's not functionally a problem, but it looks kind of\n> > weird in \"ls -l\".\n>\n> And owned by root:root ;-)\n>\n> I am sure people would complain.  What matters is if these\n> complaints have merit, and in this case, I doubt it.  I especially\n> like your \"it has been already changing once per second\" reasoning\n> for this change.\n\nI don't really get the argument as far as it is presented as a reason\n/not/ to support a --mtime option as was requested in this thread.\n\nYou yourself say \"people will complain\", and you seem to be planning\nto just ignore those complaints as lacking merit.  I honestly don't\nunderstand that, wouldn't it be less noise, less stress, and better\n\"customer service\" to let the user choose what constant is in the\narchive?  Then no complaints, and you don't have to explain/argue\nto/with everybody why their complaint is without merit over and over.\n\nI could understand this position if letting the user set the --mtime\nimplied some harm that must be mitigated, but it seems like an odd\nchoice if there is none.  Especially given it would also future proof\ngit against people coming up with a good reason not to use the 0 epoch\nin the future that you haven't thought of right now. It is not like\nepoch's and unix time have a totally uncontroversial and stable\nhistory. 0 has meant multiple dates over time, and the current\ndefinition of 1 Jan 1970, 00:00:00 UTC is problematic as UTC didn't\nexist until 1972!  Given it clearly wouldn't be hard to allow users to\nselect the epoch in these archives then why not do so?\n\nI have seen devs have issues with stuff like this in the past.\nUnpacking an archive on one machine showing a different date than one\nanother, or other weird artifacts. Mac used to use a different 0 epoch\nthan windows and linux as I recall, etc etc.  I dont remember the gory\ndetails, but i have definitely seen people gnash their teeth over\nthese kind of decisions before. Why not side-step that if you can and\nlet people choose their own defaults?\n\nJust my $0.02.\n\ncheers,\nYves\n\n-- \nperl -Mre=debug -e \"/just|another|perl|hacker/\"\n"},{"id":"472298","messageId":"91a73f5d-ca3e-6cb0-4ba3-38d703074ee6@web.de","threadId":"59258","inReplyTo":"Y+6G9n6cWRT9EKyl@google.com","subject":"[PATCH] archive: add --mtime","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2023-02-18T08:36:23Z","receivedAt":"2023-02-18T08:36:44Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Allow users to specify the modification time of archive entries.  The\nnew option --mtime uses approxidate() to parse a time specification and\noverrides the default of using the current time for trees and the commit\ntime for tags and commits.  It can be used to create a reproducible\narchive for a tree, or to use a specific mtime without creating a commit\nwith GIT_COMMITTER_DATE set.\n\nThis implementation doesn't support the negated form of the new option,\ni.e. --no-mtime is not accepted.  It is not possible to have no mtime at\nall.  We could use the Unix epoch or revert to the default behavior, but\nsince negation is not necessary for the intended use it's left undecided\nfor now.\n\nRequested-by: Raul E Rangel <rrangel@chromium.org>\nSuggested-by: demerphq <demerphq@gmail.com>\nSigned-off-by: René Scharfe <l.s.r@web.de>\n---\n Documentation/git-archive.txt |  5 +++++\n archive.c                     |  7 +++++++\n archive.h                     |  1 +\n t/t5000-tar-tree.sh           | 19 +++++++++++++++++++\n 4 files changed, 32 insertions(+)\n\ndiff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt\nindex 60c040988b..6bab201d37 100644\n--- a/Documentation/git-archive.txt\n+++ b/Documentation/git-archive.txt\n@@ -86,6 +86,11 @@ cases, write an untracked file and use `--add-file` instead.\n \tLook for attributes in .gitattributes files in the working tree\n \tas well (see <<ATTRIBUTES>>).\n\n+--mtime=<time>::\n+\tSet modification time of archive entries.  Without this option\n+\tthe committer time is used if `<tree-ish>` is a commit or tag,\n+\tand the current time if it is a tree.\n+\n <extra>::\n \tThis can be any options that the archiver backend understands.\n \tSee next section.\ndiff --git a/archive.c b/archive.c\nindex 81ff76fce9..122860b39d 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -472,6 +472,8 @@ static void parse_treeish_arg(const char **argv,\n \t\tcommit_oid = NULL;\n \t\tarchive_time = time(NULL);\n \t}\n+\tif (ar_args->mtime_option)\n+\t\tarchive_time = approxidate(ar_args->mtime_option);\n\n \ttree = parse_tree_indirect(&oid);\n \tif (!tree)\n@@ -586,6 +588,7 @@ static int parse_archive_args(int argc, const char **argv,\n \tconst char *remote = NULL;\n \tconst char *exec = NULL;\n \tconst char *output = NULL;\n+\tconst char *mtime_option = NULL;\n \tint compression_level = -1;\n \tint verbose = 0;\n \tint i;\n@@ -607,6 +610,9 @@ static int parse_archive_args(int argc, const char **argv,\n \t\tOPT_BOOL(0, \"worktree-attributes\", &worktree_attributes,\n \t\t\tN_(\"read .gitattributes in working directory\")),\n \t\tOPT__VERBOSE(&verbose, N_(\"report archived files on stderr\")),\n+\t\t{ OPTION_STRING, 0, \"mtime\", &mtime_option, N_(\"time\"),\n+\t\t  N_(\"set modification time of archive entries\"),\n+\t\t  PARSE_OPT_NONEG },\n \t\tOPT_NUMBER_CALLBACK(&compression_level,\n \t\t\tN_(\"set compression level\"), number_callback),\n \t\tOPT_GROUP(\"\"),\n@@ -668,6 +674,7 @@ static int parse_archive_args(int argc, const char **argv,\n \targs->base = base;\n \targs->baselen = strlen(base);\n \targs->worktree_attributes = worktree_attributes;\n+\targs->mtime_option = mtime_option;\n\n \treturn argc;\n }\ndiff --git a/archive.h b/archive.h\nindex 08bed3ed3a..7178e2a9a2 100644\n--- a/archive.h\n+++ b/archive.h\n@@ -16,6 +16,7 @@ struct archiver_args {\n \tstruct tree *tree;\n \tconst struct object_id *commit_oid;\n \tconst struct commit *commit;\n+\tconst char *mtime_option;\n \ttimestamp_t time;\n \tstruct pathspec pathspec;\n \tunsigned int verbose : 1;\ndiff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh\nindex eb3214bc17..918a2fc7c6 100755\n--- a/t/t5000-tar-tree.sh\n+++ b/t/t5000-tar-tree.sh\n@@ -105,6 +105,18 @@ check_added() {\n \t'\n }\n\n+check_mtime() {\n+\tdir=$1\n+\tpath_in_archive=$2\n+\tmtime=$3\n+\n+\ttest_expect_success \" validate mtime of $path_in_archive\" '\n+\t\ttest-tool chmtime --get $dir/$path_in_archive >actual.mtime &&\n+\t\techo $mtime >expect.mtime &&\n+\t\ttest_cmp expect.mtime actual.mtime\n+\t'\n+}\n+\n test_expect_success 'setup' '\n \ttest_oid_cache <<-EOF\n \tobj sha1:19f9c8273ec45a8938e6999cb59b3ff66739902a\n@@ -174,6 +186,13 @@ test_expect_success 'git archive' '\n\n check_tar b\n\n+test_expect_success 'git archive --mtime' '\n+\tgit archive --mtime=2002-02-02T02:02:02-0200 HEAD >with_mtime.tar\n+'\n+\n+check_tar with_mtime\n+check_mtime with_mtime a/a 1012622522\n+\n test_expect_success 'git archive --prefix=prefix/' '\n \tgit archive --prefix=prefix/ HEAD >with_prefix.tar\n '\n--\n2.39.2\n"},{"id":"472304","messageId":"Y/EFfxe0GGqnipvL@tapette.crustytoothpaste.net","threadId":"59258","inReplyTo":"CANgJU+VaF7-SJgGPqYGEV5VcJd_nTt2SMOQ5u9mNZ_wsArKT6g@mail.gmail.com","subject":"Re: Feature request: Add --mtime option to git archive","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2023-02-18T17:08:28Z","receivedAt":"2023-02-18T17:08:33Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2023-02-18 at 03:04:12, demerphq wrote:\n> I could understand this position if letting the user set the --mtime\n> implied some harm that must be mitigated, but it seems like an odd\n> choice if there is none.  Especially given it would also future proof\n> git against people coming up with a good reason not to use the 0 epoch\n> in the future that you haven't thought of right now. It is not like\n> epoch's and unix time have a totally uncontroversial and stable\n> history. 0 has meant multiple dates over time, and the current\n> definition of 1 Jan 1970, 00:00:00 UTC is problematic as UTC didn't\n> exist until 1972!  Given it clearly wouldn't be hard to allow users to\n> select the epoch in these archives then why not do so?\n\nIf folks want such an option, they're welcome to send a patch to do\nthat.  My approach is providing a stable tar format that doesn't change,\nand for people who want to use that format, it has fixed timestamps for\ntrees (so it's completely rigid).  If people want to use the default\nformat with an arbitrary timestamp, that's fine, and we can support\nthat, but we won't guarantee that that format won't change its\nserialization in the future.\n\n> I have seen devs have issues with stuff like this in the past.\n> Unpacking an archive on one machine showing a different date than one\n> another, or other weird artifacts. Mac used to use a different 0 epoch\n> than windows and linux as I recall, etc etc.  I dont remember the gory\n> details, but i have definitely seen people gnash their teeth over\n> these kind of decisions before. Why not side-step that if you can and\n> let people choose their own defaults?\n\nThe ustar format is defined by POSIX and uses the Unix epoch, just like\nthe zip format has its own epoch.  If you're processing a tar archive,\nyou need to use the Unix epoch.\n-- \nbrian m. carlson (he/him or they/them)\nToronto, Ontario, CA\n"},{"id":"472306","messageId":"xmqqilfykhsf.fsf@gitster.g","threadId":"59258","inReplyTo":"91a73f5d-ca3e-6cb0-4ba3-38d703074ee6@web.de","subject":"Re: [PATCH] archive: add --mtime","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-02-18T17:25:04Z","receivedAt":"2023-02-18T17:25:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n> +--mtime=<time>::\n> +\tSet modification time of archive entries.  Without this option\n> +\tthe committer time is used if `<tree-ish>` is a commit or tag,\n> +\tand the current time if it is a tree.\n> +\n>  <extra>::\n>  \tThis can be any options that the archiver backend understands.\n>  \tSee next section.\n> diff --git a/archive.c b/archive.c\n> index 81ff76fce9..122860b39d 100644\n> --- a/archive.c\n> +++ b/archive.c\n> @@ -472,6 +472,8 @@ static void parse_treeish_arg(const char **argv,\n>  \t\tcommit_oid = NULL;\n>  \t\tarchive_time = time(NULL);\n>  \t}\n> +\tif (ar_args->mtime_option)\n> +\t\tarchive_time = approxidate(ar_args->mtime_option);\n\nThis is the solution with least damage, letting the existing code to\nset archive_time and then discard the result and overwrite with the\ncommand line option.\n\nI wonder if we want to use approxidate_careful() to deal with bogus\ninput?  The code is perfectly serviceable without it (users who feed\nbogus input deserve what they get), but some folks might prefer to\nbe \"nicer\" than necessary ;-)\n\nOther than that, looks very good.  Thanks.\n"},{"id":"472314","messageId":"57b6643a-b9ff-3ea4-d60d-1a434d9ea75e@web.de","threadId":"59258","inReplyTo":"xmqqilfykhsf.fsf@gitster.g","subject":"Re: [PATCH] archive: add --mtime","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2023-02-19T10:44:38Z","receivedAt":"2023-02-19T10:45:15Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 18.02.23 um 18:25 schrieb Junio C Hamano:\n> René Scharfe <l.s.r@web.de> writes:\n>\n>> +--mtime=<time>::\n>> +\tSet modification time of archive entries.  Without this option\n>> +\tthe committer time is used if `<tree-ish>` is a commit or tag,\n>> +\tand the current time if it is a tree.\n>> +\n>>  <extra>::\n>>  \tThis can be any options that the archiver backend understands.\n>>  \tSee next section.\n>> diff --git a/archive.c b/archive.c\n>> index 81ff76fce9..122860b39d 100644\n>> --- a/archive.c\n>> +++ b/archive.c\n>> @@ -472,6 +472,8 @@ static void parse_treeish_arg(const char **argv,\n>>  \t\tcommit_oid = NULL;\n>>  \t\tarchive_time = time(NULL);\n>>  \t}\n>> +\tif (ar_args->mtime_option)\n>> +\t\tarchive_time = approxidate(ar_args->mtime_option);\n>\n> This is the solution with least damage, letting the existing code to\n> set archive_time and then discard the result and overwrite with the\n> command line option.\n\nI actually like Peff's solution more, because it's short and solves the\nspecific problem of non-deterministic timestamps for tree archives.  The\ndownside of spreading ancient timestamps seems only cosmetic to me.  It\nwould be ideal if there was a way to specify a NULL timestamp or none at\nall.  The --mtime option on the other hand mimics GNU tar, so it is more\nfamiliar and proven, though.\n\n> I wonder if we want to use approxidate_careful() to deal with bogus\n> input?  The code is perfectly serviceable without it (users who feed\n> bogus input deserve what they get), but some folks might prefer to\n> be \"nicer\" than necessary ;-)\n\nIt isn't all that careful, but you're right that we should do what we\ncan.  Like this on top?  The message string is borrowed from commit's\nhandling of --date.\n\n---\n archive.c | 11 ++++++++++-\n 1 file changed, 10 insertions(+), 1 deletion(-)\n\ndiff --git a/archive.c b/archive.c\nindex 122860b39d..871d80ee79 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -438,6 +438,15 @@ static void parse_pathspec_arg(const char **pathspec,\n \t}\n }\n\n+static timestamp_t approxidate_or_die(const char *date_str)\n+{\n+\tint errors = 0;\n+\ttimestamp_t date = approxidate_careful(date_str, &errors);\n+\tif (errors)\n+\t\tdie(_(\"invalid date format: %s\"), date_str);\n+\treturn date;\n+}\n+\n static void parse_treeish_arg(const char **argv,\n \t\tstruct archiver_args *ar_args, const char *prefix,\n \t\tint remote)\n@@ -473,7 +482,7 @@ static void parse_treeish_arg(const char **argv,\n \t\tarchive_time = time(NULL);\n \t}\n \tif (ar_args->mtime_option)\n-\t\tarchive_time = approxidate(ar_args->mtime_option);\n+\t\tarchive_time = approxidate_or_die(ar_args->mtime_option);\n\n \ttree = parse_tree_indirect(&oid);\n \tif (!tree)\n--\n2.39.2\n"},{"id":"472362","messageId":"xmqqlekrh94h.fsf@gitster.g","threadId":"59258","inReplyTo":"57b6643a-b9ff-3ea4-d60d-1a434d9ea75e@web.de","subject":"Re: [PATCH] archive: add --mtime","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-02-21T05:37:18Z","receivedAt":"2023-02-21T05:37:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n>> This is the solution with least damage, letting the existing code to\n>> set archive_time and then discard the result and overwrite with the\n>> command line option.\n>\n> I actually like Peff's solution more, because it's short and solves the\n> specific problem of non-deterministic timestamps for tree archives.\n\nYes.  That would be my preference as well.  Without any UI to\neducate users about.\n\n> The --mtime option on the other hand mimics GNU tar, so it is more\n> familiar and proven, though.\n\nAnd that gives us the second best option ;-)\n\n> It isn't all that careful, but you're right that we should do what we\n> can.  Like this on top?  The message string is borrowed from commit's\n> handling of --date.\n\nYeah, something like that, I would think.\n\nThanks.\n\n> ---\n>  archive.c | 11 ++++++++++-\n>  1 file changed, 10 insertions(+), 1 deletion(-)\n>\n> diff --git a/archive.c b/archive.c\n> index 122860b39d..871d80ee79 100644\n> --- a/archive.c\n> +++ b/archive.c\n> @@ -438,6 +438,15 @@ static void parse_pathspec_arg(const char **pathspec,\n>  \t}\n>  }\n>\n> +static timestamp_t approxidate_or_die(const char *date_str)\n> +{\n> +\tint errors = 0;\n> +\ttimestamp_t date = approxidate_careful(date_str, &errors);\n> +\tif (errors)\n> +\t\tdie(_(\"invalid date format: %s\"), date_str);\n> +\treturn date;\n> +}\n> +\n>  static void parse_treeish_arg(const char **argv,\n>  \t\tstruct archiver_args *ar_args, const char *prefix,\n>  \t\tint remote)\n> @@ -473,7 +482,7 @@ static void parse_treeish_arg(const char **argv,\n>  \t\tarchive_time = time(NULL);\n>  \t}\n>  \tif (ar_args->mtime_option)\n> -\t\tarchive_time = approxidate(ar_args->mtime_option);\n> +\t\tarchive_time = approxidate_or_die(ar_args->mtime_option);\n>\n>  \ttree = parse_tree_indirect(&oid);\n>  \tif (!tree)\n> --\n> 2.39.2\n"},{"id":"472455","messageId":"Y/ZyNNMFmafz8YvE@coredump.intra.peff.net","threadId":"59258","inReplyTo":"xmqqlekrh94h.fsf@gitster.g","subject":"Re: [PATCH] archive: add --mtime","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2023-02-22T19:51:16Z","receivedAt":"2023-02-22T19:52:01Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 20, 2023 at 09:37:18PM -0800, Junio C Hamano wrote:\n\n> René Scharfe <l.s.r@web.de> writes:\n> \n> >> This is the solution with least damage, letting the existing code to\n> >> set archive_time and then discard the result and overwrite with the\n> >> command line option.\n> >\n> > I actually like Peff's solution more, because it's short and solves the\n> > specific problem of non-deterministic timestamps for tree archives.\n> \n> Yes.  That would be my preference as well.  Without any UI to\n> educate users about.\n\nMy biggest concern with the patch I showed is that it gives no escape\nhatch if people don't like the change. Like I said earlier, I don't\nthink anybody has grounds to complain about the byte-for-byte output\nhash changing, as it would be changing once per second. But they may\ncomplain about the cosmetic problem.\n\nOne \"escape hatch\" is to tell them to use \"tar -m\", but I don't know how\nfriendly that is. The more obvious one at the Git level is to have\n\"--current-mtime\" or something to get the old behavior. But at that\npoint, you may as well support \"--mtime=now\", which is the same amount\nof work, and much more flexible.\n\n-Peff\n"},{"id":"472465","messageId":"xmqqsfexb7y3.fsf@gitster.g","threadId":"59258","inReplyTo":"Y/ZyNNMFmafz8YvE@coredump.intra.peff.net","subject":"Re: [PATCH] archive: add --mtime","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-02-22T23:23:48Z","receivedAt":"2023-02-22T23:24:12Z","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> My biggest concern with the patch I showed is that it gives no escape\n> hatch if people don't like the change.\n\nYeah.\n\n> Like I said earlier, I don't\n> think anybody has grounds to complain about the byte-for-byte output\n> hash changing, as it would be changing once per second. But they may\n> complain about the cosmetic problem.\n\nYeah, they may complain \"it no longer is possible when I took the\narchive out of a tree\".  To be honest, I didn't think of that line\nof complaints before.\n\n> The more obvious one at the Git level is to have\n> \"--current-mtime\" or something to get the old behavior. But at that\n> point, you may as well support \"--mtime=now\", which is the same amount\n> of work, and much more flexible.\n\nYup.  Let's merge it down to 'next' then.\n\nThanks.\n"}]}