aboutsummaryrefslogtreecommitdiff
path: root/builtin/rev-parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/rev-parse.c')
-rw-r--r--builtin/rev-parse.c137
1 files changed, 98 insertions, 39 deletions
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 98d1cbecc..1d9ecafd4 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -9,6 +9,8 @@
#include "quote.h"
#include "builtin.h"
#include "parse-options.h"
+#include "diff.h"
+#include "revision.h"
#define DO_REVS 1
#define DO_NOREV 2
@@ -30,6 +32,9 @@ static int abbrev_ref;
static int abbrev_ref_strict;
static int output_sq;
+static int stuck_long;
+static struct string_list *ref_excludes;
+
/*
* Some arguments are relevant "revision" arguments,
* others are about output format or other details.
@@ -185,6 +190,8 @@ static int show_default(void)
static int show_reference(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
+ if (ref_excluded(ref_excludes, refname))
+ return 0;
show_rev(NORMAL, sha1, refname);
return 0;
}
@@ -195,6 +202,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];
@@ -206,11 +219,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;
@@ -224,6 +243,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;
@@ -235,10 +255,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) {
@@ -278,7 +309,7 @@ static int try_parent_shorthands(const char *arg)
return 0;
*dotdot = 0;
- if (get_sha1(arg, sha1))
+ if (get_sha1_committish(arg, sha1))
return 0;
if (!parents_only)
@@ -296,12 +327,15 @@ static int parseopt_dump(const struct option *o, const char *arg, int unset)
struct strbuf *parsed = o->value;
if (unset)
strbuf_addf(parsed, " --no-%s", o->long_name);
- else if (o->short_name)
+ else if (o->short_name && (o->long_name == NULL || !stuck_long))
strbuf_addf(parsed, " -%c", o->short_name);
else
strbuf_addf(parsed, " --%s", o->long_name);
if (arg) {
- strbuf_addch(parsed, ' ');
+ if (!stuck_long)
+ strbuf_addch(parsed, ' ');
+ else if (o->long_name)
+ strbuf_addch(parsed, '=');
sq_quote_buf(parsed, arg);
}
return 0;
@@ -318,15 +352,17 @@ 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_BOOL(0, "stuck-long", &stuck_long,
+ N_("output in stuck long form")),
OPT_END(),
};
@@ -443,15 +479,16 @@ 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 output_prefix = 0;
unsigned char sha1[20];
const char *name = NULL;
@@ -461,21 +498,6 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (argc > 1 && !strcmp("--sq-quote", argv[1]))
return cmd_sq_quote(argc - 2, argv + 2);
- if (argc == 2 && !strcmp("--local-env-vars", argv[1])) {
- int i;
- for (i = 0; local_repo_env[i]; i++)
- printf("%s\n", local_repo_env[i]);
- return 0;
- }
-
- if (argc > 2 && !strcmp(argv[1], "--resolve-git-dir")) {
- const char *gitdir = resolve_gitdir(argv[2]);
- if (!gitdir)
- die("not a gitdir '%s'", argv[2]);
- puts(gitdir);
- return 0;
- }
-
if (argc > 1 && !strcmp("-h", argv[1]))
usage(builtin_rev_parse_usage);
@@ -485,8 +507,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
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")) {
@@ -509,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")) {
@@ -517,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;
@@ -589,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);
@@ -597,32 +630,49 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (!prefixcmp(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 (!prefixcmp(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);
continue;
}
if (!prefixcmp(arg, "--glob=")) {
for_each_glob_ref(show_reference, arg + 7, NULL);
+ clear_ref_exclusion(&ref_excludes);
continue;
}
if (!prefixcmp(arg, "--remotes=")) {
for_each_glob_ref_in(show_reference, arg + 10,
"refs/remotes/", NULL);
+ clear_ref_exclusion(&ref_excludes);
continue;
}
if (!strcmp(arg, "--remotes")) {
for_each_remote_ref(show_reference, NULL);
+ clear_ref_exclusion(&ref_excludes);
+ continue;
+ }
+ if (!prefixcmp(arg, "--exclude=")) {
+ add_ref_exclusion(&ref_excludes, arg + 10);
+ 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")) {
@@ -634,6 +684,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")) {
@@ -673,6 +725,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
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")) {
printf("%s\n", is_inside_git_dir() ? "true"
: "false");
@@ -730,9 +789,9 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (verify)
die_no_single_rev(quiet);
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) {