{"thread":{"id":"34194","subject":"[PATCH v2] name-rev: Allow to specify a subpath for --refs option","startedAt":"2013-06-18T12:35:31Z","lastAt":"2013-06-18T15:28:23Z","messageCount":2,"participants":["Namhyung Kim","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"221209","messageId":"1371558931-2980-1-git-send-email-namhyung@gmail.com","threadId":"34194","inReplyTo":null,"subject":"[PATCH v2] name-rev: Allow to specify a subpath for --refs option","fromName":"Namhyung Kim","fromEmail":"namhyung@gmail.com","sentAt":"2013-06-18T12:35:31Z","receivedAt":"2013-06-18T12:35:31Z","isPatch":true,"sender":{"key":"namhyung@gmail.com","avatar":"https://avatars.githubusercontent.com/u/48503?v=4"},"body":"From: Namhyung Kim <namhyung.kim@lge.com>\n\nIn its current form, when an user wants to filter specific ref using\n --refs option, she needs to give something like --refs=refs/tags/v1.*.\n\nIt'd be convenient providing a way to specify a subpath of ref pattern.\nFor example, --refs=origin/* can find refs/remotes/origin/master by\nsearching the pattern against its substrings in turn:\n\n  refs/remotes/origin/master\n  remotes/origin/master\n  origin/master\n\nIf it finds a match in a subpath, unambigous part of the ref path will\nbe removed in the output.\n\nMany thanks to Junio C. Hamano for suggesting better logic and code.\n\nSigned-off-by: Namhyung Kim <namhyung.kim@lge.com>\n---\n Documentation/git-name-rev.txt |  3 ++-\n builtin/name-rev.c             | 36 +++++++++++++++++++++++++++++-------\n 2 files changed, 31 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt\nindex ad1d146..6b0f1ba 100644\n--- a/Documentation/git-name-rev.txt\n+++ b/Documentation/git-name-rev.txt\n@@ -25,7 +25,8 @@ OPTIONS\n \tDo not use branch names, but only tags to name the commits\n \n --refs=<pattern>::\n-\tOnly use refs whose names match a given shell pattern.\n+\tOnly use refs whose names match a given shell pattern.  The pattern\n+\tcan be one of branch name, tag name or fully qualified ref name.\n \n --all::\n \tList all commits reachable from all refs\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 6238247..87d4854 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -82,6 +82,20 @@ copy_data:\n \t}\n }\n \n+static int subpath_matches(const char *path, const char *filter)\n+{\n+\tconst char *subpath = path;\n+\n+\twhile (subpath) {\n+\t\tif (!fnmatch(filter, subpath, 0))\n+\t\t\treturn subpath - path;\n+\t\tsubpath = strchr(subpath, '/');\n+\t\tif (subpath)\n+\t\t\tsubpath++;\n+\t}\n+\treturn -1;\n+}\n+\n struct name_ref_data {\n \tint tags_only;\n \tint name_only;\n@@ -92,13 +106,23 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void\n {\n \tstruct object *o = parse_object(sha1);\n \tstruct name_ref_data *data = cb_data;\n+\tint can_abbreviate_output = data->tags_only && data->name_only;\n \tint deref = 0;\n \n \tif (data->tags_only && prefixcmp(path, \"refs/tags/\"))\n \t\treturn 0;\n \n-\tif (data->ref_filter && fnmatch(data->ref_filter, path, 0))\n-\t\treturn 0;\n+\tif (data->ref_filter) {\n+\t\tswitch (subpath_matches(path, data->ref_filter)) {\n+\t\tcase -1: /* did not match */\n+\t\t\treturn 0;\n+\t\tcase 0:  /* matched fully */\n+\t\t\tbreak;\n+\t\tdefault: /* matched subpath */\n+\t\t\tcan_abbreviate_output = 1;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n \n \twhile (o && o->type == OBJ_TAG) {\n \t\tstruct tag *t = (struct tag *) o;\n@@ -110,12 +134,10 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void\n \tif (o && o->type == OBJ_COMMIT) {\n \t\tstruct commit *commit = (struct commit *)o;\n \n-\t\tif (!prefixcmp(path, \"refs/heads/\"))\n+\t\tif (can_abbreviate_output)\n+\t\t\tpath = shorten_unambiguous_ref(path, 0);\n+\t\telse if (!prefixcmp(path, \"refs/heads/\"))\n \t\t\tpath = path + 11;\n-\t\telse if (data->tags_only\n-\t\t    && data->name_only\n-\t\t    && !prefixcmp(path, \"refs/tags/\"))\n-\t\t\tpath = path + 10;\n \t\telse if (!prefixcmp(path, \"refs/\"))\n \t\t\tpath = path + 5;\n \n-- \n1.7.11.7\n"},{"id":"221239","messageId":"7v7ghr8mlk.fsf@alter.siamese.dyndns.org","threadId":"34194","inReplyTo":"1371558931-2980-1-git-send-email-namhyung@gmail.com","subject":"Re: [PATCH v2] name-rev: Allow to specify a subpath for --refs option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-18T15:28:23Z","receivedAt":"2013-06-18T15:28:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Namhyung Kim <namhyung@gmail.com> writes:\n\n> From: Namhyung Kim <namhyung.kim@lge.com>\n>\n> In its current form, when an user wants to filter specific ref using\n>  --refs option, she needs to give something like --refs=refs/tags/v1.*.\n\nWill queue.  Thanks.\n"}]}