git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Namhyung Kim <namhyung@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, Namhyung Kim <namhyung.kim@lge.com>
Subject: [PATCH v2] name-rev: Allow to specify a subpath for --refs option
Date: Tue, 18 Jun 2013 21:35:31 +0900	[thread overview]
Message-ID: <1371558931-2980-1-git-send-email-namhyung@gmail.com> (raw)

From: Namhyung Kim <namhyung.kim@lge.com>

In its current form, when an user wants to filter specific ref using
 --refs option, she needs to give something like --refs=refs/tags/v1.*.

It'd be convenient providing a way 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.

Many thanks to Junio C. Hamano for suggesting better logic and code.

Signed-off-by: Namhyung Kim <namhyung.kim@lge.com>
---
 Documentation/git-name-rev.txt |  3 ++-
 builtin/name-rev.c             | 36 +++++++++++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt
index ad1d146..6b0f1ba 100644
--- a/Documentation/git-name-rev.txt
+++ b/Documentation/git-name-rev.txt
@@ -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
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 6238247..87d4854 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;
 
-- 
1.7.11.7

             reply	other threads:[~2013-06-18 12:35 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-18 12:35 Namhyung Kim [this message]
2013-06-18 15:28 ` [PATCH v2] name-rev: Allow to specify a subpath for --refs option Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1371558931-2980-1-git-send-email-namhyung@gmail.com \
    --to=namhyung@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=namhyung.kim@lge.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).