{"thread":{"id":"14671","subject":"[PATCH 1/6] archive: add write_archive()","startedAt":"2008-07-25T10:41:21Z","lastAt":"2008-07-26T07:09:24Z","messageCount":10,"participants":["Rene Scharfe","René Scharfe","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"84859","messageId":"1216982486-5887-1-git-send-email-rene.scharfe@lsrfire.ath.cx","threadId":"14671","inReplyTo":null,"subject":"[PATCH 1/6] archive: add write_archive()","fromName":"Rene Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-07-25T10:41:21Z","receivedAt":"2008-07-25T10:41:21Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Both archive and upload-archive have to parse command line arguments and\nthen call the archiver specific write function.  Move the duplicate code\nto a new function, write_archive().\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n archive.c                |   18 ++++++++++++++++++\n archive.h                |    1 +\n builtin-archive.c        |   13 +------------\n builtin-upload-archive.c |   10 +---------\n 4 files changed, 21 insertions(+), 21 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex b8b45ba..75eb257 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -155,3 +155,21 @@ int write_archive_entries(struct archiver_args *args,\n \t\terr = 0;\n \treturn err;\n }\n+\n+int write_archive(int argc, const char **argv, const char *prefix,\n+\t\tint setup_prefix)\n+{\n+\tconst struct archiver *ar = NULL;\n+\tstruct archiver_args args;\n+\tint tree_idx;\n+\n+\ttree_idx = parse_archive_args(argc, argv, &ar, &args);\n+\tif (setup_prefix && prefix == NULL)\n+\t\tprefix = setup_git_directory();\n+\n+\targv += tree_idx;\n+\tparse_treeish_arg(argv, &args, prefix);\n+\tparse_pathspec_arg(argv + 1, &args);\n+\n+\treturn ar->write_archive(&args);\n+}\ndiff --git a/archive.h b/archive.h\nindex 4a02371..6b5fe5a 100644\n--- a/archive.h\n+++ b/archive.h\n@@ -41,5 +41,6 @@ extern int write_tar_archive(struct archiver_args *);\n extern int write_zip_archive(struct archiver_args *);\n \n extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);\n+extern int write_archive(int argc, const char **argv, const char *prefix, int setup_prefix);\n \n #endif\t/* ARCHIVE_H */\ndiff --git a/builtin-archive.c b/builtin-archive.c\nindex df97724..502b339 100644\n--- a/builtin-archive.c\n+++ b/builtin-archive.c\n@@ -232,9 +232,6 @@ static const char *extract_remote_arg(int *ac, const char **av)\n \n int cmd_archive(int argc, const char **argv, const char *prefix)\n {\n-\tconst struct archiver *ar = NULL;\n-\tstruct archiver_args args;\n-\tint tree_idx;\n \tconst char *remote = NULL;\n \n \tremote = extract_remote_arg(&argc, argv);\n@@ -243,13 +240,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix)\n \n \tsetvbuf(stderr, NULL, _IOLBF, BUFSIZ);\n \n-\ttree_idx = parse_archive_args(argc, argv, &ar, &args);\n-\tif (prefix == NULL)\n-\t\tprefix = setup_git_directory();\n-\n-\targv += tree_idx;\n-\tparse_treeish_arg(argv, &args, prefix);\n-\tparse_pathspec_arg(argv + 1, &args);\n-\n-\treturn ar->write_archive(&args);\n+\treturn write_archive(argc, argv, prefix, 1);\n }\ndiff --git a/builtin-upload-archive.c b/builtin-upload-archive.c\nindex 13a6c62..cc37b36 100644\n--- a/builtin-upload-archive.c\n+++ b/builtin-upload-archive.c\n@@ -19,12 +19,9 @@ static const char lostchild[] =\n \n static int run_upload_archive(int argc, const char **argv, const char *prefix)\n {\n-\tconst struct archiver *ar;\n-\tstruct archiver_args args;\n \tconst char *sent_argv[MAX_ARGS];\n \tconst char *arg_cmd = \"argument \";\n \tchar *p, buf[4096];\n-\tint treeish_idx;\n \tint sent_argc;\n \tint len;\n \n@@ -66,12 +63,7 @@ static int run_upload_archive(int argc, const char **argv, const char *prefix)\n \tsent_argv[sent_argc] = NULL;\n \n \t/* parse all options sent by the client */\n-\ttreeish_idx = parse_archive_args(sent_argc, sent_argv, &ar, &args);\n-\n-\tparse_treeish_arg(sent_argv + treeish_idx, &args, prefix);\n-\tparse_pathspec_arg(sent_argv + treeish_idx + 1, &args);\n-\n-\treturn ar->write_archive(&args);\n+\treturn write_archive(sent_argc, sent_argv, prefix, 0);\n }\n \n static void error_clnt(const char *fmt, ...)\n-- \n1.6.0.rc0.42.g186458\n"},{"id":"84863","messageId":"1216982486-5887-2-git-send-email-rene.scharfe@lsrfire.ath.cx","threadId":"14671","inReplyTo":"1216982486-5887-1-git-send-email-rene.scharfe@lsrfire.ath.cx","subject":"[PATCH 2/6] archive: move parameter parsing code to archive.c","fromName":"Rene Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-07-25T10:41:22Z","receivedAt":"2008-07-25T10:41:22Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"write_archive() in archive.c is the only callsite for the command line\nparsing functions located in builtin-archive.c.  Move them to the place\nwhere they are used, un-export them and make them static, as hinted at\nby Stephan.\n\nCc: Stephan Beyer <s-beyer@gmx.net>\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n archive.c         |  137 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n archive.h         |    8 ---\n builtin-archive.c |  137 -----------------------------------------------------\n 3 files changed, 137 insertions(+), 145 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 75eb257..c4662a2 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -1,8 +1,19 @@\n #include \"cache.h\"\n #include \"commit.h\"\n+#include \"tree-walk.h\"\n #include \"attr.h\"\n #include \"archive.h\"\n \n+static const char archive_usage[] = \\\n+\"git archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]\";\n+\n+#define USES_ZLIB_COMPRESSION 1\n+\n+const struct archiver archivers[] = {\n+\t{ \"tar\", write_tar_archive },\n+\t{ \"zip\", write_zip_archive, USES_ZLIB_COMPRESSION },\n+};\n+\n static void format_subst(const struct commit *commit,\n                          const char *src, size_t len,\n                          struct strbuf *buf)\n@@ -156,6 +167,132 @@ int write_archive_entries(struct archiver_args *args,\n \treturn err;\n }\n \n+static const struct archiver *lookup_archiver(const char *name)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < ARRAY_SIZE(archivers); i++) {\n+\t\tif (!strcmp(name, archivers[i].name))\n+\t\t\treturn &archivers[i];\n+\t}\n+\treturn NULL;\n+}\n+\n+static void parse_pathspec_arg(const char **pathspec,\n+\t\tstruct archiver_args *ar_args)\n+{\n+\tar_args->pathspec = get_pathspec(ar_args->base, pathspec);\n+}\n+\n+static void parse_treeish_arg(const char **argv,\n+\t\tstruct archiver_args *ar_args, const char *prefix)\n+{\n+\tconst char *name = argv[0];\n+\tconst unsigned char *commit_sha1;\n+\ttime_t archive_time;\n+\tstruct tree *tree;\n+\tconst struct commit *commit;\n+\tunsigned char sha1[20];\n+\n+\tif (get_sha1(name, sha1))\n+\t\tdie(\"Not a valid object name\");\n+\n+\tcommit = lookup_commit_reference_gently(sha1, 1);\n+\tif (commit) {\n+\t\tcommit_sha1 = commit->object.sha1;\n+\t\tarchive_time = commit->date;\n+\t} else {\n+\t\tcommit_sha1 = NULL;\n+\t\tarchive_time = time(NULL);\n+\t}\n+\n+\ttree = parse_tree_indirect(sha1);\n+\tif (tree == NULL)\n+\t\tdie(\"not a tree object\");\n+\n+\tif (prefix) {\n+\t\tunsigned char tree_sha1[20];\n+\t\tunsigned int mode;\n+\t\tint err;\n+\n+\t\terr = get_tree_entry(tree->object.sha1, prefix,\n+\t\t\t\t     tree_sha1, &mode);\n+\t\tif (err || !S_ISDIR(mode))\n+\t\t\tdie(\"current working directory is untracked\");\n+\n+\t\ttree = parse_tree_indirect(tree_sha1);\n+\t}\n+\tar_args->tree = tree;\n+\tar_args->commit_sha1 = commit_sha1;\n+\tar_args->commit = commit;\n+\tar_args->time = archive_time;\n+}\n+\n+static int parse_archive_args(int argc, const char **argv,\n+\t\tconst struct archiver **ar, struct archiver_args *args)\n+{\n+\tconst char *format = \"tar\";\n+\tconst char *base = \"\";\n+\tint compression_level = -1;\n+\tint verbose = 0;\n+\tint i;\n+\n+\tfor (i = 1; i < argc; i++) {\n+\t\tconst char *arg = argv[i];\n+\n+\t\tif (!strcmp(arg, \"--list\") || !strcmp(arg, \"-l\")) {\n+\t\t\tfor (i = 0; i < ARRAY_SIZE(archivers); i++)\n+\t\t\t\tprintf(\"%s\\n\", archivers[i].name);\n+\t\t\texit(0);\n+\t\t}\n+\t\tif (!strcmp(arg, \"--verbose\") || !strcmp(arg, \"-v\")) {\n+\t\t\tverbose = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!prefixcmp(arg, \"--format=\")) {\n+\t\t\tformat = arg + 9;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!prefixcmp(arg, \"--prefix=\")) {\n+\t\t\tbase = arg + 9;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"--\")) {\n+\t\t\ti++;\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (arg[0] == '-' && isdigit(arg[1]) && arg[2] == '\\0') {\n+\t\t\tcompression_level = arg[1] - '0';\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (arg[0] == '-')\n+\t\t\tdie(\"Unknown argument: %s\", arg);\n+\t\tbreak;\n+\t}\n+\n+\t/* We need at least one parameter -- tree-ish */\n+\tif (argc - 1 < i)\n+\t\tusage(archive_usage);\n+\t*ar = lookup_archiver(format);\n+\tif (!*ar)\n+\t\tdie(\"Unknown archive format '%s'\", format);\n+\n+\targs->compression_level = Z_DEFAULT_COMPRESSION;\n+\tif (compression_level != -1) {\n+\t\tif ((*ar)->flags & USES_ZLIB_COMPRESSION)\n+\t\t\targs->compression_level = compression_level;\n+\t\telse {\n+\t\t\tdie(\"Argument not supported for format '%s': -%d\",\n+\t\t\t\t\tformat, compression_level);\n+\t\t}\n+\t}\n+\targs->verbose = verbose;\n+\targs->base = base;\n+\targs->baselen = strlen(base);\n+\n+\treturn i;\n+}\n+\n int write_archive(int argc, const char **argv, const char *prefix,\n \t\tint setup_prefix)\n {\ndiff --git a/archive.h b/archive.h\nindex 6b5fe5a..f6ceaeb 100644\n--- a/archive.h\n+++ b/archive.h\n@@ -26,14 +26,6 @@ struct archiver {\n \tunsigned int flags;\n };\n \n-extern int parse_archive_args(int argc, const char **argv, const struct archiver **ar, struct archiver_args *args);\n-\n-extern void parse_treeish_arg(const char **treeish,\n-\t\t\t      struct archiver_args *ar_args,\n-\t\t\t      const char *prefix);\n-\n-extern void parse_pathspec_arg(const char **pathspec,\n-\t\t\t       struct archiver_args *args);\n /*\n  * Archive-format specific backends.\n  */\ndiff --git a/builtin-archive.c b/builtin-archive.c\nindex 502b339..4dd2716 100644\n--- a/builtin-archive.c\n+++ b/builtin-archive.c\n@@ -5,21 +5,9 @@\n #include \"cache.h\"\n #include \"builtin.h\"\n #include \"archive.h\"\n-#include \"commit.h\"\n-#include \"tree-walk.h\"\n #include \"pkt-line.h\"\n #include \"sideband.h\"\n \n-static const char archive_usage[] = \\\n-\"git archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]\";\n-\n-#define USES_ZLIB_COMPRESSION 1\n-\n-const struct archiver archivers[] = {\n-\t{ \"tar\", write_tar_archive },\n-\t{ \"zip\", write_zip_archive, USES_ZLIB_COMPRESSION },\n-};\n-\n static int run_remote_archiver(const char *remote, int argc,\n \t\t\t       const char **argv)\n {\n@@ -74,131 +62,6 @@ static int run_remote_archiver(const char *remote, int argc,\n \treturn !!rv;\n }\n \n-static const struct archiver *lookup_archiver(const char *name)\n-{\n-\tint i;\n-\n-\tfor (i = 0; i < ARRAY_SIZE(archivers); i++) {\n-\t\tif (!strcmp(name, archivers[i].name))\n-\t\t\treturn &archivers[i];\n-\t}\n-\treturn NULL;\n-}\n-\n-void parse_pathspec_arg(const char **pathspec, struct archiver_args *ar_args)\n-{\n-\tar_args->pathspec = get_pathspec(ar_args->base, pathspec);\n-}\n-\n-void parse_treeish_arg(const char **argv, struct archiver_args *ar_args,\n-\t\t       const char *prefix)\n-{\n-\tconst char *name = argv[0];\n-\tconst unsigned char *commit_sha1;\n-\ttime_t archive_time;\n-\tstruct tree *tree;\n-\tconst struct commit *commit;\n-\tunsigned char sha1[20];\n-\n-\tif (get_sha1(name, sha1))\n-\t\tdie(\"Not a valid object name\");\n-\n-\tcommit = lookup_commit_reference_gently(sha1, 1);\n-\tif (commit) {\n-\t\tcommit_sha1 = commit->object.sha1;\n-\t\tarchive_time = commit->date;\n-\t} else {\n-\t\tcommit_sha1 = NULL;\n-\t\tarchive_time = time(NULL);\n-\t}\n-\n-\ttree = parse_tree_indirect(sha1);\n-\tif (tree == NULL)\n-\t\tdie(\"not a tree object\");\n-\n-\tif (prefix) {\n-\t\tunsigned char tree_sha1[20];\n-\t\tunsigned int mode;\n-\t\tint err;\n-\n-\t\terr = get_tree_entry(tree->object.sha1, prefix,\n-\t\t\t\t     tree_sha1, &mode);\n-\t\tif (err || !S_ISDIR(mode))\n-\t\t\tdie(\"current working directory is untracked\");\n-\n-\t\ttree = parse_tree_indirect(tree_sha1);\n-\t}\n-\tar_args->tree = tree;\n-\tar_args->commit_sha1 = commit_sha1;\n-\tar_args->commit = commit;\n-\tar_args->time = archive_time;\n-}\n-\n-int parse_archive_args(int argc, const char **argv, const struct archiver **ar,\n-\t\tstruct archiver_args *args)\n-{\n-\tconst char *format = \"tar\";\n-\tconst char *base = \"\";\n-\tint compression_level = -1;\n-\tint verbose = 0;\n-\tint i;\n-\n-\tfor (i = 1; i < argc; i++) {\n-\t\tconst char *arg = argv[i];\n-\n-\t\tif (!strcmp(arg, \"--list\") || !strcmp(arg, \"-l\")) {\n-\t\t\tfor (i = 0; i < ARRAY_SIZE(archivers); i++)\n-\t\t\t\tprintf(\"%s\\n\", archivers[i].name);\n-\t\t\texit(0);\n-\t\t}\n-\t\tif (!strcmp(arg, \"--verbose\") || !strcmp(arg, \"-v\")) {\n-\t\t\tverbose = 1;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!prefixcmp(arg, \"--format=\")) {\n-\t\t\tformat = arg + 9;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!prefixcmp(arg, \"--prefix=\")) {\n-\t\t\tbase = arg + 9;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"--\")) {\n-\t\t\ti++;\n-\t\t\tbreak;\n-\t\t}\n-\t\tif (arg[0] == '-' && isdigit(arg[1]) && arg[2] == '\\0') {\n-\t\t\tcompression_level = arg[1] - '0';\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (arg[0] == '-')\n-\t\t\tdie(\"Unknown argument: %s\", arg);\n-\t\tbreak;\n-\t}\n-\n-\t/* We need at least one parameter -- tree-ish */\n-\tif (argc - 1 < i)\n-\t\tusage(archive_usage);\n-\t*ar = lookup_archiver(format);\n-\tif (!*ar)\n-\t\tdie(\"Unknown archive format '%s'\", format);\n-\n-\targs->compression_level = Z_DEFAULT_COMPRESSION;\n-\tif (compression_level != -1) {\n-\t\tif ((*ar)->flags & USES_ZLIB_COMPRESSION)\n-\t\t\targs->compression_level = compression_level;\n-\t\telse {\n-\t\t\tdie(\"Argument not supported for format '%s': -%d\",\n-\t\t\t\t\tformat, compression_level);\n-\t\t}\n-\t}\n-\targs->verbose = verbose;\n-\targs->base = base;\n-\targs->baselen = strlen(base);\n-\n-\treturn i;\n-}\n-\n static const char *extract_remote_arg(int *ac, const char **av)\n {\n \tint ix, iy, cnt = *ac;\n-- \n1.6.0.rc0.42.g186458\n"},{"id":"84860","messageId":"1216982486-5887-3-git-send-email-rene.scharfe@lsrfire.ath.cx","threadId":"14671","inReplyTo":"1216982486-5887-2-git-send-email-rene.scharfe@lsrfire.ath.cx","subject":"[PATCH 3/6] archive: define MAX_ARGS where it's needed","fromName":"Rene Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-07-25T10:41:23Z","receivedAt":"2008-07-25T10:41:23Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"MAX_EXTRA_ARGS is not used anymore, so remove it.  MAX_ARGS is used only\nin builtin-upload-archive.c, so define it there.  Also report the actual\nvalue we're comparing against when the number of args is too big.\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n archive.h                |    3 ---\n builtin-upload-archive.c |    3 ++-\n 2 files changed, 2 insertions(+), 4 deletions(-)\n\ndiff --git a/archive.h b/archive.h\nindex f6ceaeb..929368d 100644\n--- a/archive.h\n+++ b/archive.h\n@@ -1,9 +1,6 @@\n #ifndef ARCHIVE_H\n #define ARCHIVE_H\n \n-#define MAX_EXTRA_ARGS\t32\n-#define MAX_ARGS\t(MAX_EXTRA_ARGS + 32)\n-\n struct archiver_args {\n \tconst char *base;\n \tsize_t baselen;\ndiff --git a/builtin-upload-archive.c b/builtin-upload-archive.c\nindex cc37b36..a9b02fa 100644\n--- a/builtin-upload-archive.c\n+++ b/builtin-upload-archive.c\n@@ -16,6 +16,7 @@ static const char deadchild[] =\n static const char lostchild[] =\n \"git upload-archive: archiver process was lost\";\n \n+#define MAX_ARGS (64)\n \n static int run_upload_archive(int argc, const char **argv, const char *prefix)\n {\n@@ -45,7 +46,7 @@ static int run_upload_archive(int argc, const char **argv, const char *prefix)\n \t\tif (len == 0)\n \t\t\tbreak;\t/* got a flush */\n \t\tif (sent_argc > MAX_ARGS - 2)\n-\t\t\tdie(\"Too many options (>29)\");\n+\t\t\tdie(\"Too many options (>%d)\", MAX_ARGS - 2);\n \n \t\tif (p[len-1] == '\\n') {\n \t\t\tp[--len] = 0;\n-- \n1.6.0.rc0.42.g186458\n"},{"id":"84864","messageId":"1216982486-5887-4-git-send-email-rene.scharfe@lsrfire.ath.cx","threadId":"14671","inReplyTo":"1216982486-5887-3-git-send-email-rene.scharfe@lsrfire.ath.cx","subject":"[PATCH 4/6] archive: declare struct archiver where it's needed","fromName":"Rene Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-07-25T10:41:24Z","receivedAt":"2008-07-25T10:41:24Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Move the declaration of struct archiver to archive.c, as this is the only\nfile left where it is used.\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n archive.c |    6 +++++-\n archive.h |    6 ------\n 2 files changed, 5 insertions(+), 7 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex c4662a2..f834b5f 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -9,7 +9,11 @@ static const char archive_usage[] = \\\n \n #define USES_ZLIB_COMPRESSION 1\n \n-const struct archiver archivers[] = {\n+const struct archiver {\n+\tconst char *name;\n+\twrite_archive_fn_t write_archive;\n+\tunsigned int flags;\n+} archivers[] = {\n \t{ \"tar\", write_tar_archive },\n \t{ \"zip\", write_zip_archive, USES_ZLIB_COMPRESSION },\n };\ndiff --git a/archive.h b/archive.h\nindex 929368d..0b15b35 100644\n--- a/archive.h\n+++ b/archive.h\n@@ -17,12 +17,6 @@ typedef int (*write_archive_fn_t)(struct archiver_args *);\n \n typedef int (*write_archive_entry_fn_t)(struct archiver_args *args, const unsigned char *sha1, const char *path, size_t pathlen, unsigned int mode, void *buffer, unsigned long size);\n \n-struct archiver {\n-\tconst char *name;\n-\twrite_archive_fn_t write_archive;\n-\tunsigned int flags;\n-};\n-\n /*\n  * Archive-format specific backends.\n  */\n-- \n1.6.0.rc0.42.g186458\n"},{"id":"84862","messageId":"1216982486-5887-5-git-send-email-rene.scharfe@lsrfire.ath.cx","threadId":"14671","inReplyTo":"1216982486-5887-4-git-send-email-rene.scharfe@lsrfire.ath.cx","subject":"[PATCH 5/6] archive: allow --exec and --remote without equal sign","fromName":"Rene Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-07-25T10:41:25Z","receivedAt":"2008-07-25T10:41:25Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Allow \"--remote repo\" and \"--exec cmd\" in addition to \"--remote=repo\" and\n\"--exec=cmd\" to make their usage consistent with parameters handled by\nparse_options().\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n builtin-archive.c |   20 +++++++++++++++++---\n 1 files changed, 17 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin-archive.c b/builtin-archive.c\nindex 4dd2716..22445ac 100644\n--- a/builtin-archive.c\n+++ b/builtin-archive.c\n@@ -15,7 +15,7 @@ static int run_remote_archiver(const char *remote, int argc,\n \tint fd[2], i, len, rv;\n \tstruct child_process *conn;\n \tconst char *exec = \"git-upload-archive\";\n-\tint exec_at = 0;\n+\tint exec_at = 0, exec_value_at = 0;\n \n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n@@ -24,7 +24,14 @@ static int run_remote_archiver(const char *remote, int argc,\n \t\t\t\tdie(\"multiple --exec specified\");\n \t\t\texec = arg + 7;\n \t\t\texec_at = i;\n-\t\t\tbreak;\n+\t\t} else if (!strcmp(arg, \"--exec\")) {\n+\t\t\tif (exec_at)\n+\t\t\t\tdie(\"multiple --exec specified\");\n+\t\t\tif (i + 1 >= argc)\n+\t\t\t\tdie(\"option --exec requires a value\");\n+\t\t\texec = argv[i + 1];\n+\t\t\texec_at = i;\n+\t\t\texec_value_at = ++i;\n \t\t}\n \t}\n \n@@ -32,7 +39,7 @@ static int run_remote_archiver(const char *remote, int argc,\n \tconn = git_connect(fd, url, exec, 0);\n \n \tfor (i = 1; i < argc; i++) {\n-\t\tif (i == exec_at)\n+\t\tif (i == exec_at || i == exec_value_at)\n \t\t\tcontinue;\n \t\tpacket_write(fd[1], \"argument %s\\n\", argv[i]);\n \t}\n@@ -78,6 +85,13 @@ static const char *extract_remote_arg(int *ac, const char **av)\n \t\t\t\t\tdie(\"Multiple --remote specified\");\n \t\t\t\tremote = arg + 9;\n \t\t\t\tcontinue;\n+\t\t\t} else if (!strcmp(arg, \"--remote\")) {\n+\t\t\t\tif (remote)\n+\t\t\t\t\tdie(\"Multiple --remote specified\");\n+\t\t\t\tif (++ix >= cnt)\n+\t\t\t\t\tdie(\"option --remote requires a value\");\n+\t\t\t\tremote = av[ix];\n+\t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (arg[0] != '-')\n \t\t\t\tno_more_options = 1;\n-- \n1.6.0.rc0.42.g186458\n"},{"id":"84861","messageId":"1216982486-5887-6-git-send-email-rene.scharfe@lsrfire.ath.cx","threadId":"14671","inReplyTo":"1216982486-5887-5-git-send-email-rene.scharfe@lsrfire.ath.cx","subject":"[PATCH 5/6] archive: allow --exec and --remote without equal sign","fromName":"Rene Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-07-25T10:41:26Z","receivedAt":"2008-07-25T10:41:26Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Convert git archive to parse_options().  The parameters --remote and --exec\nare still handled by their special parser.  Define them anyway in order for\nthem to show up in the usage notice.\n\nNote: in a command like \"git archive --prefix --remote=a/ HEAD\", the string\n\"--remote=a/\" will be interpreted as a remote option, not a prefix, because\nthat special parser sees it first.  If one needs such a strange prefix, it\nneeds to be specified like this: \"git archive --prefix=--remote=a/ HEAD\"\n(with an equal sign).\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n archive.c |  110 +++++++++++++++++++++++++++++++++++++-----------------------\n 1 files changed, 68 insertions(+), 42 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex f834b5f..5b40e26 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -3,9 +3,15 @@\n #include \"tree-walk.h\"\n #include \"attr.h\"\n #include \"archive.h\"\n-\n-static const char archive_usage[] = \\\n-\"git archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]\";\n+#include \"parse-options.h\"\n+\n+static char const * const archive_usage[] = {\n+\t\"git archive [options] <tree-ish> [path...]\",\n+\t\"git archive --list\",\n+\t\"git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [path...]\",\n+\t\"git archive --remote <repo> [--exec <cmd>] --list\",\n+\tNULL\n+};\n \n #define USES_ZLIB_COMPRESSION 1\n \n@@ -175,6 +181,9 @@ static const struct archiver *lookup_archiver(const char *name)\n {\n \tint i;\n \n+\tif (!name)\n+\t\treturn NULL;\n+\n \tfor (i = 0; i < ARRAY_SIZE(archivers); i++) {\n \t\tif (!strcmp(name, archivers[i].name))\n \t\t\treturn &archivers[i];\n@@ -232,51 +241,70 @@ static void parse_treeish_arg(const char **argv,\n \tar_args->time = archive_time;\n }\n \n+#define OPT__COMPR(s, v, h, p) \\\n+\t{ OPTION_SET_INT, (s), NULL, (v), NULL, (h), \\\n+\t  PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, (p) }\n+#define OPT__COMPR_HIDDEN(s, v, p) \\\n+\t{ OPTION_SET_INT, (s), NULL, (v), NULL, \"\", \\\n+\t  PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN, NULL, (p) }\n+\n static int parse_archive_args(int argc, const char **argv,\n \t\tconst struct archiver **ar, struct archiver_args *args)\n {\n \tconst char *format = \"tar\";\n-\tconst char *base = \"\";\n+\tconst char *base = NULL;\n+\tconst char *remote = NULL;\n+\tconst char *exec = NULL;\n \tint compression_level = -1;\n \tint verbose = 0;\n \tint i;\n-\n-\tfor (i = 1; i < argc; i++) {\n-\t\tconst char *arg = argv[i];\n-\n-\t\tif (!strcmp(arg, \"--list\") || !strcmp(arg, \"-l\")) {\n-\t\t\tfor (i = 0; i < ARRAY_SIZE(archivers); i++)\n-\t\t\t\tprintf(\"%s\\n\", archivers[i].name);\n-\t\t\texit(0);\n-\t\t}\n-\t\tif (!strcmp(arg, \"--verbose\") || !strcmp(arg, \"-v\")) {\n-\t\t\tverbose = 1;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!prefixcmp(arg, \"--format=\")) {\n-\t\t\tformat = arg + 9;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!prefixcmp(arg, \"--prefix=\")) {\n-\t\t\tbase = arg + 9;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"--\")) {\n-\t\t\ti++;\n-\t\t\tbreak;\n-\t\t}\n-\t\tif (arg[0] == '-' && isdigit(arg[1]) && arg[2] == '\\0') {\n-\t\t\tcompression_level = arg[1] - '0';\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (arg[0] == '-')\n-\t\t\tdie(\"Unknown argument: %s\", arg);\n-\t\tbreak;\n+\tint list = 0;\n+\tstruct option opts[] = {\n+\t\tOPT_GROUP(\"\"),\n+\t\tOPT_STRING(0, \"format\", &format, \"fmt\", \"archive format\"),\n+\t\tOPT_STRING(0, \"prefix\", &base, \"prefix\",\n+\t\t\t\"prepend prefix to each pathname in the archive\"),\n+\t\tOPT__VERBOSE(&verbose),\n+\t\tOPT__COMPR('0', &compression_level, \"store only\", 0),\n+\t\tOPT__COMPR('1', &compression_level, \"compress faster\", 1),\n+\t\tOPT__COMPR_HIDDEN('2', &compression_level, 2),\n+\t\tOPT__COMPR_HIDDEN('3', &compression_level, 3),\n+\t\tOPT__COMPR_HIDDEN('4', &compression_level, 4),\n+\t\tOPT__COMPR_HIDDEN('5', &compression_level, 5),\n+\t\tOPT__COMPR_HIDDEN('6', &compression_level, 6),\n+\t\tOPT__COMPR_HIDDEN('7', &compression_level, 7),\n+\t\tOPT__COMPR_HIDDEN('8', &compression_level, 8),\n+\t\tOPT__COMPR('9', &compression_level, \"compress better\", 9),\n+\t\tOPT_GROUP(\"\"),\n+\t\tOPT_BOOLEAN('l', \"list\", &list,\n+\t\t\t\"list supported archive formats\"),\n+\t\tOPT_GROUP(\"\"),\n+\t\tOPT_STRING(0, \"remote\", &remote, \"repo\",\n+\t\t\t\"retrieve the archive from remote repository <repo>\"),\n+\t\tOPT_STRING(0, \"exec\", &exec, \"cmd\",\n+\t\t\t\"path to the remote git-upload-archive command\"),\n+\t\tOPT_END()\n+\t};\n+\n+\targc = parse_options(argc, argv, opts, archive_usage, 0);\n+\n+\tif (remote)\n+\t\tdie(\"Unexpected option --remote\");\n+\tif (exec)\n+\t\tdie(\"Option --exec can only be used together with --remote\");\n+\n+\tif (!base)\n+\t\tbase = \"\";\n+\n+\tif (list) {\n+\t\tfor (i = 0; i < ARRAY_SIZE(archivers); i++)\n+\t\t\tprintf(\"%s\\n\", archivers[i].name);\n+\t\texit(0);\n \t}\n \n \t/* We need at least one parameter -- tree-ish */\n-\tif (argc - 1 < i)\n-\t\tusage(archive_usage);\n+\tif (argc < 1)\n+\t\tusage_with_options(archive_usage, opts);\n \t*ar = lookup_archiver(format);\n \tif (!*ar)\n \t\tdie(\"Unknown archive format '%s'\", format);\n@@ -294,7 +322,7 @@ static int parse_archive_args(int argc, const char **argv,\n \targs->base = base;\n \targs->baselen = strlen(base);\n \n-\treturn i;\n+\treturn argc;\n }\n \n int write_archive(int argc, const char **argv, const char *prefix,\n@@ -302,13 +330,11 @@ int write_archive(int argc, const char **argv, const char *prefix,\n {\n \tconst struct archiver *ar = NULL;\n \tstruct archiver_args args;\n-\tint tree_idx;\n \n-\ttree_idx = parse_archive_args(argc, argv, &ar, &args);\n+\targc = parse_archive_args(argc, argv, &ar, &args);\n \tif (setup_prefix && prefix == NULL)\n \t\tprefix = setup_git_directory();\n \n-\targv += tree_idx;\n \tparse_treeish_arg(argv, &args, prefix);\n \tparse_pathspec_arg(argv + 1, &args);\n \n-- \n1.6.0.rc0.42.g186458\n"},{"id":"84865","messageId":"4889B0C8.70908@lsrfire.ath.cx","threadId":"14671","inReplyTo":"1216982486-5887-6-git-send-email-rene.scharfe@lsrfire.ath.cx","subject":"Re: [PATCH 5/6] archive: allow --exec and --remote without equal sign","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-07-25T10:54:00Z","receivedAt":"2008-07-25T10:54:00Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Rene Scharfe schrieb:\n> Convert git archive to parse_options().  The parameters --remote and --exec\n> are still handled by their special parser.  Define them anyway in order for\n> them to show up in the usage notice.\n\nHmpf, the _real_ subject of this email is \"[PATCH 6/6] archive: convert\nto parse_options()\"..\n\nRené\n"},{"id":"84969","messageId":"7vr69hpjyo.fsf@gitster.siamese.dyndns.org","threadId":"14671","inReplyTo":"1216982486-5887-5-git-send-email-rene.scharfe@lsrfire.ath.cx","subject":"Re: [PATCH 5/6] archive: allow --exec and --remote without equal sign","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-07-26T00:28:31Z","receivedAt":"2008-07-26T00:28:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rene Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n\n> Allow \"--remote repo\" and \"--exec cmd\" in addition to \"--remote=repo\" and\n> \"--exec=cmd\" to make their usage consistent with parameters handled by\n> parse_options().\n>\n> Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n> ---\n>  builtin-archive.c |   20 +++++++++++++++++---\n>  1 files changed, 17 insertions(+), 3 deletions(-)\n>\n> diff --git a/builtin-archive.c b/builtin-archive.c\n> index 4dd2716..22445ac 100644\n> --- a/builtin-archive.c\n> +++ b/builtin-archive.c\n> @@ -15,7 +15,7 @@ static int run_remote_archiver(const char *remote, int argc,\n>  \tint fd[2], i, len, rv;\n>  \tstruct child_process *conn;\n>  \tconst char *exec = \"git-upload-archive\";\n> -\tint exec_at = 0;\n> +\tint exec_at = 0, exec_value_at = 0;\n>  \n>  \tfor (i = 1; i < argc; i++) {\n>  \t\tconst char *arg = argv[i];\n> @@ -24,7 +24,14 @@ static int run_remote_archiver(const char *remote, int argc,\n>  \t\t\t\tdie(\"multiple --exec specified\");\n>  \t\t\texec = arg + 7;\n>  \t\t\texec_at = i;\n> -\t\t\tbreak;\n\nInteresting...  With this \"break\", we would have never triggered the\nmultiple --exec error, wouldn't we?\n\nThe patch itself looked fine.  Thanks.\n"},{"id":"84970","messageId":"7vmyk5pjsy.fsf@gitster.siamese.dyndns.org","threadId":"14671","inReplyTo":"1216982486-5887-6-git-send-email-rene.scharfe@lsrfire.ath.cx","subject":"Re: [PATCH 5/6] archive: allow --exec and --remote without equal sign","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-07-26T00:31:57Z","receivedAt":"2008-07-26T00:31:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rene Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n\n> Convert git archive to parse_options().  The parameters --remote and --exec\n> are still handled by their special parser.  Define them anyway in order for\n> them to show up in the usage notice.\n>\n> Note: in a command like \"git archive --prefix --remote=a/ HEAD\", the string\n> \"--remote=a/\" will be interpreted as a remote option, not a prefix, because\n> that special parser sees it first.  If one needs such a strange prefix, it\n> needs to be specified like this: \"git archive --prefix=--remote=a/ HEAD\"\n> (with an equal sign).\n>\n> Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n> ---\n>  archive.c |  110 +++++++++++++++++++++++++++++++++++++-----------------------\n>  1 files changed, 68 insertions(+), 42 deletions(-)\n\nHmph, somewhat dubious.\n\nThe real point of parse-options was to make the code smaller, easier to\nmaintain and command line handling more consistent.  At least this patch\nseems to fail on the two out of three counts.\n\nAll of the other patches made obvious sense to me and are queued for -rc1\nbut I'd like to backburner this one.\n"},{"id":"85022","messageId":"488ACDA4.4010404@lsrfire.ath.cx","threadId":"14671","inReplyTo":"7vmyk5pjsy.fsf@gitster.siamese.dyndns.org","subject":"Re: PATCH 6/6] archive: convert,to parse_options() [was: [PATCH 5/6] archive: allow --exec and --remote without equal sign]","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-07-26T07:09:24Z","receivedAt":"2008-07-26T07:09:24Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Junio C Hamano schrieb:\n>>  archive.c |  110 +++++++++++++++++++++++++++++++++++++-----------------------\n>>  1 files changed, 68 insertions(+), 42 deletions(-)\n> \n> Hmph, somewhat dubious.\n> \n> The real point of parse-options was to make the code smaller, easier to\n> maintain and command line handling more consistent.  At least this patch\n> seems to fail on the two out of three counts.\n\nWell, if we hid away the compression level handling in a macro defined\nin parse-options.h, we could save sixteen lines of code.  The patch\nmakes the four modes of running archive more explicit, adding three\nusage lines.  Three empty lines are added -- they don't really increase\nthe code's size.\n\nHandling --exec and --remote takes six lines; we didn't do that before\nat this place, but have to now, since we want them to show up in the\nusage.  We have to handle --no-format and --no-prefix, which adds four\nlines.\n\nSo I don't think the bigger size make this patch dubious, but of course\nI'm biased.  Disallowing --no-format (using a new OPT_STRING_NONEG?) and\nadding an OPT__COMPRESSION helper might be a good idea (reducing line\ncount in archive.c by seventeen).\n\nHaving parse-options provide a way to make --exec and --remote appear in\nthe usage but to reject them (OPT_UNKNOWN?) is a bit too strange, though.\n\n> All of the other patches made obvious sense to me and are queued for -rc1\n> but I'd like to backburner this one.\n\nFair enough.\n\nRené\n"}]}