Merge branch 'mm/shortopt-detached'
authorJunio C Hamano <gitster@pobox.com>
Sun, 22 Aug 2010 06:28:31 +0000 (23:28 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 22 Aug 2010 06:28:31 +0000 (23:28 -0700)
* mm/shortopt-detached:
log: parse separate option for --glob
log: parse separate options like git log --grep foo
diff: parse separate options --stat-width n, --stat-name-width n
diff: split off a function for --stat-* option parsing
diff: parse separate options like -S foo

Conflicts:
revision.c

1  2 
diff.c
diff.h
revision.c
t/t4202-log.sh
diff --combined diff.c
index 7a75bd74c9ab9c98da12f5511ff321645cfa883b,e98d59b80ca76f1bb5caa303c57f23e3dc2e3b07..6fb97d4623192167e9b9f83b02dfe9250f028c0a
--- 1/diff.c
--- 2/diff.c
+++ b/diff.c
@@@ -31,7 -31,6 +31,7 @@@ static const char *external_diff_cmd_cf
  int diff_auto_refresh_index = 1;
  static int diff_mnemonic_prefix;
  static int diff_no_prefix;
 +static struct diff_options default_diff_options;
  
  static char diff_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_RESET,
@@@ -108,9 -107,6 +108,9 @@@ int git_diff_ui_config(const char *var
        if (!strcmp(var, "diff.wordregex"))
                return git_config_string(&diff_word_regex_cfg, var, value);
  
 +      if (!strcmp(var, "diff.ignoresubmodules"))
 +              handle_ignore_submodules_arg(&default_diff_options, value);
 +
        return git_diff_basic_config(var, value, cb);
  }
  
@@@ -145,9 -141,6 +145,9 @@@ int git_diff_basic_config(const char *v
                return 0;
        }
  
 +      if (!prefixcmp(var, "submodule."))
 +              return parse_submodule_config_option(var, value);
 +
        return git_color_default_config(var, value, cb);
  }
  
