All of lore.kernel.org
 help / color / mirror / Atom feed
* finding earliest tags descended from a given commit
@ 2007-01-27  4:06 J. Bruce Fields
  2007-01-27  4:22 ` Shawn O. Pearce
  2007-01-27  4:34 ` Linus Torvalds
  0 siblings, 2 replies; 22+ messages in thread
From: J. Bruce Fields @ 2007-01-27  4:06 UTC (permalink / raw)
  To: git

Just curious: every now and then somebody will ask me what kernel
version they need to upgrade to to get some given fix.  I can find the
commit with the given fix easily enough.  How do I then find the
earliest tagged version containing that fix?

More generally, given a commit, is there a quick way to find the set of
tags which tag commits descended from the given commit?  Or to get the
subset of such tags which are earliest (in the sense that they're not
descendants of any of the others)?

I usually just do

	git-describe <commit>

to make a guess, then

	git log <tag>..<commit>

to verify, but perhaps there's something more clever, or something that
would work better in a project where the tags aren't necessarily all in
a straight line.

--b.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: finding earliest tags descended from a given commit
  2007-01-27  4:06 finding earliest tags descended from a given commit J. Bruce Fields
@ 2007-01-27  4:22 ` Shawn O. Pearce
  2007-01-27  4:34 ` Linus Torvalds
  1 sibling, 0 replies; 22+ messages in thread
From: Shawn O. Pearce @ 2007-01-27  4:22 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: git

"J. Bruce Fields" <bfields@fieldses.org> wrote:
> Just curious: every now and then somebody will ask me what kernel
> version they need to upgrade to to get some given fix.  I can find the
> commit with the given fix easily enough.  How do I then find the
> earliest tagged version containing that fix?

git-name-rev commit?

It should give you not only the tag, but how many commits before
that tag the fix was made.

-- 
Shawn.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: finding earliest tags descended from a given commit
  2007-01-27  4:06 finding earliest tags descended from a given commit J. Bruce Fields
  2007-01-27  4:22 ` Shawn O. Pearce
@ 2007-01-27  4:34 ` Linus Torvalds
  2007-01-27  4:42   ` J. Bruce Fields
  1 sibling, 1 reply; 22+ messages in thread
From: Linus Torvalds @ 2007-01-27  4:34 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: git



On Fri, 26 Jan 2007, J. Bruce Fields wrote:
>
> Just curious: every now and then somebody will ask me what kernel
> version they need to upgrade to to get some given fix.  I can find the
> commit with the given fix easily enough.  How do I then find the
> earliest tagged version containing that fix?

You can name any revision based on the set of tags you have with:

	git name-rev --tags <sha1-of-commit>

which will try to find the "simplest" way to name something by following 
one of your tags.

If no tag can be found that reaches that commit, it will say

	<sha1> undefined

but otherwise you will get something like this:

	[torvalds@woody linux]$ git name-rev --tags 7658cc28
	7658cc28 tags/v2.6.20-rc3^0~58

(That's the "VM: Fix nasty and subtle race in shared mmap'ed page 
writeback commit").

So that basically tells you that it's the 58'th parent of v2.6.20-rc3, ie 
it was in -rc3, but not in -rc2.

> I usually just do
> 
> 	git-describe <commit>
> 
> to make a guess, then
> 
> 	git log <tag>..<commit>

Yeah. That mostly works too, and kind of for the right reason: it's a 
related operation. But as you can tell, git-describe tells you which 
version somethign is *based* on, not when it was merged, so while it gives 
you a starting point for your search, it's not what you want.

Basically 'git descibe' goes the "other way": it walks backwards from the 
commit to the nearest tag that can be found, while 'git name-rev --tags' 
walks the history backwards from the tags, and tries to find the commit. 

NOTE! 'git name-rev' can in theory be quite expensive, although if you 
have a packed repository you'll probably never even notice it.

		Linus

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: finding earliest tags descended from a given commit
  2007-01-27  4:34 ` Linus Torvalds
@ 2007-01-27  4:42   ` J. Bruce Fields
  2007-01-27  4:55     ` Shawn O. Pearce
  0 siblings, 1 reply; 22+ messages in thread
From: J. Bruce Fields @ 2007-01-27  4:42 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git

On Fri, Jan 26, 2007 at 08:34:15PM -0800, Linus Torvalds wrote:
> On Fri, 26 Jan 2007, J. Bruce Fields wrote:
> >
> > Just curious: every now and then somebody will ask me what kernel
> > version they need to upgrade to to get some given fix.  I can find the
> > commit with the given fix easily enough.  How do I then find the
> > earliest tagged version containing that fix?
> 
> You can name any revision based on the set of tags you have with:
> 
> 	git name-rev --tags <sha1-of-commit>
> 
> which will try to find the "simplest" way to name something by following 
> one of your tags.

That's interesting, I hadn't noticed name-rev before you and Shawn
mentioned it.

