From 4fac1d3a98bb86d855b706d7ce6a5069b9f687e8 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Fri, 25 Jul 2008 12:41:26 +0200 Subject: [PATCH 01/80] archive: allow --exec and --remote without equal sign Convert git archive to parse_options(). The parameters --remote and --exec are still handled by their special parser. Define them anyway in order for them to show up in the usage notice. Note: in a command like "git archive --prefix --remote=a/ HEAD", the string "--remote=a/" will be interpreted as a remote option, not a prefix, because that special parser sees it first. If one needs such a strange prefix, it needs to be specified like this: "git archive --prefix=--remote=a/ HEAD" (with an equal sign). Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- archive.c | 104 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 39 deletions(-) diff --git a/archive.c b/archive.c index f834b5f51f..5b40e261f1 100644 --- a/archive.c +++ b/archive.c @@ -3,9 +3,15 @@ #include "tree-walk.h" #include "attr.h" #include "archive.h" +#include "parse-options.h" -static const char archive_usage[] = \ -"git archive --format= [--prefix=/] [--verbose] [] [path...]"; +static char const * const archive_usage[] = { + "git archive [options] [path...]", + "git archive --list", + "git archive --remote [--exec ] [options] [path...]", + "git archive --remote [--exec ] --list", + NULL +}; #define USES_ZLIB_COMPRESSION 1 @@ -175,6 +181,9 @@ static const struct archiver *lookup_archiver(const char *name) { int i; + if (!name) + return NULL; + for (i = 0; i < ARRAY_SIZE(archivers); i++) { if (!strcmp(name, archivers[i].name)) return &archivers[i]; @@ -232,51 +241,70 @@ static void parse_treeish_arg(const char **argv, ar_args->time = archive_time; } +#define OPT__COMPR(s, v, h, p) \ + { OPTION_SET_INT, (s), NULL, (v), NULL, (h), \ + PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, (p) } +#define OPT__COMPR_HIDDEN(s, v, p) \ + { OPTION_SET_INT, (s), NULL, (v), NULL, "", \ + PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN, NULL, (p) } + static int parse_archive_args(int argc, const char **argv, const struct archiver **ar, struct archiver_args *args) { const char *format = "tar"; - const char *base = ""; + const char *base = NULL; + const char *remote = NULL; + const char *exec = NULL; int compression_level = -1; int verbose = 0; int i; + int list = 0; + struct option opts[] = { + OPT_GROUP(""), + OPT_STRING(0, "format", &format, "fmt", "archive format"), + OPT_STRING(0, "prefix", &base, "prefix", + "prepend prefix to each pathname in the archive"), + OPT__VERBOSE(&verbose), + OPT__COMPR('0', &compression_level, "store only", 0), + OPT__COMPR('1', &compression_level, "compress faster", 1), + OPT__COMPR_HIDDEN('2', &compression_level, 2), + OPT__COMPR_HIDDEN('3', &compression_level, 3), + OPT__COMPR_HIDDEN('4', &compression_level, 4), + OPT__COMPR_HIDDEN('5', &compression_level, 5), + OPT__COMPR_HIDDEN('6', &compression_level, 6), + OPT__COMPR_HIDDEN('7', &compression_level, 7), + OPT__COMPR_HIDDEN('8', &compression_level, 8), + OPT__COMPR('9', &compression_level, "compress better", 9), + OPT_GROUP(""), + OPT_BOOLEAN('l', "list", &list, + "list supported archive formats"), + OPT_GROUP(""), + OPT_STRING(0, "remote", &remote, "repo", + "retrieve the archive from remote repository "), + OPT_STRING(0, "exec", &exec, "cmd", + "path to the remote git-upload-archive command"), + OPT_END() + }; - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; + argc = parse_options(argc, argv, opts, archive_usage, 0); - if (!strcmp(arg, "--list") || !strcmp(arg, "-l")) { - for (i = 0; i < ARRAY_SIZE(archivers); i++) - printf("%s\n", archivers[i].name); - exit(0); - } - if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) { - verbose = 1; - continue; - } - if (!prefixcmp(arg, "--format=")) { - format = arg + 9; - continue; - } - if (!prefixcmp(arg, "--prefix=")) { - base = arg + 9; - continue; - } - if (!strcmp(arg, "--")) { - i++; - break; - } - if (arg[0] == '-' && isdigit(arg[1]) && arg[2] == '\0') { - compression_level = arg[1] - '0'; - continue; - } - if (arg[0] == '-') - die("Unknown argument: %s", arg); - break; + if (remote) + die("Unexpected option --remote"); + if (exec) + die("Option --exec can only be used together with --remote"); + + if (!base) + base = ""; + + if (list) { + for (i = 0; i < ARRAY_SIZE(archivers); i++) + printf("%s\n", archivers[i].name); + exit(0); } /* We need at least one parameter -- tree-ish */ - if (argc - 1 < i) - usage(archive_usage); + if (argc < 1) + usage_with_options(archive_usage, opts); *ar = lookup_archiver(format); if (!*ar) die("Unknown archive format '%s'", format); @@ -294,7 +322,7 @@ static int parse_archive_args(int argc, const char **argv, args->base = base; args->baselen = strlen(base); - return i; + return argc; } int write_archive(int argc, const char **argv, const char *prefix, @@ -302,13 +330,11 @@ int write_archive(int argc, const char **argv, const char *prefix, { const struct archiver *ar = NULL; struct archiver_args args; - int tree_idx; - tree_idx = parse_archive_args(argc, argv, &ar, &args); + argc = parse_archive_args(argc, argv, &ar, &args); if (setup_prefix && prefix == NULL) prefix = setup_git_directory(); - argv += tree_idx; parse_treeish_arg(argv, &args, prefix); parse_pathspec_arg(argv + 1, &args); From 5354a56fe70420c147f930e0f7f1decbae685d19 Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Wed, 30 Jul 2008 13:48:33 -0400 Subject: [PATCH 02/80] Replace uses of "git-var" with "git var" Signed-off-by: Todd Zullinger Signed-off-by: Junio C Hamano --- Documentation/git-send-email.txt | 2 +- contrib/examples/git-commit.sh | 6 +++--- contrib/examples/git-tag.sh | 2 +- git-am.sh | 2 +- ident.c | 2 +- perl/Git.pm | 2 +- var.c | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index afbb294a7f..e2437f30ca 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -56,7 +56,7 @@ The --cc option must be repeated for each user you want on the cc list. --from:: Specify the sender of the emails. This will default to - the value GIT_COMMITTER_IDENT, as returned by "git-var -l". + the value GIT_COMMITTER_IDENT, as returned by "git var -l". The user will still be prompted to confirm this entry. --in-reply-to:: diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh index 2c4a4062a5..5c72f655c7 100755 --- a/contrib/examples/git-commit.sh +++ b/contrib/examples/git-commit.sh @@ -443,7 +443,7 @@ fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG case "$signoff" in t) - sign=$(git-var GIT_COMMITTER_IDENT | sed -e ' + sign=$(git var GIT_COMMITTER_IDENT | sed -e ' s/>.*/>/ s/^/Signed-off-by: / ') @@ -535,8 +535,8 @@ esac case "$no_edit" in '') - git-var GIT_AUTHOR_IDENT > /dev/null || die - git-var GIT_COMMITTER_IDENT > /dev/null || die + git var GIT_AUTHOR_IDENT > /dev/null || die + git var GIT_COMMITTER_IDENT > /dev/null || die git_editor "$GIT_DIR/COMMIT_EDITMSG" ;; esac diff --git a/contrib/examples/git-tag.sh b/contrib/examples/git-tag.sh index e9f3a228af..2c15bc955b 100755 --- a/contrib/examples/git-tag.sh +++ b/contrib/examples/git-tag.sh @@ -164,7 +164,7 @@ git check-ref-format "tags/$name" || object=$(git rev-parse --verify --default HEAD "$@") || exit 1 type=$(git cat-file -t $object) || exit 1 -tagger=$(git-var GIT_COMMITTER_IDENT) || exit 1 +tagger=$(git var GIT_COMMITTER_IDENT) || exit 1 test -n "$username" || username=$(git config user.signingkey) || diff --git a/git-am.sh b/git-am.sh index 6aa819280e..8f91a97eb3 100755 --- a/git-am.sh +++ b/git-am.sh @@ -291,7 +291,7 @@ fi ws=`cat "$dotest/whitespace"` if test "$(cat "$dotest/sign")" = t then - SIGNOFF=`git-var GIT_COMMITTER_IDENT | sed -e ' + SIGNOFF=`git var GIT_COMMITTER_IDENT | sed -e ' s/>.*/>/ s/^/Signed-off-by: /' ` diff --git a/ident.c b/ident.c index b35504a8d2..09cf0c95c9 100644 --- a/ident.c +++ b/ident.c @@ -204,7 +204,7 @@ const char *fmt_ident(const char *name, const char *email, if ((warn_on_no_name || error_on_no_name) && name == git_default_name && env_hint) { fprintf(stderr, env_hint, au_env, co_env); - env_hint = NULL; /* warn only once, for "git-var -l" */ + env_hint = NULL; /* warn only once, for "git var -l" */ } if (error_on_no_name) die("empty ident %s <%s> not allowed", name, email); diff --git a/perl/Git.pm b/perl/Git.pm index d99e778200..087d3d0e82 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -730,7 +730,7 @@ This suite of functions retrieves and parses ident information, as stored in the commit and tag objects or produced by C (thus C can be either I or I; case is insignificant). -The C method retrieves the ident information from C +The C method retrieves the ident information from C and either returns it as a scalar string or as an array with the fields parsed. Alternatively, it can take a prepared ident string (e.g. from the commit object) and just parse it. diff --git a/var.c b/var.c index 724ba87a7c..f1eb314e89 100644 --- a/var.c +++ b/var.c @@ -5,7 +5,7 @@ */ #include "cache.h" -static const char var_usage[] = "git-var [-l | ]"; +static const char var_usage[] = "git var [-l | ]"; struct git_var { const char *name; From c4aca9ccda51badb672ab70099863072d1567267 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 30 Jul 2008 12:53:45 -0700 Subject: [PATCH 03/80] Fix test-parse-options "integer" test OPT_INTEGER() works on an integer, not on an unsigned long. On a big endian architecture with long larger than int, integer test gives bogus results because of this bug. Reported by H.Merijn Brand in HP-UX 64-bit environment. Signed-off-by: Junio C Hamano --- t/t0040-parse-options.sh | 11 ++++++++++- test-parse-options.c | 8 +++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 03dbe00102..e38241c80a 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -47,6 +47,7 @@ test_expect_success 'test help' ' cat > expect << EOF boolean: 2 integer: 1729 +timestamp: 0 string: 123 abbrev: 7 verbose: 2 @@ -63,6 +64,7 @@ test_expect_success 'short options' ' cat > expect << EOF boolean: 2 integer: 1729 +timestamp: 0 string: 321 abbrev: 10 verbose: 2 @@ -88,6 +90,7 @@ test_expect_success 'missing required value' ' cat > expect << EOF boolean: 1 integer: 13 +timestamp: 0 string: 123 abbrev: 7 verbose: 0 @@ -108,6 +111,7 @@ test_expect_success 'intermingled arguments' ' cat > expect << EOF boolean: 0 integer: 2 +timestamp: 0 string: (not set) abbrev: 7 verbose: 0 @@ -135,6 +139,7 @@ test_expect_success 'ambiguously abbreviated option' ' cat > expect << EOF boolean: 0 integer: 0 +timestamp: 0 string: 123 abbrev: 7 verbose: 0 @@ -161,6 +166,7 @@ test_expect_success 'detect possible typos' ' cat > expect < expect < expect < expect <"), + OPT_DATE('t', NULL, ×tamp, "get timestamp of