Merge branch 'ph/parseopt'
authorJunio C Hamano <gitster@pobox.com>
Fri, 2 Nov 2007 23:42:23 +0000 (16:42 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 2 Nov 2007 23:42:23 +0000 (16:42 -0700)
* ph/parseopt: (24 commits)
gc: use parse_options
Fixed a command line option type for builtin-fsck.c
Make builtin-pack-refs.c use parse_options.
Make builtin-name-rev.c use parse_options.
Make builtin-count-objects.c use parse_options.
Make builtin-fsck.c use parse_options.
Update manpages to reflect new short and long option aliases
Make builtin-for-each-ref.c use parse-opts.
Make builtin-symbolic-ref.c use parse_options.
Make builtin-update-ref.c use parse_options
Make builtin-revert.c use parse_options.
Make builtin-describe.c use parse_options
Make builtin-branch.c use parse_options.
Make builtin-mv.c use parse-options
Make builtin-rm.c use parse_options.
Port builtin-add.c to use the new option parser.
parse-options: allow callbacks to take no arguments at all.
parse-options: Allow abbreviated options when unambiguous
Add shortcuts for very often used options.
parse-options: make some arguments optional, add callbacks.
...

Conflicts:

Makefile
builtin-add.c

1  2 
.gitignore
Makefile
builtin-add.c
builtin-revert.c
diff --combined .gitignore
index 8670081adf1698cdf189deb30116d50881217c84,249b451b87cfddc98e9c32f94c7d14ba91c7e1ad..c8c13f550317e12ccb5d3515fbc942463c8be4e0
@@@ -128,6 -128,7 +128,6 @@@ git-statu
  git-stripspace
  git-submodule
  git-svn
 -git-svnimport
  git-symbolic-ref
  git-tag
  git-tar-tree
@@@ -153,6 -154,7 +153,7 @@@ test-delt
  test-dump-cache-tree
  test-genrandom
  test-match-trees
+ test-parse-options
  test-sha1
  common-cmds.h
  *.tar.gz
diff --combined Makefile
index 71479a2a64249c2bf3f015852f1aa9aa9392d509,3c9af55f441474e0621e31f7dc4566e49fa4c9a7..042f79ef8f9e5863605e7ef19136b39b1487a07a
+++ b/Makefile
@@@ -225,7 -225,8 +225,7 @@@ SCRIPT_SH = 
  SCRIPT_PERL = \
        git-add--interactive.perl \
        git-archimport.perl git-cvsimport.perl git-relink.perl \
 -      git-cvsserver.perl git-remote.perl \
 -      git-svnimport.perl git-cvsexportcommit.perl \
 +      git-cvsserver.perl git-remote.perl git-cvsexportcommit.perl \
        git-send-email.perl git-svn.perl
  
  SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
@@@ -289,7 -290,7 +289,7 @@@ LIB_H = 
        run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
        tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h \
        utf8.h reflog-walk.h patch-ids.h attr.h decorate.h progress.h \
-       mailmap.h remote.h transport.h diffcore.h hash.h
 -      mailmap.h remote.h parse-options.h transport.h
++      mailmap.h remote.h parse-options.h transport.h diffcore.h hash.h
  
  DIFF_OBJS = \
        diff.o diff-lib.o diffcore-break.o diffcore-order.o \
  LIB_OBJS = \
        blob.o commit.o connect.o csum-file.o cache-tree.o base85.o \
        date.o diff-delta.o entry.o exec_cmd.o ident.o \
 -      interpolate.o \
 +      interpolate.o hash.o \
        lockfile.o \
        patch-ids.o \
        object.o pack-check.o pack-write.o patch-delta.o path.o pkt-line.o \
        alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
        color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
        convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o \
-       transport.o bundle.o walker.o
+       transport.o bundle.o walker.o parse-options.o
  
  BUILTIN_OBJS = \
        builtin-add.o \
@@@ -916,6 -917,7 +916,6 @@@ git-http-push$X: revision.o http.o http
  
  $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
  $(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
 -$(DIFF_OBJS): diffcore.h
  
  $(LIB_FILE): $(LIB_OBJS)
        $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
@@@ -974,7 -976,7 +974,7 @@@ endi
  
  ### Testing rules
  
- TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X
+ TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X test-parse-options$X
  
  all:: $(TEST_PROGRAMS)
  
diff --combined builtin-add.c
index dbbb05215fbcfad5d45e5d60e9d985760705d716,f61681c3ae186e1a6f96c5f7d4d6b978d0de5ddb..45b14e8a61764e18d8b89ebfef550a820ffbf831
  #include "commit.h"
  #include "revision.h"
  #include "run-command.h"
+ #include "parse-options.h"
  
- static const char builtin_add_usage[] =
- "git-add [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh] [--] <filepattern>...";
+ static const char * const builtin_add_usage[] = {
+       "git-add [options] [--] <filepattern>...",
+       NULL
+ };
  
  static int take_worktree_changes;
  static const char *excludes_file;
@@@ -108,7 -111,7 +111,7 @@@ static void update_callback(struct diff
        }
  }
  
 -static void update(int verbose, const char *prefix, const char **files)
 +void add_files_to_cache(int verbose, const char *prefix, const char **files)
  {
        struct rev_info rev;
        init_revisions(&rev, prefix);
        rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
        rev.diffopt.format_callback = update_callback;
        rev.diffopt.format_callback_data = &verbose;
 -      if (read_cache() < 0)
 -              die("index file corrupt");
        run_diff_files(&rev, 0);
  }
  
@@@ -150,86 -155,57 +153,63 @@@ static int git_add_config(const char *v
        return git_default_config(var, value);
  }
  
 +int interactive_add(void)
 +{
 +      const char *argv[2] = { "add--interactive", NULL };
 +
 +      return run_command_v_opt(argv, RUN_GIT_CMD);
 +}
 +
  static struct lock_file lock_file;
  
  static const char ignore_error[] =
  "The following paths are ignored by one of your .gitignore files:\n";
  
+ static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
+ static int add_interactive = 0;
+ static struct option builtin_add_options[] = {
+       OPT__DRY_RUN(&show_only),
+       OPT__VERBOSE(&verbose),
+       OPT_GROUP(""),
+       OPT_BOOLEAN('i', "interactive", &add_interactive, "interactive picking"),
+       OPT_BOOLEAN('f', NULL, &ignored_too, "allow adding otherwise ignored files"),
+       OPT_BOOLEAN('u', NULL, &take_worktree_changes, "update tracked files"),
+       OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"),
+       OPT_END(),
+ };
  int cmd_add(int argc, const char **argv, const char *prefix)
  {
-       int i, newfd;
-       int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
+       int i, newfd, orig_argc = argc;
        const char **pathspec;
        struct dir_struct dir;
-       int add_interactive = 0;
  
-       for (i = 1; i < argc; i++) {
-               if (!strcmp("--interactive", argv[i]) ||
-                   !strcmp("-i", argv[i]))
-                       add_interactive++;
-       }
+       argc = parse_options(argc, argv, builtin_add_options,
+                         builtin_add_usage, 0);
        if (add_interactive) {
-               if (argc != 2)
 -              const char *args[] = { "add--interactive", NULL };
 -
+               if (add_interactive != 1 || orig_argc != 2)
                        die("add --interactive does not take any parameters");
 -              execv_git_cmd(args);
 -              exit(1);
 +              exit(interactive_add());
        }
  
        git_config(git_add_config);
  
        newfd = hold_locked_index(&lock_file, 1);
  
-       for (i = 1; i < argc; i++) {
-               const char *arg = argv[i];
-               if (arg[0] != '-')
-                       break;
-               if (!strcmp(arg, "--")) {
-                       i++;
-                       break;
-               }
-               if (!strcmp(arg, "-n")) {
-                       show_only = 1;
-                       continue;
-               }
-               if (!strcmp(arg, "-f")) {
-                       ignored_too = 1;
-                       continue;
-               }
-               if (!strcmp(arg, "-v")) {
-                       verbose = 1;
-                       continue;
-               }
-               if (!strcmp(arg, "-u")) {
-                       take_worktree_changes = 1;
-                       continue;
-               }
-               if (!strcmp(arg, "--refresh")) {
-                       refresh_only = 1;
-                       continue;
-               }
-               usage(builtin_add_usage);
-       }
        if (take_worktree_changes) {
 -              update(verbose, prefix, argv);
 +              if (read_cache() < 0)
 +                      die("index file corrupt");
-               add_files_to_cache(verbose, prefix, argv + i);
++              add_files_to_cache(verbose, prefix, argv);
                goto finish;
        }
  
-       if (argc <= i) {
+       if (argc == 0) {
                fprintf(stderr, "Nothing specified, nothing added.\n");
                fprintf(stderr, "Maybe you wanted to say 'git add .'?\n");
                return 0;
        }
-       pathspec = get_pathspec(prefix, argv + i);
+       pathspec = get_pathspec(prefix, argv);
  
        if (refresh_only) {
                refresh(verbose, pathspec);
diff --combined builtin-revert.c
index e855b206cf030c5e907d94b171fbbfe3b9601a2b,2ea766b5bfc1375a2ff03664ffb55fa558b11da0..a9347cf9c57b2e4d15d37da609a2851e5b1cfc8e
@@@ -7,6 -7,7 +7,7 @@@
  #include "run-command.h"
  #include "exec_cmd.h"
  #include "utf8.h"
+ #include "parse-options.h"
  
  /*
   * This implements the builtins revert and cherry-pick.
   * Copyright (c) 2005 Junio C Hamano
   */
  
- static const char *revert_usage = "git-revert [--edit | --no-edit] [-n] <commit-ish>";
+ static const char * const revert_usage[] = {
+       "git-revert [options] <commit-ish>",
+       NULL
+ };
  
- static const char *cherry_pick_usage = "git-cherry-pick [--edit] [-n] [-r] [-x] <commit-ish>";
+ static const char * const cherry_pick_usage[] = {
+       "git-cherry-pick [options] <commit-ish>",
+       NULL
+ };
  
- static int edit;
- static int replay;
+ static int edit, no_replay, no_commit, needed_deref;
  static enum { REVERT, CHERRY_PICK } action;
- static int no_commit;
  static struct commit *commit;
- static int needed_deref;
  
  static const char *me;
  
  #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
  
- static void parse_options(int argc, const char **argv)
+ static void parse_args(int argc, const char **argv)
  {
-       const char *usage_str = action == REVERT ?
-               revert_usage : cherry_pick_usage;
+       const char * const * usage_str =
+               action == REVERT ?  revert_usage : cherry_pick_usage;
        unsigned char sha1[20];
        const char *arg;
-       int i;
-       if (argc < 2)
-               usage(usage_str);
-       for (i = 1; i < argc; i++) {
-               arg = argv[i];
-               if (arg[0] != '-')
-                       break;
-               if (!strcmp(arg, "-n") || !strcmp(arg, "--no-commit"))
-                       no_commit = 1;
-               else if (!strcmp(arg, "-e") || !strcmp(arg, "--edit"))
-                       edit = 1;
-               else if (!strcmp(arg, "--no-edit"))
-                       edit = 0;
-               else if (!strcmp(arg, "-x") || !strcmp(arg, "--i-really-want-"
-                               "to-expose-my-private-commit-object-name"))
-                       replay = 0;
-               else if (strcmp(arg, "-r"))
-                       usage(usage_str);
-       }
-       if (i != argc - 1)
-               usage(usage_str);
-       arg = argv[argc - 1];
+       int noop;
+       struct option options[] = {
+               OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"),
+               OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"),
+               OPT_BOOLEAN('x', NULL, &no_replay, "append commit name when cherry-picking"),
+               OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"),
+               OPT_END(),
+       };
+       if (parse_options(argc, argv, options, usage_str, 0) != 1)
+               usage_with_options(usage_str, options);
+       arg = argv[0];
        if (get_sha1(arg, sha1))
                die ("Cannot find '%s'", arg);
        commit = (struct commit *)parse_object(sha1);
@@@ -243,10 -235,10 +235,10 @@@ static int revert_or_cherry_pick(int ar
        git_config(git_default_config);
        me = action == REVERT ? "revert" : "cherry-pick";
        setenv(GIT_REFLOG_ACTION, me, 0);
-       parse_options(argc, argv);
+       parse_args(argc, argv);
  
        /* this is copied from the shell script, but it's never triggered... */
-       if (action == REVERT && replay)
+       if (action == REVERT && !no_replay)
                die("revert is incompatible with replay");
  
        if (no_commit) {
                next = commit;
                set_author_ident_env(message);
                add_message_to_msg(message);
-               if (!replay) {
+               if (no_replay) {
                        add_to_msg("(cherry picked from commit ");
                        add_to_msg(sha1_to_hex(commit->object.sha1));
                        add_to_msg(")\n");
                        die ("Error wrapping up %s", defmsg);
                fprintf(stderr, "Automatic %s failed.  "
                        "After resolving the conflicts,\n"
 -                      "mark the corrected paths with 'git-add <paths>'\n"
 +                      "mark the corrected paths with 'git add <paths>' "
                        "and commit the result.\n", me);
                if (action == CHERRY_PICK) {
                        fprintf(stderr, "When commiting, use the option "
@@@ -388,13 -380,14 +380,14 @@@ int cmd_revert(int argc, const char **a
  {
        if (isatty(0))
                edit = 1;
+       no_replay = 1;
        action = REVERT;
        return revert_or_cherry_pick(argc, argv);
  }
  
  int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
  {
-       replay = 1;
+       no_replay = 0;
        action = CHERRY_PICK;
        return revert_or_cherry_pick(argc, argv);
  }