It only finds one name, though. When I tried it just now on my
repository what it found was a tag I'd created for an experimental
version, which probably wouldn't be what I wanted.  (Though it might be,
in some situations.)

--b.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: finding earliest tags descended from a given commit
  2007-01-27  4:42   ` J. Bruce Fields
@ 2007-01-27  4:55     ` Shawn O. Pearce
  2007-01-27  5:23       ` Junio C Hamano
  0 siblings, 1 reply; 22+ messages in thread
From: Shawn O. Pearce @ 2007-01-27  4:55 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Linus Torvalds, git

"J. Bruce Fields" <bfields@fieldses.org> wrote:
> That's interesting, I hadn't noticed name-rev before you and Shawn
> mentioned it.
> 
> It only finds one name, though. When I tried it just now on my
> repository what it found was a tag I'd created for an experimental
> version, which probably wouldn't be what I wanted.  (Though it might be,
> in some situations.)

Yea. Hmm.  Maybe name-rev needs to learn a few more tricks, like
favoring annotated tags over non-annotated ones/heads, and being
able to print the top n nearest matches (e.g. 10), by displaying
only one line of output per tag (or ref).

Right now I'm trying to educate describe some more.  Although
similar, describe has a much easier job as its very easy for it to
say "that's the best name we have for the input".  Part of that is
because it is favoring annotated tags all of the time, and part of
that is because it does this distance computation thing now and
always favors the tag with the shortest distance between the tag
and the input.

In the case of name-rev I'm thinking maybe its actually the longest
distance annotated tag that makes sense.  That is, prefer to name
the input using the annotated tag which has the shortest distance
between the tag and the input, but where the tag is the farthest
back in history you can go when compared to any other possible tag,
and yet stills contains the input in its ancestry.

-- 
Shawn.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: finding earliest tags descended from a given commit
  2007-01-27  4:55     ` Shawn O. Pearce
@ 2007-01-27  5:23       ` Junio C Hamano
  2007-01-27 12:39         ` [PATCH] name-rev: introduce the --ref-filter=<regex> option Johannes Schindelin
  0 siblings, 1 reply; 22+ messages in thread
From: Junio C Hamano @ 2007-01-27  5:23 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: J. Bruce Fields, Linus Torvalds, git

"Shawn O. Pearce" <spearce@spearce.org> writes:

> "J. Bruce Fields" <bfields@fieldses.org> wrote:
>> That's interesting, I hadn't noticed name-rev before you and Shawn
>> mentioned it.
>> 
>> It only finds one name, though. When I tried it just now on my
>> repository what it found was a tag I'd created for an experimental
>> version, which probably wouldn't be what I wanted.  (Though it might be,
>> in some situations.)
>
> Yea. Hmm.  Maybe name-rev needs to learn a few more tricks, like
> favoring annotated tags over non-annotated ones/heads, and being
> able to print the top n nearest matches (e.g. 10), by displaying
> only one line of output per tag (or ref).

Yeah, I found name-rev to be mostly useless since it almost
always names relative to my unannotated "anchor" tag that I use
to keep track of 'master' I sent the last "What's in" message
for.

