Merge branch 'jk/rev-parse-cleanup'
authorJunio C Hamano <gitster@pobox.com>
Tue, 21 Mar 2017 22:07:16 +0000 (15:07 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 21 Mar 2017 22:07:16 +0000 (15:07 -0700)
Code clean-up.

* jk/rev-parse-cleanup:
rev-parse: simplify parsing of ref options
rev-parse: add helper for parsing "--foo/--foo="
rev-parse: use skip_prefix when parsing options

1  2 
builtin/rev-parse.c
diff --combined builtin/rev-parse.c
index 2549643267440c5742690e3b808943de6fad19af,ed8819b4516413d1597e3a3673a8eec343c82903..1e5bdea0d5ba598b4191238fee761295bd8523ab
@@@ -12,7 -12,6 +12,7 @@@
  #include "diff.h"
  #include "revision.h"
  #include "split-index.h"
 +#include "submodule.h"
  
  #define DO_REVS               1
  #define DO_NOREV      2
@@@ -536,6 -535,34 +536,34 @@@ N_("git rev-parse --parseopt [<options>
     "\n"
     "Run \"git rev-parse --parseopt -h\" for more information on the first usage.");
  
+ /*
+  * Parse "opt" or "opt=<value>", setting value respectively to either
+  * NULL or the string after "=".
+  */
+ static int opt_with_value(const char *arg, const char *opt, const char **value)
+ {
+       if (skip_prefix(arg, opt, &arg)) {
+               if (!*arg) {
+                       *value = NULL;
+                       return 1;
+               }
+               if (*arg++ == '=') {
+                       *value = arg;
+                       return 1;
+               }
+       }
+       return 0;
+ }
+ static void handle_ref_opt(const char *pattern, const char *prefix)
+ {
+       if (pattern)
+               for_each_glob_ref_in(show_reference, pattern, prefix, NULL);
+       else
+               for_each_ref_in(prefix, show_reference, NULL);
+       clear_ref_exclusion(&ref_excludes);
+ }
  int cmd_rev_parse(int argc, const char **argv, const char *prefix)
  {
        int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
        unsigned int flags = 0;
        const char *name = NULL;
        struct object_context unused;
 +      struct strbuf buf = STRBUF_INIT;
  
        if (argc > 1 && !strcmp("--parseopt", argv[1]))
                return cmd_parseopt(argc - 1, argv + 1, prefix);
                if (!strcmp(arg, "--git-path")) {
                        if (!argv[i + 1])
                                die("--git-path requires an argument");
 -                      puts(git_path("%s", argv[i + 1]));
 +                      strbuf_reset(&buf);
 +                      puts(relative_path(git_path("%s", argv[i + 1]),
 +                                         prefix, &buf));
                        i++;
                        continue;
                }
                                flags |= GET_SHA1_QUIETLY;
                                continue;
                        }
-                       if (!strcmp(arg, "--short") ||
-                           starts_with(arg, "--short=")) {
+                       if (opt_with_value(arg, "--short", &arg)) {
                                filter &= ~(DO_FLAGS|DO_NOREV);
                                verify = 1;
                                abbrev = DEFAULT_ABBREV;
-                               if (!arg[7])
+                               if (!arg)
                                        continue;
-                               abbrev = strtoul(arg + 8, NULL, 10);
+                               abbrev = strtoul(arg, NULL, 10);
                                if (abbrev < MINIMUM_ABBREV)
                                        abbrev = MINIMUM_ABBREV;
                                else if (40 <= abbrev)
                                symbolic = SHOW_SYMBOLIC_FULL;
                                continue;
                        }
-                       if (starts_with(arg, "--abbrev-ref") &&
-                           (!arg[12] || arg[12] == '=')) {
+                       if (opt_with_value(arg, "--abbrev-ref", &arg)) {
                                abbrev_ref = 1;
                                abbrev_ref_strict = warn_ambiguous_refs;
-                               if (arg[12] == '=') {
-                                       if (!strcmp(arg + 13, "strict"))
+                               if (arg) {
+                                       if (!strcmp(arg, "strict"))
                                                abbrev_ref_strict = 1;
-                                       else if (!strcmp(arg + 13, "loose"))
+                                       else if (!strcmp(arg, "loose"))
                                                abbrev_ref_strict = 0;
                                        else
-                                               die("unknown mode for %s", arg);
+                                               die("unknown mode for --abbrev-ref: %s",
+                                                   arg);
                                }
                                continue;
                        }
                                for_each_ref(show_reference, NULL);
                                continue;
                        }
-                       if (starts_with(arg, "--disambiguate=")) {
-                               for_each_abbrev(arg + 15, show_abbrev, NULL);
+                       if (skip_prefix(arg, "--disambiguate=", &arg)) {
+                               for_each_abbrev(arg, show_abbrev, NULL);
                                continue;
                        }
                        if (!strcmp(arg, "--bisect")) {
                                for_each_ref_in("refs/bisect/good", anti_reference, NULL);
                                continue;
                        }
-                       if (starts_with(arg, "--branches=")) {
-                               for_each_glob_ref_in(show_reference, arg + 11,
-                                       "refs/heads/", NULL);
-                               clear_ref_exclusion(&ref_excludes);
-                               continue;
-                       }
-                       if (!strcmp(arg, "--branches")) {
-                               for_each_branch_ref(show_reference, NULL);
-                               clear_ref_exclusion(&ref_excludes);
-                               continue;
-                       }
-                       if (starts_with(arg, "--tags=")) {
-                               for_each_glob_ref_in(show_reference, arg + 7,
-                                       "refs/tags/", NULL);
-                               clear_ref_exclusion(&ref_excludes);
-                               continue;
-                       }
-                       if (!strcmp(arg, "--tags")) {
-                               for_each_tag_ref(show_reference, NULL);
-                               clear_ref_exclusion(&ref_excludes);
+                       if (opt_with_value(arg, "--branches", &arg)) {
+                               handle_ref_opt(arg, "refs/heads/");
                                continue;
                        }
-                       if (starts_with(arg, "--glob=")) {
-                               for_each_glob_ref(show_reference, arg + 7, NULL);
-                               clear_ref_exclusion(&ref_excludes);
+                       if (opt_with_value(arg, "--tags", &arg)) {
+                               handle_ref_opt(arg, "refs/tags/");
                                continue;
                        }
-                       if (starts_with(arg, "--remotes=")) {
-                               for_each_glob_ref_in(show_reference, arg + 10,
-                                       "refs/remotes/", NULL);
-                               clear_ref_exclusion(&ref_excludes);
+                       if (skip_prefix(arg, "--glob=", &arg)) {
+                               handle_ref_opt(arg, NULL);
                                continue;
                        }
-                       if (!strcmp(arg, "--remotes")) {
-                               for_each_remote_ref(show_reference, NULL);
-                               clear_ref_exclusion(&ref_excludes);
+                       if (opt_with_value(arg, "--remotes", &arg)) {
+                               handle_ref_opt(arg, "refs/remotes/");
                                continue;
                        }
-                       if (starts_with(arg, "--exclude=")) {
-                               add_ref_exclusion(&ref_excludes, arg + 10);
+                       if (skip_prefix(arg, "--exclude=", &arg)) {
+                               add_ref_exclusion(&ref_excludes, arg);
                                continue;
                        }
                        if (!strcmp(arg, "--show-toplevel")) {
                                        puts(work_tree);
                                continue;
                        }
 +                      if (!strcmp(arg, "--show-superproject-working-tree")) {
 +                              const char *superproject = get_superproject_working_tree();
 +                              if (superproject)
 +                                      puts(superproject);
 +                              continue;
 +                      }
                        if (!strcmp(arg, "--show-prefix")) {
                                if (prefix)
                                        puts(prefix);
                                putchar('\n');
                                continue;
                        }
 -                      if (!strcmp(arg, "--git-dir")) {
 +                      if (!strcmp(arg, "--git-dir") ||
 +                          !strcmp(arg, "--absolute-git-dir")) {
                                const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
                                char *cwd;
                                int len;
 -                              if (gitdir) {
 -                                      puts(gitdir);
 -                                      continue;
 -                              }
 -                              if (!prefix) {
 -                                      puts(".git");
 -                                      continue;
 +                              if (arg[2] == 'g') {    /* --git-dir */
 +                                      if (gitdir) {
 +                                              puts(gitdir);
 +                                              continue;
 +                                      }
 +                                      if (!prefix) {
 +                                              puts(".git");
 +                                              continue;
 +                                      }
 +                              } else {                /* --absolute-git-dir */
 +                                      if (!gitdir && !prefix)
 +                                              gitdir = ".git";
 +                                      if (gitdir) {
 +                                              puts(real_path(gitdir));
 +                                              continue;
 +                                      }
                                }
                                cwd = xgetcwd();
                                len = strlen(cwd);
                                continue;
                        }
                        if (!strcmp(arg, "--git-common-dir")) {
 -                              const char *pfx = prefix ? prefix : "";
 -                              puts(prefix_filename(pfx, strlen(pfx), get_git_common_dir()));
 +                              strbuf_reset(&buf);
 +                              puts(relative_path(get_git_common_dir(),
 +                                                 prefix, &buf));
                                continue;
                        }
                        if (!strcmp(arg, "--is-inside-git-dir")) {
                                        die(_("Could not read the index"));
                                if (the_index.split_index) {
                                        const unsigned char *sha1 = the_index.split_index->base_sha1;
 -                                      puts(git_path("sharedindex.%s", sha1_to_hex(sha1)));
 +                                      const char *path = git_path("sharedindex.%s", sha1_to_hex(sha1));
 +                                      strbuf_reset(&buf);
 +                                      puts(relative_path(path, prefix, &buf));
                                }
                                continue;
                        }
-                       if (starts_with(arg, "--since=")) {
-                               show_datestring("--max-age=", arg+8);
+                       if (skip_prefix(arg, "--since=", &arg)) {
+                               show_datestring("--max-age=", arg);
                                continue;
                        }
-                       if (starts_with(arg, "--after=")) {
-                               show_datestring("--max-age=", arg+8);
+                       if (skip_prefix(arg, "--after=", &arg)) {
+                               show_datestring("--max-age=", arg);
                                continue;
                        }
-                       if (starts_with(arg, "--before=")) {
-                               show_datestring("--min-age=", arg+9);
+                       if (skip_prefix(arg, "--before=", &arg)) {
+                               show_datestring("--min-age=", arg);
                                continue;
                        }
-                       if (starts_with(arg, "--until=")) {
-                               show_datestring("--min-age=", arg+8);
+                       if (skip_prefix(arg, "--until=", &arg)) {
+                               show_datestring("--min-age=", arg);
                                continue;
                        }
                        if (show_flag(arg) && verify)
                        continue;
                verify_filename(prefix, arg, 1);
        }
 +      strbuf_release(&buf);
        if (verify) {
                if (revs_count == 1) {
                        show_rev(type, sha1, name);