@@@ -2711,16 -2704,10 +2711,16 @@@ static void diff_fill_sha1_info(struct 
  static void strip_prefix(int prefix_length, const char **namep, const char **otherp)
  {
        /* Strip the prefix but do not molest /dev/null and absolute paths */
 -      if (*namep && **namep != '/')
 +      if (*namep && **namep != '/') {
                *namep += prefix_length;
 -      if (*otherp && **otherp != '/')
 +              if (**namep == '/')
 +                      ++*namep;
 +      }
 +      if (*otherp && **otherp != '/') {
                *otherp += prefix_length;
 +              if (**otherp == '/')
 +                      ++*otherp;
 +      }
  }
  
  static void run_diff(struct diff_filepair *p, struct diff_options *o)
@@@ -2826,7 -2813,8 +2826,7 @@@ static void run_checkdiff(struct diff_f
  
  void diff_setup(struct diff_options *options)
  {
 -      memset(options, 0, sizeof(*options));
 -      memset(&diff_queued_diff, 0, sizeof(diff_queued_diff));
 +      memcpy(options, &default_diff_options, sizeof(*options));
  
        options->file = stdout;
  
@@@ -3002,9 -2990,100 +3002,100 @@@ static int opt_arg(const char *arg, in
  
  static int diff_scoreopt_parse(const char *opt);
  
+ static inline int short_opt(char opt, const char **argv,
+                           const char **optarg)
+ {
+       const char *arg = argv[0];
+       if (arg[0] != '-' || arg[1] != opt)
+               return 0;
+       if (arg[2] != '\0') {
+               *optarg = arg + 2;
+               return 1;
+       }
+       if (!argv[1])
+               die("Option '%c' requires a value", opt);
+       *optarg = argv[1];
+       return 2;
+ }
+ int parse_long_opt(const char *opt, const char **argv,
+                  const char **optarg)
+ {
+       const char *arg = argv[0];
+       if (arg[0] != '-' || arg[1] != '-')
+               return 0;
+       arg += strlen("--");
+       if (prefixcmp(arg, opt))
+               return 0;
+       arg += strlen(opt);
+       if (*arg == '=') { /* sticked form: --option=value */
+               *optarg = arg + 1;
+               return 1;
+       }
+       if (*arg != '\0')
+               return 0;
+       /* separate form: --option value */
+       if (!argv[1])
+               die("Option '--%s' requires a value", opt);
+       *optarg = argv[1];
+       return 2;
+ }
+ static int stat_opt(struct diff_options *options, const char **av)
+ {
+       const char *arg = av[0];
+       char *end;
+       int width = options->stat_width;
+       int name_width = options->stat_name_width;
+       int argcount = 1;
+       arg += strlen("--stat");
+       end = (char *)arg;
+       switch (*arg) {
+       case '-':
+               if (!prefixcmp(arg, "-width")) {
+                       arg += strlen("-width");
+                       if (*arg == '=')
+                               width = strtoul(arg + 1, &end, 10);
+                       else if (!*arg && !av[1])
+                               die("Option '--stat-width' requires a value");
+                       else if (!*arg) {
+                               width = strtoul(av[1], &end, 10);
+                               argcount = 2;
+                       }
+               } else if (!prefixcmp(arg, "-name-width")) {
+                       arg += strlen("-name-width");
+                       if (*arg == '=')
+                               name_width = strtoul(arg + 1, &end, 10);
+                       else if (!*arg && !av[1])
+                               die("Option '--stat-name-width' requires a value");
+                       else if (!*arg) {
+                               name_width = strtoul(av[1], &end, 10);
+                               argcount = 2;
+                       }
+               }
+               break;
+       case '=':
+               width = strtoul(arg+1, &end, 10);
+               if (*end == ',')
+                       name_width = strtoul(end+1, &end, 10);
+       }
+       /* Important! This checks all the error cases! */
+       if (*end)
+               return 0;
+       options->output_format |= DIFF_FORMAT_DIFFSTAT;
+       options->stat_name_width = name_width;
+       options->stat_width = width;
+       return argcount;
+ }
  int diff_opt_parse(struct diff_options *options, const char **av, int ac)
  {
        const char *arg = av[0];
+       const char *optarg;
+       int argcount;
  
        /* Output format options */
        if (!strcmp(arg, "-p") || !strcmp(arg, "-u") || !strcmp(arg, "--patch"))
                options->output_format |= DIFF_FORMAT_NAME_STATUS;
        else if (!strcmp(arg, "-s"))
                options->output_format |= DIFF_FORMAT_NO_OUTPUT;
-       else if (!prefixcmp(arg, "--stat")) {
-               char *end;
-               int width = options->stat_width;
-               int name_width = options->stat_name_width;
-               arg += 6;
-               end = (char *)arg;
-               switch (*arg) {
-               case '-':
-                       if (!prefixcmp(arg, "-width="))
-                               width = strtoul(arg + 7, &end, 10);
-                       else if (!prefixcmp(arg, "-name-width="))
-                               name_width = strtoul(arg + 12, &end, 10);
-                       break;
-               case '=':
-                       width = strtoul(arg+1, &end, 10);
-                       if (*end == ',')
-                               name_width = strtoul(end+1, &end, 10);
-               }
-               /* Important! This checks all the error cases! */
-               if (*end)
-                       return 0;
-               options->output_format |= DIFF_FORMAT_DIFFSTAT;
-               options->stat_name_width = name_width;
-               options->stat_width = width;
-       }
+       else if (!prefixcmp(arg, "--stat"))
+               /* --stat, --stat-width, or --stat-name-width */
+               return stat_opt(options, av);
  
        /* renames options */
        else if (!prefixcmp(arg, "-B")) {
                else
                        die("bad --word-diff argument: %s", type);
        }
-       else if (!prefixcmp(arg, "--word-diff-regex=")) {
+       else if ((argcount = parse_long_opt("word-diff-regex", av, &optarg))) {
                if (options->word_diff == DIFF_WORDS_NONE)
                        options->word_diff = DIFF_WORDS_PLAIN;
-               options->word_regex = arg + 18;
+               options->word_regex = optarg;
+               return argcount;
        }
        else if (!strcmp(arg, "--exit-code"))
                DIFF_OPT_SET(options, EXIT_WITH_STATUS);
                DIFF_OPT_SET(options, ALLOW_TEXTCONV);
        else if (!strcmp(arg, "--no-textconv"))
                DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
 -      else if (!strcmp(arg, "--ignore-submodules"))
 +      else if (!strcmp(arg, "--ignore-submodules")) {
 +              DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
                handle_ignore_submodules_arg(options, "all");
 -      else if (!prefixcmp(arg, "--ignore-submodules="))
 +      } else if (!prefixcmp(arg, "--ignore-submodules=")) {
 +              DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
                handle_ignore_submodules_arg(options, arg + 20);
 -      else if (!strcmp(arg, "--submodule"))
 +      else if (!strcmp(arg, "--submodule"))
                DIFF_OPT_SET(options, SUBMODULE_LOG);
        else if (!prefixcmp(arg, "--submodule=")) {
                if (!strcmp(arg + 12, "log"))
        /* misc options */
        else if (!strcmp(arg, "-z"))
                options->line_termination = 0;
-       else if (!prefixcmp(arg, "-l"))
-               options->rename_limit = strtoul(arg+2, NULL, 10);
-       else if (!prefixcmp(arg, "-S"))
-               options->pickaxe = arg + 2;
+       else if ((argcount = short_opt('l', av, &optarg))) {
+               options->rename_limit = strtoul(optarg, NULL, 10);
+               return argcount;
+       }
+       else if ((argcount = short_opt('S', av, &optarg))) {
+               options->pickaxe = optarg;
+               return argcount;
+       }
        else if (!strcmp(arg, "--pickaxe-all"))
                options->pickaxe_opts = DIFF_PICKAXE_ALL;
        else if (!strcmp(arg, "--pickaxe-regex"))
                options->pickaxe_opts = DIFF_PICKAXE_REGEX;
-       else if (!prefixcmp(arg, "-O"))
-               options->orderfile = arg + 2;
-       else if (!prefixcmp(arg, "--diff-filter="))
-               options->filter = arg + 14;
+       else if ((argcount = short_opt('O', av, &optarg))) {
+               options->orderfile = optarg;
+               return argcount;
+       }
+       else if ((argcount = parse_long_opt("diff-filter", av, &optarg))) {
+               options->filter = optarg;
+               return argcount;
+       }
        else if (!strcmp(arg, "--abbrev"))
                options->abbrev = DEFAULT_ABBREV;
        else if (!prefixcmp(arg, "--abbrev=")) {
                else if (40 < options->abbrev)
                        options->abbrev = 40;
        }
-       else if (!prefixcmp(arg, "--src-prefix="))
-               options->a_prefix = arg + 13;
-       else if (!prefixcmp(arg, "--dst-prefix="))
-               options->b_prefix = arg + 13;
+       else if ((argcount = parse_long_opt("src-prefix", av, &optarg))) {
+               options->a_prefix = optarg;
+               return argcount;
+       }
+       else if ((argcount = parse_long_opt("dst-prefix", av, &optarg))) {
+               options->b_prefix = optarg;
+               return argcount;
+       }
        else if (!strcmp(arg, "--no-prefix"))
                options->a_prefix = options->b_prefix = "";
        else if (opt_arg(arg, '\0', "inter-hunk-context",
                         &options->interhunkcontext))
                ;
-       else if (!prefixcmp(arg, "--output=")) {
-               options->file = fopen(arg + strlen("--output="), "w");
+       else if ((argcount = parse_long_opt("output", av, &optarg))) {
+               options->file = fopen(optarg, "w");
                if (!options->file)
                        die_errno("Could not open '%s'", arg + strlen("--output="));
                options->close_file = 1;
+               return argcount;
        } else
                return 0;
        return 1;
@@@ -4073,24 -4140,25 +4154,24 @@@ void diffcore_fix_diff_index(struct dif
  
  void diffcore_std(struct diff_options *options)
  {
 -      /* We never run this function more than one time, because the
 -       * rename/copy detection logic can only run once.
 -       */
 -      if (diff_queued_diff.run)
 -              return;
 -
        if (options->skip_stat_unmatch)
                diffcore_skip_stat_unmatch(options);
 -      if (options->break_opt != -1)
 -              diffcore_break(options->break_opt);
 -      if (options->detect_rename)
 -              diffcore_rename(options);
 -      if (options->break_opt != -1)
 -              diffcore_merge_broken();
 +      if (!options->found_follow) {
 +              /* See try_to_follow_renames() in tree-diff.c */
 +              if (options->break_opt != -1)
 +                      diffcore_break(options->break_opt);
 +              if (options->detect_rename)
 +                      diffcore_rename(options);
 +              if (options->break_opt != -1)
 +                      diffcore_merge_broken();
 +      }
        if (options->pickaxe)
                diffcore_pickaxe(options->pickaxe, options->pickaxe_opts);
        if (options->orderfile)
                diffcore_order(options->orderfile);
 -      diff_resolve_rename_copy();
 +      if (!options->found_follow)
 +              /* See try_to_follow_renames() in tree-diff.c */
 +              diff_resolve_rename_copy();
        diffcore_apply_filter(options->filter);
  
        if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
        else
                DIFF_OPT_CLR(options, HAS_CHANGES);
  
 -      diff_queued_diff.run = 1;
 +      options->found_follow = 0;
  }
  
  int diff_result_code(struct diff_options *opt, int status)
        return result;
  }
  
 +/*
 + * Shall changes to this submodule be ignored?
 + *
 + * Submodule changes can be configured to be ignored separately for each path,
 + * but that configuration can be overridden from the command line.
 + */
 +static int is_submodule_ignored(const char *path, struct diff_options *options)
 +{
 +      int ignored = 0;
 +      unsigned orig_flags = options->flags;
 +      if (!DIFF_OPT_TST(options, OVERRIDE_SUBMODULE_CONFIG))
 +              set_diffopt_flags_from_submodule_config(options, path);
 +      if (DIFF_OPT_TST(options, IGNORE_SUBMODULES))
 +              ignored = 1;
 +      options->flags = orig_flags;
 +      return ignored;
 +}
 +
  void diff_addremove(struct diff_options *options,
                    int addremove, unsigned mode,
                    const unsigned char *sha1,
  {
        struct diff_filespec *one, *two;
  
 -      if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(mode))
 +      if (S_ISGITLINK(mode) && is_submodule_ignored(concatpath, options))
                return;
  
        /* This may look odd, but it is a preparation for
@@@ -4188,8 -4238,8 +4269,8 @@@ void diff_change(struct diff_options *o
  {
        struct diff_filespec *one, *two;
  
 -      if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(old_mode)
 -                      && S_ISGITLINK(new_mode))
 +      if (S_ISGITLINK(old_mode) && S_ISGITLINK(new_mode) &&
 +          is_submodule_ignored(concatpath, options))
                return;
  
        if (DIFF_OPT_TST(options, REVERSE_DIFF)) {
diff --combined diff.h
index d43da9da95fae4dd13d3abbe738948708cf90939,2b94ad66d2fa9cd7105f505fd466ecab63401505..bf2f44d840735684c89f654ee6f3b3a935af2c55
--- 1/diff.h
--- 2/diff.h
+++ b/diff.h
@@@ -77,7 -77,6 +77,7 @@@ typedef struct strbuf *(*diff_prefix_fn
  #define DIFF_OPT_DIRTY_SUBMODULES    (1 << 24)
  #define DIFF_OPT_IGNORE_UNTRACKED_IN_SUBMODULES (1 << 25)
  #define DIFF_OPT_IGNORE_DIRTY_SUBMODULES (1 << 26)
 +#define DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG (1 << 27)
  
  #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)
  #define DIFF_OPT_SET(opts, flag)    ((opts)->flags |= DIFF_OPT_##flag)
@@@ -127,9 -126,6 +127,9 @@@ struct diff_options 
        /* this is set by diffcore for DIFF_FORMAT_PATCH */
        int found_changes;
  
 +      /* to support internal diff recursion by --follow hack*/
 +      int found_follow;
 +
        FILE *file;
        int close_file;
  
@@@ -218,6 -214,13 +218,13 @@@ extern void diff_unmerge(struct diff_op
  #define DIFF_SETUP_USE_CACHE          2
  #define DIFF_SETUP_USE_SIZE_CACHE     4
  
+ /*
+  * Poor man's alternative to parse-option, to allow both sticked form
+  * (--option=value) and separate form (--option value).
+  */
+ extern int parse_long_opt(const char *opt, const char **argv,
+                        const char **optarg);
  extern int git_diff_basic_config(const char *var, const char *value, void *cb);
  extern int git_diff_ui_config(const char *var, const char *value, void *cb);
  extern int diff_use_color_default;
diff --combined revision.c
index 5f2cf1e8431199207c9abc494c877ab695b1bb07,f241f341c77c63ca6342d31e56f432dac43fbb39..b1c18906badc5fc4ce3af48daa7c226365e3c08f
@@@ -820,12 -820,12 +820,12 @@@ static void init_all_refs_cb(struct all
        cb->all_flags = flags;
  }
  
 -static void handle_refs(struct rev_info *revs, unsigned flags,
 -              int (*for_each)(each_ref_fn, void *))
 +static void handle_refs(const char *submodule, struct rev_info *revs, unsigned flags,
 +              int (*for_each)(const char *, each_ref_fn, void *))
  {
        struct all_refs_cb cb;
        init_all_refs_cb(&cb, revs, flags);
 -      for_each(handle_one_ref, &cb);
 +      for_each(submodule, handle_one_ref, &cb);
  }
  
  static void handle_one_reflog_commit(unsigned char *sha1, void *cb_data)
@@@ -1148,6 -1148,8 +1148,8 @@@ static int handle_revision_opt(struct r
                               int *unkc, const char **unkv)
  {
        const char *arg = argv[0];
+       const char *optarg;
+       int argcount;
  
        /* pseudo revision arguments */
        if (!strcmp(arg, "--all") || !strcmp(arg, "--branches") ||
                return 1;
        }
  
-       if (!prefixcmp(arg, "--max-count=")) {
-               revs->max_count = atoi(arg + 12);
+       if ((argcount = parse_long_opt("max-count", argv, &optarg))) {
+               revs->max_count = atoi(optarg);
                revs->no_walk = 0;
-       } else if (!prefixcmp(arg, "--skip=")) {
-               revs->skip_count = atoi(arg + 7);
+               return argcount;
+       } else if ((argcount = parse_long_opt("skip", argv, &optarg))) {
+               revs->skip_count = atoi(optarg);
+               return argcount;
        } else if ((*arg == '-') && isdigit(arg[1])) {
        /* accept -<digit>, like traditional "head" */
                revs->max_count = atoi(arg + 1);
        } else if (!prefixcmp(arg, "-n")) {
                revs->max_count = atoi(arg + 2);
                revs->no_walk = 0;
-       } else if (!prefixcmp(arg, "--max-age=")) {
-               revs->max_age = atoi(arg + 10);
-       } else if (!prefixcmp(arg, "--since=")) {
-               revs->max_age = approxidate(arg + 8);
-       } else if (!prefixcmp(arg, "--after=")) {
-               revs->max_age = approxidate(arg + 8);
-       } else if (!prefixcmp(arg, "--min-age=")) {
-               revs->min_age = atoi(arg + 10);
-       } else if (!prefixcmp(arg, "--before=")) {
-               revs->min_age = approxidate(arg + 9);
-       } else if (!prefixcmp(arg, "--until=")) {
-               revs->min_age = approxidate(arg + 8);
+       } else if ((argcount = parse_long_opt("max-age", argv, &optarg))) {
+               revs->max_age = atoi(optarg);
+               return argcount;
+       } else if ((argcount = parse_long_opt("since", argv, &optarg))) {
+               revs->max_age = approxidate(optarg);
+               return argcount;
+       } else if ((argcount = parse_long_opt("after", argv, &optarg))) {
+               revs->max_age = approxidate(optarg);
+               return argcount;
+       } else if ((argcount = parse_long_opt("min-age", argv, &optarg))) {
+               revs->min_age = atoi(optarg);
+               return argcount;
+       } else if ((argcount = parse_long_opt("before", argv, &optarg))) {
+               revs->min_age = approxidate(optarg);
+               return argcount;
+       } else if ((argcount = parse_long_opt("until", argv, &optarg))) {
+               revs->min_age = approxidate(optarg);
+               return argcount;
        } else if (!strcmp(arg, "--first-parent")) {
                revs->first_parent_only = 1;
        } else if (!strcmp(arg, "--ancestry-path")) {
                revs->pretty_given = 1;
                get_commit_format(arg+8, revs);
        } else if (!prefixcmp(arg, "--pretty=") || !prefixcmp(arg, "--format=")) {
+               /*
+                * Detached form ("--pretty X" as opposed to "--pretty=X")
+                * not allowed, since the argument is optional.
+                */
                revs->verbose_header = 1;
                revs->pretty_given = 1;
                get_commit_format(arg+9, revs);
        } else if (!strcmp(arg, "--relative-date")) {
                revs->date_mode = DATE_RELATIVE;
                revs->date_mode_explicit = 1;
-       } else if (!strncmp(arg, "--date=", 7)) {
-               revs->date_mode = parse_date_format(arg + 7);
+       } else if ((argcount = parse_long_opt("date", argv, &optarg))) {
+               revs->date_mode = parse_date_format(optarg);
                revs->date_mode_explicit = 1;
+               return argcount;
        } else if (!strcmp(arg, "--log-size")) {
                revs->show_log_size = 1;
        }
        /*
         * Grepping the commit log
         */
-       else if (!prefixcmp(arg, "--author=")) {
-               add_header_grep(revs, GREP_HEADER_AUTHOR, arg+9);
-       } else if (!prefixcmp(arg, "--committer=")) {
-               add_header_grep(revs, GREP_HEADER_COMMITTER, arg+12);
-       } else if (!prefixcmp(arg, "--grep=")) {
-               add_message_grep(revs, arg+7);
+       else if ((argcount = parse_long_opt("author", argv, &optarg))) {
+               add_header_grep(revs, GREP_HEADER_AUTHOR, optarg);
+               return argcount;
+       } else if ((argcount = parse_long_opt("committer", argv, &optarg))) {
+               add_header_grep(revs, GREP_HEADER_COMMITTER, optarg);
+               return argcount;
+       } else if ((argcount = parse_long_opt("grep", argv, &optarg))) {
+               add_message_grep(revs, optarg);
+               return argcount;
        } else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
                revs->grep_filter.regflags |= REG_EXTENDED;
        } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
                revs->grep_filter.fixed = 1;
        } else if (!strcmp(arg, "--all-match")) {
                revs->grep_filter.all_match = 1;
-       } else if (!prefixcmp(arg, "--encoding=")) {
-               arg += 11;
-               if (strcmp(arg, "none"))
-                       git_log_output_encoding = xstrdup(arg);
+       } else if ((argcount = parse_long_opt("encoding", argv, &optarg))) {
+               if (strcmp(optarg, "none"))
+                       git_log_output_encoding = xstrdup(optarg);
                else
                        git_log_output_encoding = "";
+               return argcount;
        } else if (!strcmp(arg, "--reverse")) {
                revs->reverse ^= 1;
        } else if (!strcmp(arg, "--children")) {
@@@ -1417,14 -1435,14 +1435,14 @@@ void parse_revision_opt(struct rev_inf
        ctx->argc -= n;
  }
  
 -static int for_each_bad_bisect_ref(each_ref_fn fn, void *cb_data)
 +static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)
  {
 -      return for_each_ref_in("refs/bisect/bad", fn, cb_data);
 +      return for_each_ref_in_submodule(submodule, "refs/bisect/bad", fn, cb_data);
  }
  
 -static int for_each_good_bisect_ref(each_ref_fn fn, void *cb_data)
 +static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)
  {
 -      return for_each_ref_in("refs/bisect/good", fn, cb_data);
 +      return for_each_ref_in_submodule(submodule, "refs/bisect/good", fn, cb_data);
  }
  
  static void append_prune_data(const char ***prune_data, const char **av)
@@@ -1466,11 -1484,9 +1484,13 @@@ int setup_revisions(int argc, const cha
  {
        int i, flags, left, seen_dashdash, read_from_stdin, got_rev_arg = 0;
        const char **prune_data = NULL;
 +      const char *submodule = NULL;
+       const char *optarg;
+       int argcount;
  
 +      if (opt)
 +              submodule = opt->submodule;
 +
        /* First, search for "--" */
        seen_dashdash = 0;
        for (i = 1; i < argc; i++) {
                        int opts;
  
                        if (!strcmp(arg, "--all")) {
 -                              handle_refs(revs, flags, for_each_ref);
 -                              handle_refs(revs, flags, head_ref);
 +                              handle_refs(submodule, revs, flags, for_each_ref_submodule);
 +                              handle_refs(submodule, revs, flags, head_ref_submodule);
                                continue;
                        }
                        if (!strcmp(arg, "--branches")) {
 -                              handle_refs(revs, flags, for_each_branch_ref);
 +                              handle_refs(submodule, revs, flags, for_each_branch_ref_submodule);
                                continue;
                        }
                        if (!strcmp(arg, "--bisect")) {
 -                              handle_refs(revs, flags, for_each_bad_bisect_ref);
 -                              handle_refs(revs, flags ^ UNINTERESTING, for_each_good_bisect_ref);
 +                              handle_refs(submodule, revs, flags, for_each_bad_bisect_ref);
 +                              handle_refs(submodule, revs, flags ^ UNINTERESTING, for_each_good_bisect_ref);
                                revs->bisect = 1;
                                continue;
                        }
                        if (!strcmp(arg, "--tags")) {
 -                              handle_refs(revs, flags, for_each_tag_ref);
 +                              handle_refs(submodule, revs, flags, for_each_tag_ref_submodule);
                                continue;
                        }
                        if (!strcmp(arg, "--remotes")) {
 -                              handle_refs(revs, flags, for_each_remote_ref);
 +                              handle_refs(submodule, revs, flags, for_each_remote_ref_submodule);
                                continue;
                        }
-                       if (!prefixcmp(arg, "--glob=")) {
+                       if ((argcount = parse_long_opt("glob", argv + i, &optarg))) {
                                struct all_refs_cb cb;
+                               i += argcount - 1;
                                init_all_refs_cb(&cb, revs, flags);
-                               for_each_glob_ref(handle_one_ref, arg + 7, &cb);
+                               for_each_glob_ref(handle_one_ref, optarg, &cb);
                                continue;
                        }
                        if (!prefixcmp(arg, "--branches=")) {
diff --combined t/t4202-log.sh
index ead204e5cb77804ee1b54cc1b2f31d35312fa758,95ac3f8cc813aa88d82db748af94f61150472261..2e513569477bb5efc389a2088a4d896620e50b8f
@@@ -100,13 -100,11 +100,11 @@@ test_expect_success 'oneline' 
  
  test_expect_success 'diff-filter=A' '
  
-       actual=$(git log --pretty="format:%s" --diff-filter=A HEAD) &&
-       expect=$(echo fifth ; echo fourth ; echo third ; echo initial) &&
-       test "$actual" = "$expect" || {
-               echo Oops
-               echo "Actual: $actual"
-               false
-       }
+       git log --pretty="format:%s" --diff-filter=A HEAD > actual &&
+       git log --pretty="format:%s" --diff-filter A HEAD > actual-separate &&
+       printf "fifth\nfourth\nthird\ninitial" > expect &&
+       test_cmp expect actual &&
+       test_cmp expect actual-separate
  
  '
  
@@@ -203,6 -201,13 +201,13 @@@ test_expect_success 'log --grep' 
        test_cmp expect actual
  '
  
+ test_expect_success 'log --grep option parsing' '
+       echo second >expect &&
+       git log -1 --pretty="tformat:%s" --grep sec >actual &&
+       test_cmp expect actual &&
+       test_must_fail git log -1 --pretty="tformat:%s" --grep
+ '
  test_expect_success 'log -i --grep' '
        echo Second >expect &&
        git log -1 --pretty="tformat:%s" -i --grep=sec >actual &&
@@@ -436,17 -441,5 +441,17 @@@ test_expect_success 'log.decorate confi
  
  '
  
 -test_done
 +test_expect_success 'show added path under "--follow -M"' '
 +      # This tests for a regression introduced in v1.7.2-rc0~103^2~2
 +      test_create_repo regression &&
 +      (
 +              cd regression &&
 +              test_commit needs-another-commit &&
 +              test_commit foo.bar &&
 +              git log -M --follow -p foo.bar.t &&
 +              git log -M --follow --stat foo.bar.t &&
 +              git log -M --follow --name-only foo.bar.t
 +      )
 +'
  
 +test_done