{"thread":{"id":"37621","subject":"Passing tar(1) options via git-archive(1)","startedAt":"2014-09-23T18:57:19Z","lastAt":"2014-09-24T05:46:25Z","messageCount":5,"participants":["Daniel Brockman","Thomas Braun","brian m. carlson","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"249803","messageId":"87bnq6jhbk.fsf@brockman.se","threadId":"37621","inReplyTo":null,"subject":"Passing tar(1) options via git-archive(1)","fromName":"Daniel Brockman","fromEmail":"daniel@brockman.se","sentAt":"2014-09-23T18:57:19Z","receivedAt":"2014-09-23T18:57:19Z","isPatch":false,"sender":{"key":"daniel@brockman.se","avatar":null},"body":"Some background from the git-archive(1) man page:\n\n    git-archive behaves differently when given a tree ID versus when\n    given a commit ID or tag ID.  In the first case the current time is\n    used as the modification time of each file in the archive.  In the\n    latter case the commit time as recorded in the referenced commit\n    object is used instead.\n\nWould it make sense to add an --mtime option to git-archive(1) to enable\nexplicitly setting the mtime for all files in the archive?  It could\njust pass through to the tar(1) --mtime option.\n\nMy use case is `git archive HEAD | docker build -`, in which the Docker\ncache is prevented from working because the mtime keeps getting bumped\non all files.  I would like to have the mtime always be the same.\n\nSee, e.g., <https://github.com/deis/deis/issues/1334>.\n\nOtherwise, how about a generic way to pass options to tar(1)?\n\nThanks,\nDaniel\n"},{"id":"249818","messageId":"5421EAE4.30704@virtuell-zuhause.de","threadId":"37621","inReplyTo":"87bnq6jhbk.fsf@brockman.se","subject":"Re: Passing tar(1) options via git-archive(1)","fromName":"Thomas Braun","fromEmail":"thomas.braun@virtuell-zuhause.de","sentAt":"2014-09-23T21:49:24Z","receivedAt":"2014-09-23T21:49:24Z","isPatch":false,"sender":{"key":"thomas.braun@virtuell-zuhause.de","avatar":"https://avatars.githubusercontent.com/u/1185677?v=4"},"body":"Am 23.09.2014 um 20:57 schrieb Daniel Brockman:\n> Some background from the git-archive(1) man page:\n> \n>     git-archive behaves differently when given a tree ID versus when\n>     given a commit ID or tag ID.  In the first case the current time is\n>     used as the modification time of each file in the archive.  In the\n>     latter case the commit time as recorded in the referenced commit\n>     object is used instead.\n> \n> Would it make sense to add an --mtime option to git-archive(1) to enable\n> explicitly setting the mtime for all files in the archive?  It could\n> just pass through to the tar(1) --mtime option.\n> \n> My use case is `git archive HEAD | docker build -`, in which the Docker\n> cache is prevented from working because the mtime keeps getting bumped\n> on all files.  I would like to have the mtime always be the same.\n> \n> See, e.g., <https://github.com/deis/deis/issues/1334>.\n> \n> Otherwise, how about a generic way to pass options to tar(1)?\n\nActually I wanted to just hint to TAR_OPTIONS\nas in\nTAR_OPTIONS=\"--mtime 2014-09-23\\ 00:00\" git archive -o ausg.tar HEAD\nbut that does not work here (on windows).\n\nThe questions is should it be supported?\n"},{"id":"249820","messageId":"20140924001522.GB6920@vauxhall.crustytoothpaste.net","threadId":"37621","inReplyTo":"5421EAE4.30704@virtuell-zuhause.de","subject":"Re: Passing tar(1) options via git-archive(1)","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2014-09-24T00:15:22Z","receivedAt":"2014-09-24T00:15:22Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Tue, Sep 23, 2014 at 11:49:24PM +0200, Thomas Braun wrote:\n> Am 23.09.2014 um 20:57 schrieb Daniel Brockman:\n> > Would it make sense to add an --mtime option to git-archive(1) to enable\n> > explicitly setting the mtime for all files in the archive?  It could\n> > just pass through to the tar(1) --mtime option.\n> > \n> > My use case is `git archive HEAD | docker build -`, in which the Docker\n> > cache is prevented from working because the mtime keeps getting bumped\n> > on all files.  I would like to have the mtime always be the same.\n> > \n> > See, e.g., <https://github.com/deis/deis/issues/1334>.\n> > \n> > Otherwise, how about a generic way to pass options to tar(1)?\n> \n> Actually I wanted to just hint to TAR_OPTIONS\n> as in\n> TAR_OPTIONS=\"--mtime 2014-09-23\\ 00:00\" git archive -o ausg.tar HEAD\n> but that does not work here (on windows).\n\nGit does not invoke tar(1).  It has its own tar (actually, pax)\nimplementation, so any options would have to be implemented in Git.\nWe'd probably want to make such a change effective in the zip format as\nwell.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"249821","messageId":"87k34tizb5.fsf@brockman.se","threadId":"37621","inReplyTo":"20140924001522.GB6920@vauxhall.crustytoothpaste.net","subject":"Re: Passing tar(1) options via git-archive(1)","fromName":"Daniel Brockman","fromEmail":"daniel@brockman.se","sentAt":"2014-09-24T01:26:22Z","receivedAt":"2014-09-24T01:26:22Z","isPatch":false,"sender":{"key":"daniel@brockman.se","avatar":null},"body":"\"brian m. carlson\" <sandals@crustytoothpaste.net> writes:\n\n> Git does not invoke tar(1).  It has its own tar (actually, pax)\n> implementation, so any options would have to be implemented in Git.\n> We'd probably want to make such a change effective in the zip format\n> as well.\n\nAh, I see...\n\nWell, I guess in the meantime I'll just do this:\n\n   git commit -m dummy --allow-empty --date=1970-01-01T00:00:00Z\n   git archive HEAD | docker build -\n   git reset HEAD~\n\nOr even (slightly more atomically) this:\n\n   git archive HEAD | { tmpdir=`mktemp -d` && tar x -C\"$tmpdir\" &&\n     tar c -C\"$tmpdir\" --mtime=1970-01-01T00:00:00Z . &&\n     rm -r \"$tmpdir\"; } | docker build -\n"},{"id":"249822","messageId":"20140924054624.GB24141@peff.net","threadId":"37621","inReplyTo":"87k34tizb5.fsf@brockman.se","subject":"Re: Passing tar(1) options via git-archive(1)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-09-24T05:46:25Z","receivedAt":"2014-09-24T05:46:25Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Sep 24, 2014 at 03:26:22AM +0200, Daniel Brockman wrote:\n\n> \"brian m. carlson\" <sandals@crustytoothpaste.net> writes:\n> \n> > Git does not invoke tar(1).  It has its own tar (actually, pax)\n> > implementation, so any options would have to be implemented in Git.\n> > We'd probably want to make such a change effective in the zip format\n> > as well.\n> \n> Ah, I see...\n> \n> Well, I guess in the meantime I'll just do this:\n> \n>    git commit -m dummy --allow-empty --date=1970-01-01T00:00:00Z\n>    git archive HEAD | docker build -\n>    git reset HEAD~\n\nI don't think that will work. The `--date` parameter sets the author\ndate, but archive uses the committer date. You'd have to set\nGIT_COMMITTER_DATE in the environment to override that.\n\nAlso, you can avoid writing to the HEAD ref entirely by using the\ncommit-tree plumbing. Like:\n\n  commit=$(\n    GIT_COMMITTER_DATE=1970-01-01T00:00:00Z \\\n    git commit-tree HEAD^{tree} </dev/null\n  )\n  git archive $commit | ...\n\nHowever, the --mtime patch you are asking for is really not that big:\n\ndiff --git a/archive.c b/archive.c\nindex 952a659..9396fca 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -299,7 +299,8 @@ static void parse_treeish_arg(const char **argv,\n \tar_args->tree = tree;\n \tar_args->commit_sha1 = commit_sha1;\n \tar_args->commit = commit;\n-\tar_args->time = archive_time;\n+\tif (!ar_args->time)\n+\t\tar_args->time = archive_time;\n }\n \n #define OPT__COMPR(s, v, h, p) \\\n@@ -323,6 +324,7 @@ static int parse_archive_args(int argc, const char **argv,\n \tint i;\n \tint list = 0;\n \tint worktree_attributes = 0;\n+\tunsigned long mtime = 0;\n \tstruct option opts[] = {\n \t\tOPT_GROUP(\"\"),\n \t\tOPT_STRING(0, \"format\", &format, N_(\"fmt\"), N_(\"archive format\")),\n@@ -332,6 +334,7 @@ static int parse_archive_args(int argc, const char **argv,\n \t\t\tN_(\"write the archive to this file\")),\n \t\tOPT_BOOL(0, \"worktree-attributes\", &worktree_attributes,\n \t\t\tN_(\"read .gitattributes in working directory\")),\n+\t\tOPT_DATE(0, \"mtime\", &mtime, N_(\"mtime of files in archive\")),\n \t\tOPT__VERBOSE(&verbose, N_(\"report archived files on stderr\")),\n \t\tOPT__COMPR('0', &compression_level, N_(\"store only\"), 0),\n \t\tOPT__COMPR('1', &compression_level, N_(\"compress faster\"), 1),\n@@ -398,6 +401,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->time = mtime;\n \n \treturn argc;\n }\n\nwhich allows:\n\n  git archive --mtime='yesterday at 3pm' HEAD\n\nFor inclusion in git, it would need someone to wrap it up with a commit\nmessage, and add a basic test (see the existing mtime test in\nt/t5000-tar-tree) and documentation in Documentation/git-archive.txt.\nThat someone could be you. :)\n\n-Peff\n"}]}