{"thread":{"id":"8221","subject":"[PATCH] git-archive: recursive prefix directory creation","startedAt":"2007-05-19T11:37:13Z","lastAt":"2007-05-20T10:51:11Z","messageCount":5,"participants":["René Scharfe","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"42614","messageId":"464EE169.30306@lsrfire.ath.cx","threadId":"8221","inReplyTo":null,"subject":"[PATCH] git-archive: recursive prefix directory creation","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2007-05-19T11:37:13Z","receivedAt":"2007-05-19T11:37:13Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Currently git-archive only adds a single directory entry for prefixes,\ne.g. for --prefix=a/b/c/ only the directory a/b/c/ would be added to\nthe archive, not a/ nor a/b/.  While tar and unzip don't seem to have\na problem handling these missing entries, their omission was not\nintended.\n\nThis patch replaces the prefix path creation code in git-archive with\ncalls to a new path walker similar to read_tree_recursive, named\ndescend_leading_dirs.  It calls a read_tree_fn_t function for each\nleading directory while descending deeper into the path (e.g. first\na/, then a/b/ etc.).\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n archive-tar.c |   11 ++---------\n archive-zip.c |   11 ++---------\n tree.c        |   45 +++++++++++++++++++++++++++++++++++++++++++++\n tree.h        |    5 +++++\n 4 files changed, 54 insertions(+), 18 deletions(-)\n\ndiff --git a/archive-tar.c b/archive-tar.c\nindex 33e7657..7ea396d 100644\n--- a/archive-tar.c\n+++ b/archive-tar.c\n@@ -308,15 +308,8 @@ int write_tar_archive(struct archiver_args *args)\n \tif (args->commit_sha1)\n \t\twrite_global_extended_header(args->commit_sha1);\n \n-\tif (args->base && plen > 0 && args->base[plen - 1] == '/') {\n-\t\tchar *base = xstrdup(args->base);\n-\t\tint baselen = strlen(base);\n-\n-\t\twhile (baselen > 0 && base[baselen - 1] == '/')\n-\t\t\tbase[--baselen] = '\\0';\n-\t\twrite_tar_entry(args->tree->object.sha1, \"\", 0, base, 040777, 0);\n-\t\tfree(base);\n-\t}\n+\tdescend_leading_dirs(args->tree->object.sha1, args->base, plen,\n+\t                     040777, 0, write_tar_entry);\n \tread_tree_recursive(args->tree, args->base, plen, 0,\n \t\t\t    args->pathspec, write_tar_entry);\n \twrite_trailer();\ndiff --git a/archive-zip.c b/archive-zip.c\nindex 3cbf6bb..2fc22ff 100644\n--- a/archive-zip.c\n+++ b/archive-zip.c\n@@ -317,15 +317,8 @@ int write_zip_archive(struct archiver_args *args)\n \tzip_dir_size = ZIP_DIRECTORY_MIN_SIZE;\n \tverbose = args->verbose;\n \n-\tif (args->base && plen > 0 && args->base[plen - 1] == '/') {\n-\t\tchar *base = xstrdup(args->base);\n-\t\tint baselen = strlen(base);\n-\n-\t\twhile (baselen > 0 && base[baselen - 1] == '/')\n-\t\t\tbase[--baselen] = '\\0';\n-\t\twrite_zip_entry(args->tree->object.sha1, \"\", 0, base, 040777, 0);\n-\t\tfree(base);\n-\t}\n+\tdescend_leading_dirs(args->tree->object.sha1, args->base, plen,\n+\t                     040777, 0, write_zip_entry);\n \tread_tree_recursive(args->tree, args->base, plen, 0,\n \t\t\t    args->pathspec, write_zip_entry);\n \twrite_zip_trailer(args->commit_sha1);\ndiff --git a/tree.c b/tree.c\nindex e4a39aa..5cd1f90 100644\n--- a/tree.c\n+++ b/tree.c\n@@ -231,3 +231,48 @@ struct tree *parse_tree_indirect(const unsigned char *sha1)\n \t\t\tparse_object(obj->sha1);\n \t} while (1);\n }\n+\n+int descend_leading_dirs(const unsigned char *sha1,\n+                         const char *path, size_t pathlen,\n+                         unsigned int mode, int stage, read_tree_fn_t fn)\n+{\n+\tint err;\n+\tsize_t baselen;\n+\n+\tif (!path)\n+\t\treturn 0;\n+\n+\t/* Discard file name part. */\n+\twhile (pathlen > 0 && path[pathlen - 1] != '/')\n+\t\tpathlen--;\n+\twhile (pathlen > 0 && path[pathlen - 1] == '/')\n+\t\tpathlen--;\n+\tif (pathlen == 0)\n+\t\treturn 0;\n+\n+\t/* Now separate base and current directory name. */\n+\tbaselen = pathlen;\n+\twhile (baselen > 0 && path[baselen - 1] != '/')\n+\t\tbaselen--;\n+\n+\terr = descend_leading_dirs(null_sha1, path, baselen, mode, stage, fn);\n+\n+\tif (!err) {\n+\t\t/* We need a NUL-terminated version of the directory name. */\n+\t\tchar *dirname = xstrndup(path + baselen, pathlen - baselen);\n+\t\tswitch (fn(sha1, path, baselen, dirname, mode, stage)) {\n+\t\tcase 0:\n+\t\t\terr = 1;\n+\t\t\tbreak;\n+\t\tcase READ_TREE_RECURSIVE:\n+\t\t\terr = 0;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\terr = -1;\n+\t\t\tbreak;\n+\t\t}\n+\t\tfree(dirname);\n+\t}\n+\n+\treturn err;\n+}\ndiff --git a/tree.h b/tree.h\nindex dd25c53..6b0f5d9 100644\n--- a/tree.h\n+++ b/tree.h\n@@ -30,4 +30,9 @@ extern int read_tree_recursive(struct tree *tree,\n \n extern int read_tree(struct tree *tree, int stage, const char **paths);\n \n+extern int descend_leading_dirs(const unsigned char *sha1,\n+                                const char *path, size_t pathlen,\n+                                unsigned int mode, int stage,\n+                                read_tree_fn_t fn);\n+\n #endif /* TREE_H */\n"},{"id":"42638","messageId":"7vbqggy8ym.fsf@assigned-by-dhcp.cox.net","threadId":"8221","inReplyTo":"464EE169.30306@lsrfire.ath.cx","subject":"Re: [PATCH] git-archive: recursive prefix directory creation","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-19T18:17:05Z","receivedAt":"2007-05-19T18:17:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n\n> Currently git-archive only adds a single directory entry for prefixes,\n> e.g. for --prefix=a/b/c/ only the directory a/b/c/ would be added to\n> the archive, not a/ nor a/b/.  While tar and unzip don't seem to have\n> a problem handling these missing entries, their omission was not\n> intended.\n\nUntil we start tracking directories (we briefly discussed, and I\nthink I agree with Linus that it should not be too painful), I'd\nrather keep the current behaviour which I feel is more\nconsistent with what we really are doing.\n"},{"id":"42642","messageId":"464F568B.9030308@lsrfire.ath.cx","threadId":"8221","inReplyTo":"7vbqggy8ym.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-archive: recursive prefix directory creation","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2007-05-19T19:56:59Z","receivedAt":"2007-05-19T19:56:59Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Junio C Hamano schrieb:\n> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n> \n>> Currently git-archive only adds a single directory entry for prefixes,\n>> e.g. for --prefix=a/b/c/ only the directory a/b/c/ would be added to\n>> the archive, not a/ nor a/b/.  While tar and unzip don't seem to have\n>> a problem handling these missing entries, their omission was not\n>> intended.\n> \n> Until we start tracking directories (we briefly discussed, and I\n> think I agree with Linus that it should not be too painful), I'd\n> rather keep the current behaviour which I feel is more\n> consistent with what we really are doing.\n\nHmm, fair enough.  I started out with a simple cleanup and then I guess\nwent a bit overboard with that overblown path walker. :-]\n\nRené\n"},{"id":"42646","messageId":"7vtzu8va12.fsf@assigned-by-dhcp.cox.net","threadId":"8221","inReplyTo":"464F568B.9030308@lsrfire.ath.cx","subject":"Re: [PATCH] git-archive: recursive prefix directory creation","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-19T20:22:17Z","receivedAt":"2007-05-19T20:22:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n\n> Junio C Hamano schrieb:\n>> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n>> \n>>> Currently git-archive only adds a single directory entry for prefixes,\n>>> e.g. for --prefix=a/b/c/ only the directory a/b/c/ would be added to\n>>> the archive, not a/ nor a/b/.  While tar and unzip don't seem to have\n>>> a problem handling these missing entries, their omission was not\n>>> intended.\n>> \n>> Until we start tracking directories (we briefly discussed, and I\n>> think I agree with Linus that it should not be too painful), I'd\n>> rather keep the current behaviour which I feel is more\n>> consistent with what we really are doing.\n>\n> Hmm, fair enough.  I started out with a simple cleanup and then I guess\n> went a bit overboard with that overblown path walker. :-]\n\nWell, I take that back -- I did not realize you were primarily\ntalking about the LEADING part of the path.\n"},{"id":"42698","messageId":"4650281F.2030301@lsrfire.ath.cx","threadId":"8221","inReplyTo":"7vtzu8va12.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-archive: recursive prefix directory creation","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2007-05-20T10:51:11Z","receivedAt":"2007-05-20T10:51:11Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Junio C Hamano schrieb:\n> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n> \n>> Junio C Hamano schrieb:\n>>> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n>>> \n>>>> Currently git-archive only adds a single directory entry for\n>>>> prefixes, e.g. for --prefix=a/b/c/ only the directory a/b/c/\n>>>> would be added to the archive, not a/ nor a/b/.  While tar and\n>>>> unzip don't seem to have a problem handling these missing\n>>>> entries, their omission was not intended.\n>>> Until we start tracking directories (we briefly discussed, and I \n>>> think I agree with Linus that it should not be too painful), I'd \n>>> rather keep the current behaviour which I feel is more consistent\n>>> with what we really are doing.\n>> Hmm, fair enough.  I started out with a simple cleanup and then I\n>> guess went a bit overboard with that overblown path walker. :-]\n> \n> Well, I take that back -- I did not realize you were primarily \n> talking about the LEADING part of the path.\n\nIn any case, please don't apply this patch.  I checked again, and it\nturns out both tar and zip don't always add leading directories to\narchives.  So my \"cleanup\" only adds bloat.  I'll try to find another\nway to beautify the code.\n\nRené\n"}]}