Skip to content

Commit

Permalink
Merge branch 'nk/name-rev-abbreviated-refs'
Browse files Browse the repository at this point in the history
"git name-rev --refs=tags/v*" were forbidden, which was a bit
inconvenient (you had to give a pattern to match refs fully, like
--refs=refs/tags/v*).

* nk/name-rev-abbreviated-refs:
  name-rev: allow to specify a subpath for --refs option
  • Loading branch information
Junio C Hamano committed Jun 30, 2013
2 parents d9857bf + 98c5c4a commit 96ffd4c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
3 changes: 2 additions & 1 deletion Documentation/git-name-rev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ OPTIONS
Do not use branch names, but only tags to name the commits

--refs=<pattern>::
Only use refs whose names match a given shell pattern.
Only use refs whose names match a given shell pattern. The pattern
can be one of branch name, tag name or fully qualified ref name.

--all::
List all commits reachable from all refs
Expand Down
36 changes: 29 additions & 7 deletions builtin/name-rev.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,20 @@ static void name_rev(struct commit *commit,
}
}

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;
Expand All @@ -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;
Expand All @@ -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;

Expand Down

0 comments on commit 96ffd4c

Please sign in to comment.