I think doing parallel merge-base computation that is in
show-branch and the updated describe would be a sensible
approach.  When somebody says such and such does not work yet in
his version, after identifying the commit that introduced that
feature, I would run "show-branch $that_rev 'tags/v1.*'" to see
which tag(s) contain that revision.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH] name-rev: introduce the --ref-filter=<regex> option
  2007-01-27  5:23       ` Junio C Hamano
@ 2007-01-27 12:39         ` Johannes Schindelin
  2007-02-17 14:02           ` Johannes Schindelin
  0 siblings, 1 reply; 22+ messages in thread
From: Johannes Schindelin @ 2007-01-27 12:39 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git


Instead of (or, in addition to) --tags, to use only tags for naming,
you can now use --ref-filter=<regex> to specify which refs are
used for naming.

Example:

	$ git name-rev --ref-filter='/v1' 33db5f4d
	33db5f4d tags/v1.0rc1^0~1593

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---

	On Fri, 26 Jan 2007, Junio C Hamano wrote:

	> Yeah, I found name-rev to be mostly useless since it almost
	> always names relative to my unannotated "anchor" tag that I use
	> to keep track of 'master' I sent the last "What's in" message
	> for.

	How about this?

	Though I think you'd use --ref-filter='tags/v[0-9]'. Or you would 
	alias it:

		git-repo-config alias.findver \
			"name-rev --ref-filter='tags/v[0-9]'"

 Documentation/git-name-rev.txt |   14 ++++++++++++--
 builtin-name-rev.c             |   27 +++++++++++++++++++++------
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt
index 37fbf66..7de4bea 100644
--- a/Documentation/git-name-rev.txt
+++ b/Documentation/git-name-rev.txt
@@ -8,7 +8,7 @@ git-name-rev - Find symbolic names for given revs
 
 SYNOPSIS
 --------
-'git-name-rev' [--tags] ( --all | --stdin | <committish>... )
+'git-name-rev' [--tags | --ref-filter=<regex>] ( --all | --stdin | <committish>... )
 
 DESCRIPTION
 -----------
@@ -22,6 +22,9 @@ OPTIONS
 --tags::
 	Do not use branch names, but only tags to name the commits
 
+--ref-filter=<regex>::
+	Only use refs for naming which match the regexp
+
 --all::
 	List all commits reachable from all refs
 
@@ -29,7 +32,7 @@ OPTIONS
 	Read from stdin, append "(<rev_name>)" to all sha1's of nameable
 	commits, and pass to stdout
 
-EXAMPLE
+EXAMPLES
 -------
 
 Given a commit, find out where it is relative to the local refs. Say somebody
@@ -52,6 +55,13 @@ Another nice thing you can do is:
 % git log | git name-rev --stdin
 ------------
 
+If you want to name a revision only by a subset of the refs you have, use
+a regular expression to specify the subset:
+
+------------
+$ git name-rev --ref-filter='/v1' 33db5f4d
+33db5f4d tags/v1.0rc1^0~1593
+------------
 
 Author
 ------
diff --git a/builtin-name-rev.c b/builtin-name-rev.c
index b4f15cc..89ea95d 100644
--- a/builtin-name-rev.c
+++ b/builtin-name-rev.c
@@ -3,9 +3,10 @@
 #include "commit.h"
 #include "tag.h"
 #include "refs.h"
+#include <regex.h>
 
 static const char name_rev_usage[] =
-	"git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\n";
+	"git-name-rev [--tags | --ref-filter=<regexp>] ( --all | --stdin | committish [committish...] )\n";
 
 typedef struct rev_name {
 	const char *tip_name;
@@ -74,13 +75,21 @@ copy_data:
 	}
 }
 
+struct name_ref_data {
+	int tags_only;
+	regex_t *ref_filter;
+};
+
 static int name_ref(const char *path, const unsigned char *sha1, int flags, void *cb_data)
 {
 	struct object *o = parse_object(sha1);
-	int tags_only = *(int*)cb_data;
+	struct name_ref_data *data = cb_data;
 	int deref = 0;
 
-	if (tags_only && strncmp(path, "refs/tags/", 10))
+	if (data->tags_only && strncmp(path, "refs/tags/", 10))
+		return 0;
+
+	if (data->ref_filter && regexec(data->ref_filter, path, 0, NULL, 0))
 		return 0;
 
 	while (o && o->type == OBJ_TAG) {
@@ -129,7 +138,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 {
 	struct object_array revs = { 0, 0, NULL };
 	int as_is = 0, all = 0, transform_stdin = 0;
-	int tags_only = 0;
+	struct name_ref_data data = { 0, NULL };
 
 	git_config(git_default_config);
 
@@ -146,7 +155,13 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 				as_is = 1;
 				continue;
 			} else if (!strcmp(*argv, "--tags")) {
-				tags_only = 1;
+				data.tags_only = 1;
+				continue;
+			} else  if (!strncmp(*argv, "--ref-filter=", 13)) {
+				data.ref_filter = xmalloc(sizeof(regex_t));
+				if (regcomp(data.ref_filter, *argv + 13,
+							REG_EXTENDED))
+					die ("invalid regexp: %s", *argv + 13);
 				continue;
 			} else if (!strcmp(*argv, "--all")) {
 				if (argc > 1)
@@ -185,7 +200,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 		add_object_array((struct object *)commit, *argv, &revs);
 	}
 
-	for_each_ref(name_ref, &tags_only);
+	for_each_ref(name_ref, &data);
 
 	if (transform_stdin) {
 		char buffer[2048];
-- 
1.5.0.rc2.g324a-dirty

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option
  2007-01-27 12:39         ` [PATCH] name-rev: introduce the --ref-filter=<regex> option Johannes Schindelin
@ 2007-02-17 14:02           ` Johannes Schindelin
  2007-02-17 14:59             ` Jeff King
  2007-02-17 17:42             ` [PATCH] name-rev: introduce the --ref-filter=<regex> option Junio C Hamano
  0 siblings, 2 replies; 22+ messages in thread
From: Johannes Schindelin @ 2007-02-17 14:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Hi,

On Sat, 27 Jan 2007, Johannes Schindelin wrote:

> Instead of (or, in addition to) --tags, to use only tags for naming,
> you can now use --ref-filter=<regex> to specify which refs are
> used for naming.
> 
> Example:
> 
> 	$ git name-rev --ref-filter='/v1' 33db5f4d
> 	33db5f4d tags/v1.0rc1^0~1593

Likes, dislikes?

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option
  2007-02-17 14:02           ` Johannes Schindelin
@ 2007-02-17 14:59             ` Jeff King
  2007-02-17 17:50               ` Johannes Schindelin
  2007-02-17 18:25               ` Junio C Hamano
  2007-02-17 17:42             ` [PATCH] name-rev: introduce the --ref-filter=<regex> option Junio C Hamano
  1 sibling, 2 replies; 22+ messages in thread
