summaryrefslogtreecommitdiff
path: root/builtin/name-rev.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/name-rev.c')
-rw-r--r--builtin/name-rev.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 1b374583c2..87d485496f 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -82,6 +82,20 @@ copy_data:
}
}
+static int subpath_matches(const char *path, const char *filter)
+{
+ const char *subpath = path;
+
+ while (subpath) {
+ if (!fnmatch(filter, subpath, 0))
+ return subpath - path;
+ subpath = strchr(subpath, '/');
+ if (subpath)
+ subpath++;
+ }
+ return -1;
+}
+
struct name_ref_data {
int tags_only;
int name_only;
@@ -92,13 +106,23 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
{
struct object *o = parse_object(sha1);
struct name_ref_data *data = cb_data;
+ int can_abbreviate_output = data->tags_only && data->name_only;
int deref = 0;
if (data->tags_only && prefixcmp(path, "refs/tags/"))
return 0;
- if (data->ref_filter && fnmatch(data->ref_filter, path, 0))
- return 0;
+ if (data->ref_filter) {
+ switch (subpath_matches(path, data->ref_filter)) {
+ case -1: /* did not match */
+ return 0;
+ case 0: /* matched fully */
+ break;
+ default: /* matched subpath */
+ can_abbreviate_output = 1;
+ break;
+ }
+ }
while (o && o->type == OBJ_TAG) {
struct tag *t = (struct tag *) o;
@@ -110,12 +134,10 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
if (o && o->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *)o;
- if (!prefixcmp(path, "refs/heads/"))
+ if (can_abbreviate_output)
+ path = shorten_unambiguous_ref(path, 0);
+ else if (!prefixcmp(path, "refs/heads/"))
path = path + 11;
- else if (data->tags_only
- && data->name_only
- && !prefixcmp(path, "refs/tags/"))
- path = path + 10;
else if (!prefixcmp(path, "refs/"))
path = path + 5;
@@ -172,9 +194,9 @@ static void show_name(const struct object *obj,
}
static char const * const name_rev_usage[] = {
- "git name-rev [options] <commit>...",
- "git name-rev [options] --all",
- "git name-rev [options] --stdin",
+ N_("git name-rev [options] <commit>..."),
+ N_("git name-rev [options] --all"),
+ N_("git name-rev [options] --stdin"),
NULL
};
@@ -226,16 +248,16 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
int all = 0, transform_stdin = 0, allow_undefined = 1, always = 0;
struct name_ref_data data = { 0, 0, NULL };
struct option opts[] = {
- OPT_BOOLEAN(0, "name-only", &data.name_only, "print only names (no SHA-1)"),
- OPT_BOOLEAN(0, "tags", &data.tags_only, "only use tags to name the commits"),
- OPT_STRING(0, "refs", &data.ref_filter, "pattern",
- "only use refs matching <pattern>"),
+ OPT_BOOLEAN(0, "name-only", &data.name_only, N_("print only names (no SHA-1)")),
+ OPT_BOOLEAN(0, "tags", &data.tags_only, N_("only use tags to name the commits")),
+ OPT_STRING(0, "refs", &data.ref_filter, N_("pattern"),
+ N_("only use refs matching <pattern>")),
OPT_GROUP(""),
- OPT_BOOLEAN(0, "all", &all, "list all commits reachable from all refs"),
- OPT_BOOLEAN(0, "stdin", &transform_stdin, "read from stdin"),
- OPT_BOOLEAN(0, "undefined", &allow_undefined, "allow to print `undefined` names"),
+ OPT_BOOLEAN(0, "all", &all, N_("list all commits reachable from all refs")),
+ OPT_BOOLEAN(0, "stdin", &transform_stdin, N_("read from stdin")),
+ OPT_BOOLEAN(0, "undefined", &allow_undefined, N_("allow to print `undefined` names")),
OPT_BOOLEAN(0, "always", &always,
- "show abbreviated commit object as fallback"),
+ N_("show abbreviated commit object as fallback")),
OPT_END(),
};