Merge branch 'js/difftool-no-index'
authorJunio C Hamano <gitster@pobox.com>
Thu, 25 Apr 2019 07:41:14 +0000 (16:41 +0900)
committerJunio C Hamano <gitster@pobox.com>
Thu, 25 Apr 2019 07:41:14 +0000 (16:41 +0900)
"git difftool" can now run outside a repository.

* js/difftool-no-index:
difftool: allow running outside Git worktrees with --no-index
parse-options: make OPT_ARGUMENT() more useful
difftool: remove obsolete (and misleading) comment

1  2 
git.c
parse-options.c
parse-options.h
diff --combined git.c
index 1c4fa3e3efdb6a086cb696f01bf5844a7d6aae91,46365ed86a7376d9ca7a4244bbb64dfc86336585..50da125c60a317d820cec18767ef1fc88efd56bf
--- 1/git.c
--- 2/git.c
+++ b/git.c
@@@ -62,13 -62,6 +62,13 @@@ static int list_cmds(const char *spec
  {
        struct string_list list = STRING_LIST_INIT_DUP;
        int i;
 +      int nongit;
 +
 +      /*
 +      * Set up the repository so we can pick up any repo-level config (like
 +      * completion.commands).
 +      */
 +      setup_git_directory_gently(&nongit);
  
        while (*spec) {
                const char *sep = strchrnul(spec, ',');
@@@ -498,7 -491,7 +498,7 @@@ static struct cmd_struct commands[] = 
        { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
        { "diff-index", cmd_diff_index, RUN_SETUP | NO_PARSEOPT },
        { "diff-tree", cmd_diff_tree, RUN_SETUP | NO_PARSEOPT },
-       { "difftool", cmd_difftool, RUN_SETUP | NEED_WORK_TREE },
+       { "difftool", cmd_difftool, RUN_SETUP_GENTLY },
        { "fast-export", cmd_fast_export, RUN_SETUP },
        { "fetch", cmd_fetch, RUN_SETUP },
        { "fetch-pack", cmd_fetch_pack, RUN_SETUP | NO_PARSEOPT },
        { "show-index", cmd_show_index },
        { "show-ref", cmd_show_ref, RUN_SETUP },
        { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
 +      /*
 +       * NEEDSWORK: Until the builtin stash is thoroughly robust and no
 +       * longer needs redirection to the stash shell script this is kept as
 +       * is, then should be changed to RUN_SETUP | NEED_WORK_TREE
 +       */
 +      { "stash", cmd_stash },
        { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
        { "stripspace", cmd_stripspace },
        { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT },
diff --combined parse-options.c
index bf2037f6e1cc307ba04d817620b534697c3609c9,1d57802da0e5da70cf00c2cf55b9f3945f44fe53..cb24f1aa8ae980a366f6f700db15b68064e1f926
@@@ -6,8 -6,6 +6,8 @@@
  #include "color.h"
  #include "utf8.h"
  
 +static int disallow_abbreviated_options;
 +
  #define OPT_SHORT 1
  #define OPT_UNSET 2
  
@@@ -288,6 -286,8 +288,8 @@@ again
                                             optname(options, flags));
                        if (*rest)
                                continue;
+                       if (options->value)
+                               *(int *)options->value = options->defval;
                        p->out[p->cpidx++] = arg - 2;
                        return PARSE_OPT_DONE;
                }
@@@ -346,10 -346,6 +348,10 @@@ is_abbreviated
                return get_value(p, options, all_opts, flags ^ opt_flags);
        }
  
 +      if (disallow_abbreviated_options && (ambiguous_option || abbrev_option))
 +              die("disallowed abbreviated or ambiguous option '%.*s'",
 +                  (int)(arg_end - arg), arg);
 +
        if (ambiguous_option) {
                error(_("ambiguous option: %s "
                        "(could be --%s%s or --%s%s)"),
@@@ -529,7 -525,8 +531,7 @@@ static void show_negated_gitcomp(const 
        }
  }
  
 -static int show_gitcomp(struct parse_opt_ctx_t *ctx,
 -                      const struct option *opts)
 +static int show_gitcomp(const struct option *opts)
  {
        const struct option *original_opts = opts;
        int nr_noopts = 0;
@@@ -608,7 -605,7 +610,7 @@@ int parse_options_step(struct parse_opt
  
                /* lone --git-completion-helper is asked by git-completion.bash */
                if (ctx->total == 1 && !strcmp(arg + 1, "-git-completion-helper"))
 -                      return show_gitcomp(ctx, options);
 +                      return show_gitcomp(options);
  
                if (arg[1] != '-') {
                        ctx->opt = arg + 1;
@@@ -713,9 -710,6 +715,9 @@@ int parse_options(int argc, const char 
  {
        struct parse_opt_ctx_t ctx;
  
 +      disallow_abbreviated_options =
 +              git_env_bool("GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS", 0);
 +
        parse_options_start(&ctx, argc, argv, prefix, options, flags);
        switch (parse_options_step(&ctx, options, usagestr)) {
        case PARSE_OPT_HELP:
diff --combined parse-options.h
index 0f7378706610bc9cf394d012e5cd02ef272b5ef4,c3d45ba1ac1cefb6c2a7877d02e753a0c4c3ea4b..cc9230adacb61f2a5066ac094c66bdfd18534354
@@@ -136,12 -136,10 +136,12 @@@ struct option 
  #define OPT_BOOL_F(s, l, v, h, f)   OPT_SET_INT_F(s, l, v, h, 1, f)
  #define OPT_CALLBACK_F(s, l, v, a, h, f, cb)                  \
        { OPTION_CALLBACK, (s), (l), (v), (a), (h), (f), (cb) }
 +#define OPT_STRING_F(s, l, v, a, h, f)   { OPTION_STRING,  (s), (l), (v), (a), (h), (f) }
 +#define OPT_INTEGER_F(s, l, v, h, f)     { OPTION_INTEGER, (s), (l), (v), N_("n"), (h), (f) }
  
  #define OPT_END()                   { OPTION_END }
- #define OPT_ARGUMENT(l, h)          { OPTION_ARGUMENT, 0, (l), NULL, NULL, \
-                                     (h), PARSE_OPT_NOARG}
+ #define OPT_ARGUMENT(l, v, h)       { OPTION_ARGUMENT, 0, (l), (v), NULL, \
+                                     (h), PARSE_OPT_NOARG, NULL, 1 }
  #define OPT_GROUP(h)                { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
  #define OPT_BIT(s, l, v, h, b)      OPT_BIT_F(s, l, v, h, b, 0)
  #define OPT_BITOP(s, l, v, h, set, clear) { OPTION_BITOP, (s), (l), (v), NULL, (h), \
                                      (h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1}
  #define OPT_CMDMODE(s, l, v, h, i)  { OPTION_CMDMODE, (s), (l), (v), NULL, \
                                      (h), PARSE_OPT_NOARG|PARSE_OPT_NONEG, NULL, (i) }
 -#define OPT_INTEGER(s, l, v, h)     { OPTION_INTEGER, (s), (l), (v), N_("n"), (h) }
 +#define OPT_INTEGER(s, l, v, h)     OPT_INTEGER_F(s, l, v, h, 0)
  #define OPT_MAGNITUDE(s, l, v, h)   { OPTION_MAGNITUDE, (s), (l), (v), \
                                      N_("n"), (h), PARSE_OPT_NONEG }
 -#define OPT_STRING(s, l, v, a, h)   { OPTION_STRING,  (s), (l), (v), (a), (h) }
 +#define OPT_STRING(s, l, v, a, h)   OPT_STRING_F(s, l, v, a, h, 0)
  #define OPT_STRING_LIST(s, l, v, a, h) \
                                    { OPTION_CALLBACK, (s), (l), (v), (a), \
                                      (h), 0, &parse_opt_string_list }
@@@ -224,17 -222,6 +224,17 @@@ const char *optname(const struct optio
                BUG("option callback does not expect an argument"); \
  } while (0)
  
 +/*
 + * Similar to the assertions above, but checks that "arg" is always non-NULL.
 + * This assertion also implies BUG_ON_OPT_NEG(), letting you declare both
 + * assertions in a single line.
 + */
 +#define BUG_ON_OPT_NEG_NOARG(unset, arg) do { \
 +      BUG_ON_OPT_NEG(unset); \
 +      if(!(arg)) \
 +              BUG("option callback expects an argument"); \
 +} while(0)
 +
  /*----- incremental advanced APIs -----*/
  
  enum parse_opt_result {