From: Jeff King @ 2007-02-17 14:59 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git

On Sat, Feb 17, 2007 at 03:02:36PM +0100, Johannes Schindelin wrote:

> > Instead of (or, in addition to) --tags, to use only tags for naming,
> > you can now use --ref-filter=<regex> to specify which refs are
> > used for naming.
> > 
> > Example:
> > 
> > 	$ git name-rev --ref-filter='/v1' 33db5f4d
> > 	33db5f4d tags/v1.0rc1^0~1593
> 
> Likes, dislikes?

It's a neat idea, but I wonder if you could make it even more flexible
by simply accepting a list of possible refs, and then you could filter
using grep, or your own more complex selection algorithm.
Unfortunately, --stdin is already taken, but something like:

git show-ref | grep tags/v1.4 | git name-rev --stdin-refs 33db5f4d

If the stdin ref format includes both the refname and the hash, you
could even find 'fake' refs that don't exist in git (e.g., that you get
from a foreign SCM; though why you wouldn't just make git tags for them,
I don't know).

Or maybe this is just making the problem too complex, and nobody really
wants to do it. I certainly don't have a use at this point, but if
you're going to do ref filtering, it seems like making it as general as
(painlessly) possible is useful.

-Peff

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option
  2007-02-17 14:02           ` Johannes Schindelin
  2007-02-17 14:59             ` Jeff King
@ 2007-02-17 17:42             ` Junio C Hamano
  2007-02-17 18:01               ` Johannes Schindelin
  2007-02-17 18:22               ` [PATCH] name-rev: introduce the --ref-filter=<pattern> option Johannes Schindelin
  1 sibling, 2 replies; 22+ messages in thread
From: Junio C Hamano @ 2007-02-17 17:42 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> Instead of (or, in addition to) --tags, to use only tags for naming,
>> you can now use --ref-filter=<regex> to specify which refs are
>> used for naming.
>> 
>> Example:
>> 
>> 	$ git name-rev --ref-filter='/v1' 33db5f4d
>> 	33db5f4d tags/v1.0rc1^0~1593
>
> Likes, dislikes?

"Describe these objects in terms of these refs -- do not use any
other random refs, even if they are closer" was sorely lacking
for it to be usable for me, so I like what it does.

When we talk about path and path-like things including refs
I think we consistently use fnmatch not regexp.  At least I
think we try to.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option
  2007-02-17 14:59             ` Jeff King
@ 2007-02-17 17:50               ` Johannes Schindelin
  2007-02-17 18:25               ` Junio C Hamano
  1 sibling, 0 replies; 22+ messages in thread
From: Johannes Schindelin @ 2007-02-17 17:50 UTC (permalink / raw)
  To: Jeff King; +Cc: git

Hi,

On Sat, 17 Feb 2007, Jeff King wrote:

> On Sat, Feb 17, 2007 at 03:02:36PM +0100, Johannes Schindelin wrote:
> 
> > > Instead of (or, in addition to) --tags, to use only tags for naming,
> > > you can now use --ref-filter=<regex> to specify which refs are
> > > used for naming.
> > > 
> > > Example:
> > > 
> > > 	$ git name-rev --ref-filter='/v1' 33db5f4d
> > > 	33db5f4d tags/v1.0rc1^0~1593
> > 
> > Likes, dislikes?
> 
> It's a neat idea, but I wonder if you could make it even more flexible
> by simply accepting a list of possible refs, and then you could filter
> using grep, or your own more complex selection algorithm.

You can do that with regexps also. And you're right, my code was meant to 
be simple...

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option
  2007-02-17 17:42             ` [PATCH] name-rev: introduce the --ref-filter=<regex> option Junio C Hamano
@ 2007-02-17 18:01               ` Johannes Schindelin
  2007-02-17 18:22               ` [PATCH] name-rev: introduce the --ref-filter=<pattern> option Johannes Schindelin
  1 sibling, 0 replies; 22+ messages in thread
From: Johannes Schindelin @ 2007-02-17 18:01 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Hi,

On Sat, 17 Feb 2007, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> >> Instead of (or, in addition to) --tags, to use only tags for naming,
> >> you can now use --ref-filter=<regex> to specify which refs are
> >> used for naming.
> >> 
> >> Example:
> >> 
> >> 	$ git name-rev --ref-filter='/v1' 33db5f4d
> >> 	33db5f4d tags/v1.0rc1^0~1593
> >
> > Likes, dislikes?
> 
> "Describe these objects in terms of these refs -- do not use any
> other random refs, even if they are closer" was sorely lacking
> for it to be usable for me, so I like what it does.
> 
> When we talk about path and path-like things including refs
> I think we consistently use fnmatch not regexp.  At least I
> think we try to.

Okay. Will rework.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH] name-rev: introduce the --ref-filter=<pattern> option
  2007-02-17 17:42             ` [PATCH] name-rev: introduce the --ref-filter=<regex> option Junio C Hamano
  2007-02-17 18:01               ` Johannes Schindelin
@ 2007-02-17 18:22               ` Johannes Schindelin
  2007-02-17 18:47                 ` Junio C Hamano
  2007-02-17 19:00                 ` Junio C Hamano
  1 sibling, 2 replies; 22+ messages in thread
