name-rev: allow to specify a subpath for --refs option
When an user wants to filter specific ref using the --refs option, the pattern needs to match the full ref, e.g. --refs=refs/tags/v1.*. It'd be convenient to specify a subpath of ref pattern. For example, --refs=origin/* can find refs/remotes/origin/master by searching the pattern against its substrings in turn: refs/remotes/origin/master remotes/origin/master origin/master If it finds a match in a subpath, unambigous part of the ref path will be removed in the output. Signed-off-by: Namhyung Kim <namhyung.kim@lge.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
edca415256
commit
98c5c4ad01
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user