Merge branch 'jc/maint-pathspec-stdin-and-cmdline'
authorJunio C Hamano <gitster@pobox.com>
Fri, 20 May 2011 03:37:18 +0000 (20:37 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 20 May 2011 03:37:18 +0000 (20:37 -0700)
* jc/maint-pathspec-stdin-and-cmdline:
setup_revisions(): take pathspec from command line and --stdin correctly

Conflicts:
revision.c

1  2 
revision.c
diff --combined revision.c
index a7cf79bf2ed3f348f211878005899bebd96629f2,707a703a09d6c7ffc1adfcd89da83d5b97da397f..cf0b001570838af00b79b5c305dc9e5da65d5653
@@@ -955,8 -955,6 +955,8 @@@ void init_revisions(struct rev_info *re
                revs->diffopt.prefix = prefix;
                revs->diffopt.prefix_length = strlen(prefix);
        }
 +
 +      revs->notes_opt.use_default_notes = -1;
  }
  
  static void add_pending_commit_list(struct rev_info *revs,
@@@ -1098,35 -1096,34 +1098,34 @@@ int handle_revision_arg(const char *arg
        return 0;
  }
  
- static void read_pathspec_from_stdin(struct rev_info *revs, struct strbuf *sb, const char ***prune_data)
- {
-       const char **prune = *prune_data;
-       int prune_nr;
      int prune_alloc;
+ struct cmdline_pathspec {
+       int alloc;
+       int nr;
+       const char **path;
};
  
-       /* count existing ones */
-       if (!prune)
-               prune_nr = 0;
-       else
-               for (prune_nr = 0; prune[prune_nr]; prune_nr++)
-                       ;
-       prune_alloc = prune_nr; /* not really, but we do not know */
+ static void append_prune_data(struct cmdline_pathspec *prune, const char **av)
+ {
+       while (*av) {
+               ALLOC_GROW(prune->path, prune->nr+1, prune->alloc);
+               prune->path[prune->nr++] = *(av++);
+       }
+ }
  
+ static void read_pathspec_from_stdin(struct rev_info *revs, struct strbuf *sb,
+                                    struct cmdline_pathspec *prune)
+ {
        while (strbuf_getwholeline(sb, stdin, '\n') != EOF) {
                int len = sb->len;
                if (len && sb->buf[len - 1] == '\n')
                        sb->buf[--len] = '\0';
-               ALLOC_GROW(prune, prune_nr+1, prune_alloc);
-               prune[prune_nr++] = xstrdup(sb->buf);
+               ALLOC_GROW(prune->path, prune->nr+1, prune->alloc);
+               prune->path[prune->nr++] = xstrdup(sb->buf);
        }
-       if (prune) {
-               ALLOC_GROW(prune, prune_nr+1, prune_alloc);
-               prune[prune_nr] = NULL;
-       }
-       *prune_data = prune;
  }
  
- static void read_revisions_from_stdin(struct rev_info *revs, const char ***prune)
+ static void read_revisions_from_stdin(struct rev_info *revs,
+                                     struct cmdline_pathspec *prune)
  {
        struct strbuf sb;
        int seen_dashdash = 0;
@@@ -1180,9 -1177,7 +1179,9 @@@ static int handle_revision_opt(struct r
            !strcmp(arg, "--tags") || !strcmp(arg, "--remotes") ||
            !strcmp(arg, "--reflog") || !strcmp(arg, "--not") ||
            !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") ||
 -          !strcmp(arg, "--bisect"))
 +          !strcmp(arg, "--bisect") || !prefixcmp(arg, "--glob=") ||
 +          !prefixcmp(arg, "--branches=") || !prefixcmp(arg, "--tags=") ||
 +          !prefixcmp(arg, "--remotes="))
        {
                unkv[(*unkc)++] = arg;
                return 1;
                revs->verbose_header = 1;
                revs->pretty_given = 1;
                get_commit_format(arg+9, revs);
 -      } else if (!strcmp(arg, "--show-notes")) {
 +      } else if (!strcmp(arg, "--show-notes") || !strcmp(arg, "--notes")) {
                revs->show_notes = 1;
                revs->show_notes_given = 1;
 -      } else if (!prefixcmp(arg, "--show-notes=")) {
 +              revs->notes_opt.use_default_notes = 1;
 +      } else if (!prefixcmp(arg, "--show-notes=") ||
 +                 !prefixcmp(arg, "--notes=")) {
                struct strbuf buf = STRBUF_INIT;
                revs->show_notes = 1;
                revs->show_notes_given = 1;
 -              if (!revs->notes_opt.extra_notes_refs)
 -                      revs->notes_opt.extra_notes_refs = xcalloc(1, sizeof(struct string_list));
 -              if (!prefixcmp(arg+13, "refs/"))
 -                      /* happy */;
 -              else if (!prefixcmp(arg+13, "notes/"))
 -                      strbuf_addstr(&buf, "refs/");
 +              if (!prefixcmp(arg, "--show-notes")) {
 +                      if (revs->notes_opt.use_default_notes < 0)
 +                              revs->notes_opt.use_default_notes = 1;
 +                      strbuf_addstr(&buf, arg+13);
 +              }
                else
 -                      strbuf_addstr(&buf, "refs/notes/");
 -              strbuf_addstr(&buf, arg+13);
 -              string_list_append(revs->notes_opt.extra_notes_refs,
 +                      strbuf_addstr(&buf, arg+8);
 +              expand_notes_ref(&buf);
 +              string_list_append(&revs->notes_opt.extra_notes_refs,
                                   strbuf_detach(&buf, NULL));
        } else if (!strcmp(arg, "--no-notes")) {
                revs->show_notes = 0;
                revs->show_notes_given = 1;
 +              revs->notes_opt.use_default_notes = -1;
 +              /* we have been strdup'ing ourselves, so trick
 +               * string_list into free()ing strings */
 +              revs->notes_opt.extra_notes_refs.strdup_strings = 1;
 +              string_list_clear(&revs->notes_opt.extra_notes_refs, 0);
 +              revs->notes_opt.extra_notes_refs.strdup_strings = 0;
        } else if (!strcmp(arg, "--standard-notes")) {
                revs->show_notes_given = 1;
 -              revs->notes_opt.suppress_default_notes = 0;
 +              revs->notes_opt.use_default_notes = 1;
        } else if (!strcmp(arg, "--no-standard-notes")) {
 -              revs->notes_opt.suppress_default_notes = 1;
 +              revs->notes_opt.use_default_notes = 0;
        } else if (!strcmp(arg, "--oneline")) {
                revs->verbose_header = 1;
                get_commit_format("oneline", revs);
@@@ -1509,97 -1497,6 +1508,69 @@@ static int for_each_good_bisect_ref(con
        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)
- {
-       const char **prune = *prune_data;
-       int prune_nr;
-       int prune_alloc;
-       if (!prune) {
-               *prune_data = av;
-               return;
-       }
-       /* count existing ones */
-       for (prune_nr = 0; prune[prune_nr]; prune_nr++)
-               ;
-       prune_alloc = prune_nr; /* not really, but we do not know */
-       while (*av) {
-               ALLOC_GROW(prune, prune_nr+1, prune_alloc);
-               prune[prune_nr++] = *av;
-               av++;
-       }
-       if (prune) {
-               ALLOC_GROW(prune, prune_nr+1, prune_alloc);
-               prune[prune_nr] = NULL;
-       }
-       *prune_data = prune;
- }
 +static int handle_revision_pseudo_opt(const char *submodule,
 +                              struct rev_info *revs,
 +                              int argc, const char **argv, int *flags)
 +{
 +      const char *arg = argv[0];
 +      const char *optarg;
 +      int argcount;
 +
 +      /*
 +       * NOTE!
 +       *
 +       * Commands like "git shortlog" will not accept the options below
 +       * unless parse_revision_opt queues them (as opposed to erroring
 +       * out).
 +       *
 +       * When implementing your new pseudo-option, remember to
 +       * register it in the list at the top of handle_revision_opt.
 +       */
 +      if (!strcmp(arg, "--all")) {
 +              handle_refs(submodule, revs, *flags, for_each_ref_submodule);
 +              handle_refs(submodule, revs, *flags, head_ref_submodule);
 +      } else if (!strcmp(arg, "--branches")) {
 +              handle_refs(submodule, revs, *flags, for_each_branch_ref_submodule);
 +      } else if (!strcmp(arg, "--bisect")) {
 +              handle_refs(submodule, revs, *flags, for_each_bad_bisect_ref);
 +              handle_refs(submodule, revs, *flags ^ UNINTERESTING, for_each_good_bisect_ref);
 +              revs->bisect = 1;
 +      } else if (!strcmp(arg, "--tags")) {
 +              handle_refs(submodule, revs, *flags, for_each_tag_ref_submodule);
 +      } else if (!strcmp(arg, "--remotes")) {
 +              handle_refs(submodule, revs, *flags, for_each_remote_ref_submodule);
 +      } else if ((argcount = parse_long_opt("glob", argv, &optarg))) {
 +              struct all_refs_cb cb;
 +              init_all_refs_cb(&cb, revs, *flags);
 +              for_each_glob_ref(handle_one_ref, optarg, &cb);
 +              return argcount;
 +      } else if (!prefixcmp(arg, "--branches=")) {
 +              struct all_refs_cb cb;
 +              init_all_refs_cb(&cb, revs, *flags);
 +              for_each_glob_ref_in(handle_one_ref, arg + 11, "refs/heads/", &cb);
 +      } else if (!prefixcmp(arg, "--tags=")) {
 +              struct all_refs_cb cb;
 +              init_all_refs_cb(&cb, revs, *flags);
 +              for_each_glob_ref_in(handle_one_ref, arg + 7, "refs/tags/", &cb);
 +      } else if (!prefixcmp(arg, "--remotes=")) {
 +              struct all_refs_cb cb;
 +              init_all_refs_cb(&cb, revs, *flags);
 +              for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb);
 +      } else if (!strcmp(arg, "--reflog")) {
 +              handle_reflog(revs, *flags);
 +      } else if (!strcmp(arg, "--not")) {
 +              *flags ^= UNINTERESTING;
 +      } else if (!strcmp(arg, "--no-walk")) {
 +              revs->no_walk = 1;
 +      } else if (!strcmp(arg, "--do-walk")) {
 +              revs->no_walk = 0;
 +      } else {
 +              return 0;
 +      }
 +
 +      return 1;
 +}
 +
  /*
   * Parse revision information, filling in the "rev_info" structure,
   * and removing the used arguments from the argument list.
  int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *opt)
  {
        int i, flags, left, seen_dashdash, read_from_stdin, got_rev_arg = 0;
-       const char **prune_data = NULL;
+       struct cmdline_pathspec prune_data;
        const char *submodule = NULL;
 -      const char *optarg;
 -      int argcount;
  
+       memset(&prune_data, 0, sizeof(prune_data));
        if (opt)
                submodule = opt->submodule;
  
                argv[i] = NULL;
                argc = i;
                if (argv[i + 1])
-                       prune_data = argv + i + 1;
+                       append_prune_data(&prune_data, argv + i + 1);
                seen_dashdash = 1;
                break;
        }
                if (*arg == '-') {
                        int opts;
  
 -                      if (!strcmp(arg, "--all")) {
 -                              handle_refs(submodule, revs, flags, for_each_ref_submodule);
 -                              handle_refs(submodule, revs, flags, head_ref_submodule);
 -                              continue;
 -                      }
 -                      if (!strcmp(arg, "--branches")) {
 -                              handle_refs(submodule, revs, flags, for_each_branch_ref_submodule);
 -                              continue;
 -                      }
 -                      if (!strcmp(arg, "--bisect")) {
 -                              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(submodule, revs, flags, for_each_tag_ref_submodule);
 -                              continue;
 -                      }
 -                      if (!strcmp(arg, "--remotes")) {
 -                              handle_refs(submodule, revs, flags, for_each_remote_ref_submodule);
 -                              continue;
 -                      }
 -                      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, optarg, &cb);
 -                              continue;
 -                      }
 -                      if (!prefixcmp(arg, "--branches=")) {
 -                              struct all_refs_cb cb;
 -                              init_all_refs_cb(&cb, revs, flags);
 -                              for_each_glob_ref_in(handle_one_ref, arg + 11, "refs/heads/", &cb);
 -                              continue;
 -                      }
 -                      if (!prefixcmp(arg, "--tags=")) {
 -                              struct all_refs_cb cb;
 -                              init_all_refs_cb(&cb, revs, flags);
 -                              for_each_glob_ref_in(handle_one_ref, arg + 7, "refs/tags/", &cb);
 -                              continue;
 -                      }
 -                      if (!prefixcmp(arg, "--remotes=")) {
 -                              struct all_refs_cb cb;
 -                              init_all_refs_cb(&cb, revs, flags);
 -                              for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb);
 -                              continue;
 -                      }
 -                      if (!strcmp(arg, "--reflog")) {
 -                              handle_reflog(revs, flags);
 -                              continue;
 -                      }
 -                      if (!strcmp(arg, "--not")) {
 -                              flags ^= UNINTERESTING;
 -                              continue;
 -                      }
 -                      if (!strcmp(arg, "--no-walk")) {
 -                              revs->no_walk = 1;
 -                              continue;
 -                      }
 -                      if (!strcmp(arg, "--do-walk")) {
 -                              revs->no_walk = 0;
 +                      opts = handle_revision_pseudo_opt(submodule,
 +                                              revs, argc - i, argv + i,
 +                                              &flags);
 +                      if (opts > 0) {
 +                              i += opts - 1;
                                continue;
                        }
 +
                        if (!strcmp(arg, "--stdin")) {
                                if (revs->disable_stdin) {
                                        argv[left++] = arg;
                        got_rev_arg = 1;
        }
  
-       if (prune_data)
-               init_pathspec(&revs->prune_data, get_pathspec(revs->prefix, prune_data));
+       if (prune_data.nr) {
+               ALLOC_GROW(prune_data.path, prune_data.nr+1, prune_data.alloc);
+               prune_data.path[prune_data.nr++] = NULL;
+               init_pathspec(&revs->prune_data,
+                             get_pathspec(revs->prefix, prune_data.path));
+       }
  
        if (revs->def == NULL)
                revs->def = opt ? opt->def : NULL;