From: Johannes Schindelin @ 2007-02-17 18:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git


Instead of (or, in addition to) --tags, to use only tags for naming,
you can now use --ref-filter=<patter> to specify a shell pattern
which the refs must match to be used for naming.

Example:

	$ git name-rev --ref-filter=*v1* 33db5f4d
	33db5f4d tags/v1.0rc1^0~1593

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---

	On Sat, 17 Feb 2007, Junio C Hamano wrote:

	> When we talk about path and path-like things including refs
	> I think we consistently use fnmatch not regexp.  At least I
	> think we try to.

	And this patch does exactly that.

 Documentation/git-name-rev.txt |    6 +++++-
 builtin-name-rev.c             |   23 +++++++++++++++++------
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt
index 37fbf66..a99d60b 100644
--- a/Documentation/git-name-rev.txt
+++ b/Documentation/git-name-rev.txt
@@ -8,7 +8,8 @@ git-name-rev - Find symbolic names for given revs
 
 SYNOPSIS
 --------
-'git-name-rev' [--tags] ( --all | --stdin | <committish>... )
+'git-name-rev' [--tags] [--ref-filter=<pattern>]
+	       ( --all | --stdin | <committish>... )
 
 DESCRIPTION
 -----------
@@ -22,6 +23,9 @@ OPTIONS
 --tags::
 	Do not use branch names, but only tags to name the commits
 
+--ref-filter=<pattern>::
+	Only use refs whose names match a given shell pattern.
+
 --all::
 	List all commits reachable from all refs
 
diff --git a/builtin-name-rev.c b/builtin-name-rev.c
index b4f15cc..615af4b 100644
--- a/builtin-name-rev.c
+++ b/builtin-name-rev.c
@@ -5,7 +5,7 @@
 #include "refs.h"
 
 static const char name_rev_usage[] =
-	"git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\n";
+	"git-name-rev [--tags | --ref-filter=<pattern>] ( --all | --stdin | committish [committish...] )\n";
 
 typedef struct rev_name {
 	const char *tip_name;
@@ -74,13 +74,21 @@ copy_data:
 	}
 }
 
