pull: add pull.ff configuration
[gitweb.git] / builtin / rev-parse.c
index a8c5043dedd785b8fc43c0921edd01e2adac65e1..c4b768ffda4cb91dbe01012ccb8eb2475435a77e 100644 (file)
@@ -44,10 +44,15 @@ static int is_rev_argument(const char *arg)
                "--branches=",
                "--branches",
                "--header",
+               "--ignore-missing",
                "--max-age=",
                "--max-count=",
                "--min-age=",
                "--no-merges",
+               "--min-parents=",
+               "--no-min-parents",
+               "--max-parents=",
+               "--no-max-parents",
                "--objects",
                "--objects-edge",
                "--parents",
@@ -190,6 +195,12 @@ static int anti_reference(const char *refname, const unsigned char *sha1, int fl
        return 0;
 }
 
+static int show_abbrev(const unsigned char *sha1, void *cb_data)
+{
+       show_rev(NORMAL, sha1, NULL);
+       return 0;
+}
+
 static void show_datestring(const char *flag, const char *datestr)
 {
        static char buffer[100];
@@ -201,11 +212,17 @@ static void show_datestring(const char *flag, const char *datestr)
        show(buffer);
 }
 
-static int show_file(const char *arg)
+static int show_file(const char *arg, int output_prefix)
 {
        show_default();
        if ((filter & (DO_NONFLAGS|DO_NOREV)) == (DO_NONFLAGS|DO_NOREV)) {
-               show(arg);
+               if (output_prefix) {
+                       const char *prefix = startup_info->prefix;
+                       show(prefix_filename(prefix,
+                                            prefix ? strlen(prefix) : 0,
+                                            arg));
+               } else
+                       show(arg);
                return 1;
        }
        return 0;
@@ -219,6 +236,7 @@ static int try_difference(const char *arg)
        const char *next;
        const char *this;
        int symmetric;
+       static const char head_by_default[] = "HEAD";
 
        if (!(dotdot = strstr(arg, "..")))
                return 0;
@@ -230,10 +248,21 @@ static int try_difference(const char *arg)
        next += symmetric;
 
        if (!*next)
-               next = "HEAD";
+               next = head_by_default;
        if (dotdot == arg)
-               this = "HEAD";
-       if (!get_sha1(this, sha1) && !get_sha1(next, end)) {
+               this = head_by_default;
+
+       if (this == head_by_default && next == head_by_default &&
+           !symmetric) {
+               /*
+                * Just ".."?  That is not a range but the
+                * pathspec for the parent directory.
+                */
+               *dotdot = '.';
+               return 0;
+       }
+
+       if (!get_sha1_committish(this, sha1) && !get_sha1_committish(next, end)) {
                show_rev(NORMAL, end, next);
                show_rev(symmetric ? NORMAL : REVERSED, sha1, this);
                if (symmetric) {
@@ -250,6 +279,7 @@ static int try_difference(const char *arg)
                                exclude = n;
                        }
                }
+               *dotdot = '.';
                return 1;
        }
        *dotdot = '.';
@@ -273,8 +303,10 @@ static int try_parent_shorthands(const char *arg)
                return 0;
 
        *dotdot = 0;
-       if (get_sha1(arg, sha1))
+       if (get_sha1_committish(arg, sha1)) {
+               *dotdot = '^';
                return 0;
+       }
 
        if (!parents_only)
                show_rev(NORMAL, sha1, arg);
@@ -283,6 +315,7 @@ static int try_parent_shorthands(const char *arg)
                show_rev(parents_only ? NORMAL : REVERSED,
                                parents->item->object.sha1, arg);
 
+       *dotdot = '^';
        return 1;
 }
 
@@ -313,15 +346,15 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
 {
        static int keep_dashdash = 0, stop_at_non_option = 0;
        static char const * const parseopt_usage[] = {
-               "git rev-parse --parseopt [options] -- [<args>...]",
+               N_("git rev-parse --parseopt [options] -- [<args>...]"),
                NULL
        };
        static struct option parseopt_opts[] = {
-               OPT_BOOLEAN(0, "keep-dashdash", &keep_dashdash,
-                                       "keep the `--` passed as an arg"),
-               OPT_BOOLEAN(0, "stop-at-non-option", &stop_at_non_option,
-                                       "stop parsing after the "
-                                       "first non-option argument"),
+               OPT_BOOL(0, "keep-dashdash", &keep_dashdash,
+                                       N_("keep the `--` passed as an arg")),
+               OPT_BOOL(0, "stop-at-non-option", &stop_at_non_option,
+                                       N_("stop parsing after the "
+                                          "first non-option argument")),
                OPT_END(),
        };
 
@@ -407,8 +440,9 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
        ALLOC_GROW(opts, onb + 1, osz);
        memset(opts + onb, 0, sizeof(opts[onb]));
        argc = parse_options(argc, argv, prefix, opts, usage,
-                       keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0 |
-                       stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0);
+                       (keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0) |
+                       (stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0) |
+                       PARSE_OPT_SHELL_EVAL);
 
        strbuf_addf(&parsed, " --");
        sq_quote_argv(&parsed, argv, 0);
