Merge branch 'nk/name-rev-abbreviated-refs'

"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
This commit is contained in:
Junio C Hamano 2013-06-30 15:39:41 -07:00
commit 96ffd4ca93
2 changed files with 31 additions and 8 deletions

View file

@ -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

View file

@ -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;
@ -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))
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;