+struct name_ref_data {
+	int tags_only;
+	const char *ref_filter;
+};
+
 static int name_ref(const char *path, const unsigned char *sha1, int flags, void *cb_data)
 {
 	struct object *o = parse_object(sha1);
-	int tags_only = *(int*)cb_data;
+	struct name_ref_data *data = cb_data;
 	int deref = 0;
 
-	if (tags_only && strncmp(path, "refs/tags/", 10))
+	if (data->tags_only && strncmp(path, "refs/tags/", 10))
+		return 0;
+
+	if (data->ref_filter && fnmatch(data->ref_filter, path, 0))
 		return 0;
 
 	while (o && o->type == OBJ_TAG) {
@@ -129,7 +137,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 {
 	struct object_array revs = { 0, 0, NULL };
 	int as_is = 0, all = 0, transform_stdin = 0;
-	int tags_only = 0;
+	struct name_ref_data data = { 0, NULL };
 
 	git_config(git_default_config);
 
@@ -146,7 +154,10 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 				as_is = 1;
 				continue;
 			} else if (!strcmp(*argv, "--tags")) {
-				tags_only = 1;
+				data.tags_only = 1;
+				continue;
+			} else  if (!strncmp(*argv, "--ref-filter=", 13)) {
+				data.ref_filter = *argv + 13;
 				continue;
 			} else if (!strcmp(*argv, "--all")) {
 				if (argc > 1)
@@ -185,7 +196,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 		add_object_array((struct object *)commit, *argv, &revs);
 	}
 
-	for_each_ref(name_ref, &tags_only);
+	for_each_ref(name_ref, &data);
 
 	if (transform_stdin) {
 		char buffer[2048];
-- 
1.5.0.2139.gdafc9-dirty

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option
  2007-02-17 14:59             ` Jeff King
  2007-02-17 17:50               ` Johannes Schindelin
@ 2007-02-17 18:25               ` Junio C Hamano
  2007-02-17 23:13                 ` [PATCH] git-name-rev: accept list of refs from user Jeff King
  1 sibling, 1 reply; 22+ messages in thread
From: Junio C Hamano @ 2007-02-17 18:25 UTC (permalink / raw)
  To: Jeff King; +Cc: Johannes Schindelin, git

Jeff King <peff@peff.net> writes:

> On Sat, Feb 17, 2007 at 03:02:36PM +0100, Johannes Schindelin wrote:
>
>> > Instead of (or, in addition to) --tags, to use only tags for naming,
>> > you can now use --ref-filter=<regex> to specify which refs are
>> > used for naming.
>> > 
>> > Example:
>> > 
>> > 	$ git name-rev --ref-filter='/v1' 33db5f4d
>> > 	33db5f4d tags/v1.0rc1^0~1593
>> 
>> Likes, dislikes?
>
> It's a neat idea, but I wonder if you could make it even more flexible
> by simply accepting a list of possible refs, and then you could filter
> using grep, or your own more complex selection algorithm.
> Unfortunately, --stdin is already taken, but something like:
>
> git show-ref | grep tags/v1.4 | git name-rev --stdin-refs 33db5f4d

FWIW, I like that.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] name-rev: introduce the --ref-filter=<pattern> option
  2007-02-17 18:22               ` [PATCH] name-rev: introduce the --ref-filter=<pattern> option Johannes Schindelin
@ 2007-02-17 18:47                 ` Junio C Hamano
  2007-02-17 23:55                   ` Johannes Schindelin
  2007-02-17 19:00                 ` Junio C Hamano
  1 sibling, 1 reply; 22+ messages in thread
From: Junio C Hamano @ 2007-02-17 18:47 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Instead of (or, in addition to) --tags, to use only tags for naming,
> you can now use --ref-filter=<patter> to specify a shell pattern
> which the refs must match to be used for naming.
>
> Example:
>
> 	$ git name-rev --ref-filter=*v1* 33db5f4d
> 	33db5f4d tags/v1.0rc1^0~1593

I am sorry I did not mention earlier, but doesn't --ref-filter
sound too long?  How about '--refs=*v1*'?

No need to resend, just Ack / Nack would do.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] name-rev: introduce the --ref-filter=<pattern> option
  2007-02-17 18:22               ` [PATCH] name-rev: introduce the --ref-filter=<pattern> option Johannes Schindelin
  2007-02-17 18:47                 ` Junio C Hamano
@ 2007-02-17 19:00                 ` Junio C Hamano
  1 sibling, 0 replies; 22+ messages in thread
From: Junio C Hamano @ 2007-02-17 19:00 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Instead of (or, in addition to) --tags, to use only tags for naming,
> you can now use --ref-filter=<patter> to specify a shell pattern
> which the refs must match to be used for naming.
>
> Example:
>
> 	$ git name-rev --ref-filter=*v1* 33db5f4d
> 	33db5f4d tags/v1.0rc1^0~1593
>
> Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>

Thanks.  It's a bit counterintuitive that the first asterisk in
your example "*v1*" matches something that contains a slash, but
at least the patch makes it usable for me.

By the way, v1.0rc1^0~1593 is the same as v1.0rc1~1593.
Technically, the latter loses the information that the starting
ref is a tag, but I wonder if it is worth keeping that
information at the expense of (slightly) uglier output.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH] git-name-rev: accept list of refs from user
  2007-02-17 18:25               ` Junio C Hamano
@ 2007-02-17 23:13                 ` Jeff King
  2007-02-17 23:19                   ` Jeff King
  0 siblings, 1 reply; 22+ messages in thread
From: Jeff King @ 2007-02-17 23:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git

This lets you do things like

  git show-ref | grep /v1 | git name-rev --refs-from=- $commit

or even

  git show-ref | ./some_complex_ref_filter >refs
  git name-rev --refs-from=refs --stdin <list_of_commits

Signed-off-by: Jeff King <peff@peff.net>
---
On Sat, Feb 17, 2007 at 10:25:00AM -0800, Junio C Hamano wrote:
>> git show-ref | grep tags/v1.4 | git name-rev --stdin-refs 33db5f4d
> FWIW, I like that.

Here it is (I chose --refs-from= so you could use it with the existing
--stdin flag). We might want to do the same for git-describe, I would
think (they can probably share the for_each_ref_from_file code).

The input format is "sha1 ref"; clearly it could also accept just "ref",
and look up the sha1, but I expect most people will just be piping from
git-show-ref anyway.

 Documentation/git-name-rev.txt |   16 +++++++++++-
 builtin-name-rev.c             |   54 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt
index 37fbf66..d2fb3bb 100644
--- a/Documentation/git-name-rev.txt
+++ b/Documentation/git-name-rev.txt
@@ -8,7 +8,7 @@ git-name-rev - Find symbolic names for given revs
 
 SYNOPSIS
 --------
-'git-name-rev' [--tags] ( --all | --stdin | <committish>... )
+'git-name-rev' [--tags] [--refs-from=<file>] ( --all | --stdin | <committish>... )
 
 DESCRIPTION
 -----------
@@ -22,6 +22,13 @@ OPTIONS
 --tags::
 	Do not use branch names, but only tags to name the commits
 
+--refs-from=<file>::
+	Instead of choosing a name based on all refs, read refs from <file>,
+	one per line, in the form "sha1 ref". This is the same as the
+	default output generated by "git show-ref". If <file> is "-",
+	read from stdin. The --tags option is still respected when using
+	--refs-from.
+
 --all::
 	List all commits reachable from all refs
 
@@ -52,6 +59,13 @@ Another nice thing you can do is:
 % git log | git name-rev --stdin
 ------------
 
+You can filter the commits used to describe a commit using the --refs-from
+option:
+
+------------
+% git show-ref | grep tags/v1 | git name-rev --refs-from=- 26cfcfbf
+------------
+
 
 Author
 ------
diff --git a/builtin-name-rev.c b/builtin-name-rev.c
index b4f15cc..c8480d2 100644
--- a/builtin-name-rev.c
+++ b/builtin-name-rev.c
@@ -5,7 +5,7 @@
 #include "refs.h"
 
 static const char name_rev_usage[] =
-	"git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\n";
+"git-name-rev [--tags] [--refs-from=<file>] ( --all | --stdin | committish ... )";
 
 typedef struct rev_name {
 	const char *tip_name;
@@ -14,6 +14,7 @@ typedef struct rev_name {
 } rev_name;
 
 static long cutoff = LONG_MAX;
+static const char *refs_from = NULL;
 
 static void name_rev(struct commit *commit,
 		const char *tip_name, int merge_traversals, int generation,
@@ -103,6 +104,46 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
 	return 0;
 }
 
+static void trim_trailing_whitespace(char *buf)
+{
+	int i = strlen(buf) - 1;
+	while(i >= 0 && isspace(buf[i]))
+		buf[i--] = '\0';
+}
+
+static void for_each_ref_from_file(const char *filename, each_ref_fn fn, void *data)
+{
+	FILE *fh;
+	char buf[PATH_MAX + 40 + 3]; /* "PATH SHA1\n\0" */
+	unsigned char sha1[20];
+
+	if (!strcmp(filename, "-"))
+		fh = stdin;
+	else {
+		fh = fopen(filename, "r");
+		if (!fh)
+			die("unable to open %s: %s", filename, strerror(errno));
+	}
+
+	while (fgets(buf, sizeof buf, fh)) {
+		char *name;
+
+		trim_trailing_whitespace(buf);
+
+		name = strchr(buf, ' ');
+		if (!name)
+			die("invalid input ref format: %s\n", buf);
+		*name++ = '\0';
+
+		if (get_sha1_hex(buf, sha1) < 0)
+			die("invalid sha1: %s\n", buf);
+
+		name_ref(name, sha1, 0, data);
+	}
+
+	fclose(fh);
+}
+
 /* returns a static buffer */
 static const char* get_rev_name(struct object *o)
 {
@@ -160,6 +201,9 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 				transform_stdin = 1;
 				cutoff = 0;
 				continue;
+			} else if (!strncmp(*argv, "--refs-from=", 12)) {
+				refs_from = (*argv)+12;
+				continue;
 			}
 			usage(name_rev_usage);
 		}
@@ -185,7 +229,13 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 		add_object_array((struct object *)commit, *argv, &revs);
 	}
 