@@ -437,15 +471,17 @@ static void die_no_single_rev(int quiet)
 }
 
 static const char builtin_rev_parse_usage[] =
-"git rev-parse --parseopt [options] -- [<args>...]\n"
-"   or: git rev-parse --sq-quote [<arg>...]\n"
-"   or: git rev-parse [options] [<arg>...]\n"
-"\n"
-"Run \"git rev-parse --parseopt -h\" for more information on the first usage.";
+N_("git rev-parse --parseopt [options] -- [<args>...]\n"
+   "   or: git rev-parse --sq-quote [<arg>...]\n"
+   "   or: git rev-parse [options] [<arg>...]\n"
+   "\n"
+   "Run \"git rev-parse --parseopt -h\" for more information on the first usage.");
 
 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;
+       int has_dashdash = 0;
+       int output_prefix = 0;
        unsigned char sha1[20];
        const char *name = NULL;
 
@@ -458,14 +494,21 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
        if (argc > 1 && !strcmp("-h", argv[1]))
                usage(builtin_rev_parse_usage);
 
+       for (i = 1; i < argc; i++) {
+               if (!strcmp(argv[i], "--")) {
+                       has_dashdash = 1;
+                       break;
+               }
+       }
+
        prefix = setup_git_directory();
        git_config(git_default_config, NULL);
        for (i = 1; i < argc; i++) {
                const char *arg = argv[i];
 
                if (as_is) {
-                       if (show_file(arg) && as_is < 2)
-                               verify_filename(prefix, arg);
+                       if (show_file(arg, output_prefix) && as_is < 2)
+                               verify_filename(prefix, arg, 0);
                        continue;
                }
                if (!strcmp(arg,"-n")) {
@@ -488,7 +531,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                                as_is = 2;
                                /* Pass on the "--" if we show anything but files.. */
                                if (filter & (DO_FLAGS | DO_REVS))
-                                       show_file(arg);
+                                       show_file(arg, 0);
                                continue;
                        }
                        if (!strcmp(arg, "--default")) {
@@ -496,6 +539,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                                i++;
                                continue;
                        }
+                       if (!strcmp(arg, "--prefix")) {
+                               prefix = argv[i+1];
+                               startup_info->prefix = prefix;
+                               output_prefix = 1;
+                               i++;
+                               continue;
+                       }
                        if (!strcmp(arg, "--revs-only")) {
                                filter &= ~DO_NOREV;
                                continue;
@@ -568,6 +618,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                                for_each_ref(show_reference, NULL);
                                continue;
                        }
+                       if (!prefixcmp(arg, "--disambiguate=")) {
+                               for_each_abbrev(arg + 15, show_abbrev, NULL);
+                               continue;
+                       }
                        if (!strcmp(arg, "--bisect")) {
                                for_each_ref_in("refs/bisect/bad", show_reference, NULL);
                                for_each_ref_in("refs/bisect/good", anti_reference, NULL);
@@ -604,6 +658,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                                for_each_remote_ref(show_reference, NULL);
                                continue;
                        }
+                       if (!strcmp(arg, "--local-env-vars")) {
+                               int i;
+                               for (i = 0; local_repo_env[i]; i++)
+                                       printf("%s\n", local_repo_env[i]);
+                               continue;
+                       }
                        if (!strcmp(arg, "--show-toplevel")) {
                                const char *work_tree = get_git_work_tree();
                                if (work_tree)
@@ -613,6 +673,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                        if (!strcmp(arg, "--show-prefix")) {
                                if (prefix)
                                        puts(prefix);
+                               else
+                                       putchar('\n');
                                continue;
                        }
                        if (!strcmp(arg, "--show-cdup")) {
@@ -637,6 +699,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                        if (!strcmp(arg, "--git-dir")) {
                                const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
                                static char cwd[PATH_MAX];
+                               int len;
                                if (gitdir) {
                                        puts(gitdir);
                                        continue;
@@ -647,7 +710,15 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                                }
                                if (!getcwd(cwd, PATH_MAX))
                                        die_errno("unable to get current working directory");
-                               printf("%s/.git\n", cwd);
+                               len = strlen(cwd);
+                               printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : "");
+                               continue;
+                       }
+                       if (!strcmp(arg, "--resolve-git-dir")) {
+                               const char *gitdir = resolve_gitdir(argv[i+1]);
+                               if (!gitdir)
+                                       die("not a gitdir '%s'", argv[i+1]);
+                               puts(gitdir);
                                continue;
                        }
                        if (!strcmp(arg, "--is-inside-git-dir")) {
@@ -706,10 +777,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                }
                if (verify)
                        die_no_single_rev(quiet);
+               if (has_dashdash)
+                       die("bad revision '%s'", arg);
                as_is = 1;
-               if (!show_file(arg))
+               if (!show_file(arg, output_prefix))
                        continue;
-               verify_filename(prefix, arg);
+               verify_filename(prefix, arg, 1);
        }
        if (verify) {
                if (revs_count == 1) {