-	for_each_ref(name_ref, &tags_only);
+	if (refs_from && !strcmp(refs_from, "-") && transform_stdin)
+		die("--refs-from=- and --stdin are incompatible!");
+
+	if (refs_from)
+		for_each_ref_from_file(refs_from, name_ref, &tags_only);
+	else
+		for_each_ref(name_ref, &tags_only);
 
 	if (transform_stdin) {
 		char buffer[2048];
-- 
1.5.0.552.ge1b1c-dirty

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH] git-name-rev: accept list of refs from user
  2007-02-17 23:13                 ` [PATCH] git-name-rev: accept list of refs from user Jeff King
@ 2007-02-17 23:19                   ` Jeff King
  2007-02-17 23:30                     ` Junio C Hamano
  0 siblings, 1 reply; 22+ messages in thread
From: Jeff King @ 2007-02-17 23:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git

On Sat, Feb 17, 2007 at 06:13:28PM -0500, Jeff King wrote:

>   git show-ref | grep /v1 | git name-rev --refs-from=- $commit

BTW, I think this should be in addition to, not instead of, Johannes'
patch. I think for the simple filtering case, his syntax is much quicker
and more natural.

Of course, there will be plenty of conflicts merging them. :) I can do
the merge and resubmit after you publish Johannes' patch; just let me
know.

-Peff

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] git-name-rev: accept list of refs from user
  2007-02-17 23:19                   ` Jeff King
@ 2007-02-17 23:30                     ` Junio C Hamano
  2007-02-17 23:40                       ` Jeff King
  0 siblings, 1 reply; 22+ messages in thread
From: Junio C Hamano @ 2007-02-17 23:30 UTC (permalink / raw)
  To: Jeff King; +Cc: Johannes Schindelin, git

Jeff King <peff@peff.net> writes:

> On Sat, Feb 17, 2007 at 06:13:28PM -0500, Jeff King wrote:
>
>>   git show-ref | grep /v1 | git name-rev --refs-from=- $commit
>
> BTW, I think this should be in addition to, not instead of, Johannes'
> patch. I think for the simple filtering case, his syntax is much quicker
> and more natural.
>
> Of course, there will be plenty of conflicts merging them. :) I can do
> the merge and resubmit after you publish Johannes' patch; just let me
> know.

I was hoping that everybody would be happy once Johannes's patch
is extended to grok more than one --refs=<pattern> options.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] git-name-rev: accept list of refs from user
  2007-02-17 23:30                     ` Junio C Hamano
@ 2007-02-17 23:40                       ` Jeff King
  2007-02-18  0:02                         ` Johannes Schindelin
  0 siblings, 1 reply; 22+ messages in thread
From: Jeff King @ 2007-02-17 23:40 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git

On Sat, Feb 17, 2007 at 03:30:02PM -0800, Junio C Hamano wrote:

> I was hoping that everybody would be happy once Johannes's patch
> is extended to grok more than one --refs=<pattern> options.

I don't think just having text filters easily allows something like:

  git show-ref |
    perl -ne 'print if m#tags/v1\.(\d+)# && $1 > 3' |
    git name-rev --refs-from=- $commit

But I don't know how many people will want to do something that complex.
I suppose you could mimic it with many --refs, but the syntax gets a bit
painful.

-Peff

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] name-rev: introduce the --ref-filter=<pattern> option
  2007-02-17 18:47                 ` Junio C Hamano
@ 2007-02-17 23:55                   ` Johannes Schindelin
  0 siblings, 0 replies; 22+ messages in thread
From: Johannes Schindelin @ 2007-02-17 23:55 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Hi,

On Sat, 17 Feb 2007, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > Instead of (or, in addition to) --tags, to use only tags for naming,
> > you can now use --ref-filter=<patter> to specify a shell pattern
> > which the refs must match to be used for naming.
> >
> > Example:
> >
> > 	$ git name-rev --ref-filter=*v1* 33db5f4d
> > 	33db5f4d tags/v1.0rc1^0~1593
> 
> I am sorry I did not mention earlier, but doesn't --ref-filter
> sound too long?  How about '--refs=*v1*'?
> 
> No need to resend, just Ack / Nack would do.

Ack. I am okay with any change, since I will probably not use it anyway. 
name-rev is usable to me, but since you said it is not to you, I wanted to 
change _that_.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] git-name-rev: accept list of refs from user
  2007-02-17 23:40                       ` Jeff King
@ 2007-02-18  0:02                         ` Johannes Schindelin
  0 siblings, 0 replies; 22+ messages in thread
From: Johannes Schindelin @ 2007-02-18  0:02 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git

Hi,

On Sat, 17 Feb 2007, Jeff King wrote:

> On Sat, Feb 17, 2007 at 03:30:02PM -0800, Junio C Hamano wrote:
> 
> > I was hoping that everybody would be happy once Johannes's patch
> > is extended to grok more than one --refs=<pattern> options.
> 
> I don't think just having text filters easily allows something like:
> 
>   git show-ref |
>     perl -ne 'print if m#tags/v1\.(\d+)# && $1 > 3' |
>     git name-rev --refs-from=- $commit

Does

	git name-rev --refs='*v1.[4-]*' $commit

what you are trying to achieve?

However, another use case could be where you do not want to tag a certain 
commit, but want to label it with a certin name just for this call to 
name-rev. But I don't know how useful that is.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2007-02-18  0:02 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-27  4:06 finding earliest tags descended from a given commit J. Bruce Fields
2007-01-27  4:22 ` Shawn O. Pearce
2007-01-27  4:34 ` Linus Torvalds
2007-01-27  4:42   ` J. Bruce Fields
2007-01-27  4:55     ` Shawn O. Pearce
2007-01-27  5:23       ` Junio C Hamano
2007-01-27 12:39         ` [PATCH] name-rev: introduce the --ref-filter=<regex> option Johannes Schindelin
2007-02-17 14:02           ` Johannes Schindelin
2007-02-17 14:59             ` Jeff King
2007-02-17 17:50               ` Johannes Schindelin
2007-02-17 18:25               ` Junio C Hamano
2007-02-17 23:13                 ` [PATCH] git-name-rev: accept list of refs from user Jeff King
2007-02-17 23:19                   ` Jeff King
2007-02-17 23:30                     ` Junio C Hamano
2007-02-17 23:40                       ` Jeff King
2007-02-18  0:02                         ` Johannes Schindelin
2007-02-17 17:42             ` [PATCH] name-rev: introduce the --ref-filter=<regex> option Junio C Hamano
2007-02-17 18:01               ` Johannes Schindelin
2007-02-17 18:22               ` [PATCH] name-rev: introduce the --ref-filter=<pattern> option Johannes Schindelin
2007-02-17 18:47                 ` Junio C Hamano
2007-02-17 23:55                   ` Johannes Schindelin
2007-02-17 19:00                 ` Junio C Hamano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.