{"thread":{"id":"6555","subject":"finding earliest tags descended from a given commit","startedAt":"2007-01-27T04:06:18Z","lastAt":"2007-02-18T00:02:28Z","messageCount":22,"participants":["J. Bruce Fields","Shawn O. Pearce","Linus Torvalds","Junio C Hamano","Johannes Schindelin","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"32796","messageId":"20070127040618.GA14205@fieldses.org","threadId":"6555","inReplyTo":null,"subject":"finding earliest tags descended from a given commit","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-01-27T04:06:18Z","receivedAt":"2007-01-27T04:06:18Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"Just curious: every now and then somebody will ask me what kernel\nversion they need to upgrade to to get some given fix.  I can find the\ncommit with the given fix easily enough.  How do I then find the\nearliest tagged version containing that fix?\n\nMore generally, given a commit, is there a quick way to find the set of\ntags which tag commits descended from the given commit?  Or to get the\nsubset of such tags which are earliest (in the sense that they're not\ndescendants of any of the others)?\n\nI usually just do\n\n\tgit-describe <commit>\n\nto make a guess, then\n\n\tgit log <tag>..<commit>\n\nto verify, but perhaps there's something more clever, or something that\nwould work better in a project where the tags aren't necessarily all in\na straight line.\n\n--b.\n"},{"id":"32797","messageId":"20070127042235.GA9966@spearce.org","threadId":"6555","inReplyTo":"20070127040618.GA14205@fieldses.org","subject":"Re: finding earliest tags descended from a given commit","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-01-27T04:22:35Z","receivedAt":"2007-01-27T04:22:35Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"\"J. Bruce Fields\" <bfields@fieldses.org> wrote:\n> Just curious: every now and then somebody will ask me what kernel\n> version they need to upgrade to to get some given fix.  I can find the\n> commit with the given fix easily enough.  How do I then find the\n> earliest tagged version containing that fix?\n\ngit-name-rev commit?\n\nIt should give you not only the tag, but how many commits before\nthat tag the fix was made.\n\n-- \nShawn.\n"},{"id":"32798","messageId":"Pine.LNX.4.64.0701262022230.25027@woody.linux-foundation.org","threadId":"6555","inReplyTo":"20070127040618.GA14205@fieldses.org","subject":"Re: finding earliest tags descended from a given commit","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-01-27T04:34:15Z","receivedAt":"2007-01-27T04:34:15Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 26 Jan 2007, J. Bruce Fields wrote:\n>\n> Just curious: every now and then somebody will ask me what kernel\n> version they need to upgrade to to get some given fix.  I can find the\n> commit with the given fix easily enough.  How do I then find the\n> earliest tagged version containing that fix?\n\nYou can name any revision based on the set of tags you have with:\n\n\tgit name-rev --tags <sha1-of-commit>\n\nwhich will try to find the \"simplest\" way to name something by following \none of your tags.\n\nIf no tag can be found that reaches that commit, it will say\n\n\t<sha1> undefined\n\nbut otherwise you will get something like this:\n\n\t[torvalds@woody linux]$ git name-rev --tags 7658cc28\n\t7658cc28 tags/v2.6.20-rc3^0~58\n\n(That's the \"VM: Fix nasty and subtle race in shared mmap'ed page \nwriteback commit\").\n\nSo that basically tells you that it's the 58'th parent of v2.6.20-rc3, ie \nit was in -rc3, but not in -rc2.\n\n> I usually just do\n> \n> \tgit-describe <commit>\n> \n> to make a guess, then\n> \n> \tgit log <tag>..<commit>\n\nYeah. That mostly works too, and kind of for the right reason: it's a \nrelated operation. But as you can tell, git-describe tells you which \nversion somethign is *based* on, not when it was merged, so while it gives \nyou a starting point for your search, it's not what you want.\n\nBasically 'git descibe' goes the \"other way\": it walks backwards from the \ncommit to the nearest tag that can be found, while 'git name-rev --tags' \nwalks the history backwards from the tags, and tries to find the commit. \n\nNOTE! 'git name-rev' can in theory be quite expensive, although if you \nhave a packed repository you'll probably never even notice it.\n\n\t\tLinus\n"},{"id":"32799","messageId":"20070127044246.GC14205@fieldses.org","threadId":"6555","inReplyTo":"Pine.LNX.4.64.0701262022230.25027@woody.linux-foundation.org","subject":"Re: finding earliest tags descended from a given commit","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-01-27T04:42:46Z","receivedAt":"2007-01-27T04:42:46Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Fri, Jan 26, 2007 at 08:34:15PM -0800, Linus Torvalds wrote:\n> On Fri, 26 Jan 2007, J. Bruce Fields wrote:\n> >\n> > Just curious: every now and then somebody will ask me what kernel\n> > version they need to upgrade to to get some given fix.  I can find the\n> > commit with the given fix easily enough.  How do I then find the\n> > earliest tagged version containing that fix?\n> \n> You can name any revision based on the set of tags you have with:\n> \n> \tgit name-rev --tags <sha1-of-commit>\n> \n> which will try to find the \"simplest\" way to name something by following \n> one of your tags.\n\nThat's interesting, I hadn't noticed name-rev before you and Shawn\nmentioned it.\n\nIt only finds one name, though. When I tried it just now on my\nrepository what it found was a tag I'd created for an experimental\nversion, which probably wouldn't be what I wanted.  (Though it might be,\nin some situations.)\n\n--b.\n"},{"id":"32800","messageId":"20070127045552.GB9966@spearce.org","threadId":"6555","inReplyTo":"20070127044246.GC14205@fieldses.org","subject":"Re: finding earliest tags descended from a given commit","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-01-27T04:55:52Z","receivedAt":"2007-01-27T04:55:52Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"\"J. Bruce Fields\" <bfields@fieldses.org> wrote:\n> That's interesting, I hadn't noticed name-rev before you and Shawn\n> mentioned it.\n> \n> It only finds one name, though. When I tried it just now on my\n> repository what it found was a tag I'd created for an experimental\n> version, which probably wouldn't be what I wanted.  (Though it might be,\n> in some situations.)\n\nYea. Hmm.  Maybe name-rev needs to learn a few more tricks, like\nfavoring annotated tags over non-annotated ones/heads, and being\nable to print the top n nearest matches (e.g. 10), by displaying\nonly one line of output per tag (or ref).\n\nRight now I'm trying to educate describe some more.  Although\nsimilar, describe has a much easier job as its very easy for it to\nsay \"that's the best name we have for the input\".  Part of that is\nbecause it is favoring annotated tags all of the time, and part of\nthat is because it does this distance computation thing now and\nalways favors the tag with the shortest distance between the tag\nand the input.\n\nIn the case of name-rev I'm thinking maybe its actually the longest\ndistance annotated tag that makes sense.  That is, prefer to name\nthe input using the annotated tag which has the shortest distance\nbetween the tag and the input, but where the tag is the farthest\nback in history you can go when compared to any other possible tag,\nand yet stills contains the input in its ancestry.\n\n-- \nShawn.\n"},{"id":"32801","messageId":"7vhcudoxfj.fsf@assigned-by-dhcp.cox.net","threadId":"6555","inReplyTo":"20070127045552.GB9966@spearce.org","subject":"Re: finding earliest tags descended from a given commit","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-01-27T05:23:12Z","receivedAt":"2007-01-27T05:23:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> \"J. Bruce Fields\" <bfields@fieldses.org> wrote:\n>> That's interesting, I hadn't noticed name-rev before you and Shawn\n>> mentioned it.\n>> \n>> It only finds one name, though. When I tried it just now on my\n>> repository what it found was a tag I'd created for an experimental\n>> version, which probably wouldn't be what I wanted.  (Though it might be,\n>> in some situations.)\n>\n> Yea. Hmm.  Maybe name-rev needs to learn a few more tricks, like\n> favoring annotated tags over non-annotated ones/heads, and being\n> able to print the top n nearest matches (e.g. 10), by displaying\n> only one line of output per tag (or ref).\n\nYeah, I found name-rev to be mostly useless since it almost\nalways names relative to my unannotated \"anchor\" tag that I use\nto keep track of 'master' I sent the last \"What's in\" message\nfor.\n\nI think doing parallel merge-base computation that is in\nshow-branch and the updated describe would be a sensible\napproach.  When somebody says such and such does not work yet in\nhis version, after identifying the commit that introduced that\nfeature, I would run \"show-branch $that_rev 'tags/v1.*'\" to see\nwhich tag(s) contain that revision.\n"},{"id":"32830","messageId":"Pine.LNX.4.63.0701271334410.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6555","inReplyTo":"7vhcudoxfj.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] name-rev: introduce the --ref-filter=<regex> option","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-01-27T12:39:07Z","receivedAt":"2007-01-27T12:39:07Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nInstead of (or, in addition to) --tags, to use only tags for naming,\nyou can now use --ref-filter=<regex> to specify which refs are\nused for naming.\n\nExample:\n\n\t$ git name-rev --ref-filter='/v1' 33db5f4d\n\t33db5f4d tags/v1.0rc1^0~1593\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n---\n\n\tOn Fri, 26 Jan 2007, Junio C Hamano wrote:\n\n\t> Yeah, I found name-rev to be mostly useless since it almost\n\t> always names relative to my unannotated \"anchor\" tag that I use\n\t> to keep track of 'master' I sent the last \"What's in\" message\n\t> for.\n\n\tHow about this?\n\n\tThough I think you'd use --ref-filter='tags/v[0-9]'. Or you would \n\talias it:\n\n\t\tgit-repo-config alias.findver \\\n\t\t\t\"name-rev --ref-filter='tags/v[0-9]'\"\n\n Documentation/git-name-rev.txt |   14 ++++++++++++--\n builtin-name-rev.c             |   27 +++++++++++++++++++++------\n 2 files changed, 33 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt\nindex 37fbf66..7de4bea 100644\n--- a/Documentation/git-name-rev.txt\n+++ b/Documentation/git-name-rev.txt\n@@ -8,7 +8,7 @@ git-name-rev - Find symbolic names for given revs\n \n SYNOPSIS\n --------\n-'git-name-rev' [--tags] ( --all | --stdin | <committish>... )\n+'git-name-rev' [--tags | --ref-filter=<regex>] ( --all | --stdin | <committish>... )\n \n DESCRIPTION\n -----------\n@@ -22,6 +22,9 @@ OPTIONS\n --tags::\n \tDo not use branch names, but only tags to name the commits\n \n+--ref-filter=<regex>::\n+\tOnly use refs for naming which match the regexp\n+\n --all::\n \tList all commits reachable from all refs\n \n@@ -29,7 +32,7 @@ OPTIONS\n \tRead from stdin, append \"(<rev_name>)\" to all sha1's of nameable\n \tcommits, and pass to stdout\n \n-EXAMPLE\n+EXAMPLES\n -------\n \n Given a commit, find out where it is relative to the local refs. Say somebody\n@@ -52,6 +55,13 @@ Another nice thing you can do is:\n % git log | git name-rev --stdin\n ------------\n \n+If you want to name a revision only by a subset of the refs you have, use\n+a regular expression to specify the subset:\n+\n+------------\n+$ git name-rev --ref-filter='/v1' 33db5f4d\n+33db5f4d tags/v1.0rc1^0~1593\n+------------\n \n Author\n ------\ndiff --git a/builtin-name-rev.c b/builtin-name-rev.c\nindex b4f15cc..89ea95d 100644\n--- a/builtin-name-rev.c\n+++ b/builtin-name-rev.c\n@@ -3,9 +3,10 @@\n #include \"commit.h\"\n #include \"tag.h\"\n #include \"refs.h\"\n+#include <regex.h>\n \n static const char name_rev_usage[] =\n-\t\"git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\\n\";\n+\t\"git-name-rev [--tags | --ref-filter=<regexp>] ( --all | --stdin | committish [committish...] )\\n\";\n \n typedef struct rev_name {\n \tconst char *tip_name;\n@@ -74,13 +75,21 @@ copy_data:\n \t}\n }\n \n+struct name_ref_data {\n+\tint tags_only;\n+\tregex_t *ref_filter;\n+};\n+\n static int name_ref(const char *path, const unsigned char *sha1, int flags, void *cb_data)\n {\n \tstruct object *o = parse_object(sha1);\n-\tint tags_only = *(int*)cb_data;\n+\tstruct name_ref_data *data = cb_data;\n \tint deref = 0;\n \n-\tif (tags_only && strncmp(path, \"refs/tags/\", 10))\n+\tif (data->tags_only && strncmp(path, \"refs/tags/\", 10))\n+\t\treturn 0;\n+\n+\tif (data->ref_filter && regexec(data->ref_filter, path, 0, NULL, 0))\n \t\treturn 0;\n \n \twhile (o && o->type == OBJ_TAG) {\n@@ -129,7 +138,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)\n {\n \tstruct object_array revs = { 0, 0, NULL };\n \tint as_is = 0, all = 0, transform_stdin = 0;\n-\tint tags_only = 0;\n+\tstruct name_ref_data data = { 0, NULL };\n \n \tgit_config(git_default_config);\n \n@@ -146,7 +155,13 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)\n \t\t\t\tas_is = 1;\n \t\t\t\tcontinue;\n \t\t\t} else if (!strcmp(*argv, \"--tags\")) {\n-\t\t\t\ttags_only = 1;\n+\t\t\t\tdata.tags_only = 1;\n+\t\t\t\tcontinue;\n+\t\t\t} else  if (!strncmp(*argv, \"--ref-filter=\", 13)) {\n+\t\t\t\tdata.ref_filter = xmalloc(sizeof(regex_t));\n+\t\t\t\tif (regcomp(data.ref_filter, *argv + 13,\n+\t\t\t\t\t\t\tREG_EXTENDED))\n+\t\t\t\t\tdie (\"invalid regexp: %s\", *argv + 13);\n \t\t\t\tcontinue;\n \t\t\t} else if (!strcmp(*argv, \"--all\")) {\n \t\t\t\tif (argc > 1)\n@@ -185,7 +200,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)\n \t\tadd_object_array((struct object *)commit, *argv, &revs);\n \t}\n \n-\tfor_each_ref(name_ref, &tags_only);\n+\tfor_each_ref(name_ref, &data);\n \n \tif (transform_stdin) {\n \t\tchar buffer[2048];\n-- \n1.5.0.rc2.g324a-dirty\n"},{"id":"34869","messageId":"Pine.LNX.4.63.0702171502040.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6555","inReplyTo":"Pine.LNX.4.63.0701271334410.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-17T14:02:36Z","receivedAt":"2007-02-17T14:02:36Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 27 Jan 2007, Johannes Schindelin wrote:\n\n> Instead of (or, in addition to) --tags, to use only tags for naming,\n> you can now use --ref-filter=<regex> to specify which refs are\n> used for naming.\n> \n> Example:\n> \n> \t$ git name-rev --ref-filter='/v1' 33db5f4d\n> \t33db5f4d tags/v1.0rc1^0~1593\n\nLikes, dislikes?\n\nCiao,\nDscho\n"},{"id":"34873","messageId":"20070217145921.GA16747@coredump.intra.peff.net","threadId":"6555","inReplyTo":"Pine.LNX.4.63.0702171502040.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-02-17T14:59:21Z","receivedAt":"2007-02-17T14:59:21Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Feb 17, 2007 at 03:02:36PM +0100, Johannes Schindelin wrote:\n\n> > Instead of (or, in addition to) --tags, to use only tags for naming,\n> > you can now use --ref-filter=<regex> to specify which refs are\n> > used for naming.\n> > \n> > Example:\n> > \n> > \t$ git name-rev --ref-filter='/v1' 33db5f4d\n> > \t33db5f4d tags/v1.0rc1^0~1593\n> \n> Likes, dislikes?\n\nIt's a neat idea, but I wonder if you could make it even more flexible\nby simply accepting a list of possible refs, and then you could filter\nusing grep, or your own more complex selection algorithm.\nUnfortunately, --stdin is already taken, but something like:\n\ngit show-ref | grep tags/v1.4 | git name-rev --stdin-refs 33db5f4d\n\nIf the stdin ref format includes both the refname and the hash, you\ncould even find 'fake' refs that don't exist in git (e.g., that you get\nfrom a foreign SCM; though why you wouldn't just make git tags for them,\nI don't know).\n\nOr maybe this is just making the problem too complex, and nobody really\nwants to do it. I certainly don't have a use at this point, but if\nyou're going to do ref filtering, it seems like making it as general as\n(painlessly) possible is useful.\n\n-Peff\n"},{"id":"34876","messageId":"7vlkiwvfy5.fsf@assigned-by-dhcp.cox.net","threadId":"6555","inReplyTo":"Pine.LNX.4.63.0702171502040.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-17T17:42:26Z","receivedAt":"2007-02-17T17:42:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> Instead of (or, in addition to) --tags, to use only tags for naming,\n>> you can now use --ref-filter=<regex> to specify which refs are\n>> used for naming.\n>> \n>> Example:\n>> \n>> \t$ git name-rev --ref-filter='/v1' 33db5f4d\n>> \t33db5f4d tags/v1.0rc1^0~1593\n>\n> Likes, dislikes?\n\n\"Describe these objects in terms of these refs -- do not use any\nother random refs, even if they are closer\" was sorely lacking\nfor it to be usable for me, so I like what it does.\n\nWhen we talk about path and path-like things including refs\nI think we consistently use fnmatch not regexp.  At least I\nthink we try to.\n"},{"id":"34878","messageId":"Pine.LNX.4.63.0702171840140.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6555","inReplyTo":"20070217145921.GA16747@coredump.intra.peff.net","subject":"Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-17T17:50:51Z","receivedAt":"2007-02-17T17:50:51Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 17 Feb 2007, Jeff King wrote:\n\n> On Sat, Feb 17, 2007 at 03:02:36PM +0100, Johannes Schindelin wrote:\n> \n> > > Instead of (or, in addition to) --tags, to use only tags for naming,\n> > > you can now use --ref-filter=<regex> to specify which refs are\n> > > used for naming.\n> > > \n> > > Example:\n> > > \n> > > \t$ git name-rev --ref-filter='/v1' 33db5f4d\n> > > \t33db5f4d tags/v1.0rc1^0~1593\n> > \n> > Likes, dislikes?\n> \n> It's a neat idea, but I wonder if you could make it even more flexible\n> by simply accepting a list of possible refs, and then you could filter\n> using grep, or your own more complex selection algorithm.\n\nYou can do that with regexps also. And you're right, my code was meant to \nbe simple...\n\nCiao,\nDscho\n"},{"id":"34880","messageId":"Pine.LNX.4.63.0702171901310.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6555","inReplyTo":"7vlkiwvfy5.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-17T18:01:43Z","receivedAt":"2007-02-17T18:01:43Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 17 Feb 2007, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> >> Instead of (or, in addition to) --tags, to use only tags for naming,\n> >> you can now use --ref-filter=<regex> to specify which refs are\n> >> used for naming.\n> >> \n> >> Example:\n> >> \n> >> \t$ git name-rev --ref-filter='/v1' 33db5f4d\n> >> \t33db5f4d tags/v1.0rc1^0~1593\n> >\n> > Likes, dislikes?\n> \n> \"Describe these objects in terms of these refs -- do not use any\n> other random refs, even if they are closer\" was sorely lacking\n> for it to be usable for me, so I like what it does.\n> \n> When we talk about path and path-like things including refs\n> I think we consistently use fnmatch not regexp.  At least I\n> think we try to.\n\nOkay. Will rework.\n\nCiao,\nDscho\n"},{"id":"34883","messageId":"Pine.LNX.4.63.0702171921130.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6555","inReplyTo":"7vlkiwvfy5.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] name-rev: introduce the --ref-filter=<pattern> option","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-17T18:22:35Z","receivedAt":"2007-02-17T18:22:35Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nInstead of (or, in addition to) --tags, to use only tags for naming,\nyou can now use --ref-filter=<patter> to specify a shell pattern\nwhich the refs must match to be used for naming.\n\nExample:\n\n\t$ git name-rev --ref-filter=*v1* 33db5f4d\n\t33db5f4d tags/v1.0rc1^0~1593\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n---\n\n\tOn Sat, 17 Feb 2007, Junio C Hamano wrote:\n\n\t> When we talk about path and path-like things including refs\n\t> I think we consistently use fnmatch not regexp.  At least I\n\t> think we try to.\n\n\tAnd this patch does exactly that.\n\n Documentation/git-name-rev.txt |    6 +++++-\n builtin-name-rev.c             |   23 +++++++++++++++++------\n 2 files changed, 22 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt\nindex 37fbf66..a99d60b 100644\n--- a/Documentation/git-name-rev.txt\n+++ b/Documentation/git-name-rev.txt\n@@ -8,7 +8,8 @@ git-name-rev - Find symbolic names for given revs\n \n SYNOPSIS\n --------\n-'git-name-rev' [--tags] ( --all | --stdin | <committish>... )\n+'git-name-rev' [--tags] [--ref-filter=<pattern>]\n+\t       ( --all | --stdin | <committish>... )\n \n DESCRIPTION\n -----------\n@@ -22,6 +23,9 @@ OPTIONS\n --tags::\n \tDo not use branch names, but only tags to name the commits\n \n+--ref-filter=<pattern>::\n+\tOnly use refs whose names match a given shell pattern.\n+\n --all::\n \tList all commits reachable from all refs\n \ndiff --git a/builtin-name-rev.c b/builtin-name-rev.c\nindex b4f15cc..615af4b 100644\n--- a/builtin-name-rev.c\n+++ b/builtin-name-rev.c\n@@ -5,7 +5,7 @@\n #include \"refs.h\"\n \n static const char name_rev_usage[] =\n-\t\"git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\\n\";\n+\t\"git-name-rev [--tags | --ref-filter=<pattern>] ( --all | --stdin | committish [committish...] )\\n\";\n \n typedef struct rev_name {\n \tconst char *tip_name;\n@@ -74,13 +74,21 @@ copy_data:\n \t}\n }\n \n+struct name_ref_data {\n+\tint tags_only;\n+\tconst char *ref_filter;\n+};\n+\n static int name_ref(const char *path, const unsigned char *sha1, int flags, void *cb_data)\n {\n \tstruct object *o = parse_object(sha1);\n-\tint tags_only = *(int*)cb_data;\n+\tstruct name_ref_data *data = cb_data;\n \tint deref = 0;\n \n-\tif (tags_only && strncmp(path, \"refs/tags/\", 10))\n+\tif (data->tags_only && strncmp(path, \"refs/tags/\", 10))\n+\t\treturn 0;\n+\n+\tif (data->ref_filter && fnmatch(data->ref_filter, path, 0))\n \t\treturn 0;\n \n \twhile (o && o->type == OBJ_TAG) {\n@@ -129,7 +137,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)\n {\n \tstruct object_array revs = { 0, 0, NULL };\n \tint as_is = 0, all = 0, transform_stdin = 0;\n-\tint tags_only = 0;\n+\tstruct name_ref_data data = { 0, NULL };\n \n \tgit_config(git_default_config);\n \n@@ -146,7 +154,10 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)\n \t\t\t\tas_is = 1;\n \t\t\t\tcontinue;\n \t\t\t} else if (!strcmp(*argv, \"--tags\")) {\n-\t\t\t\ttags_only = 1;\n+\t\t\t\tdata.tags_only = 1;\n+\t\t\t\tcontinue;\n+\t\t\t} else  if (!strncmp(*argv, \"--ref-filter=\", 13)) {\n+\t\t\t\tdata.ref_filter = *argv + 13;\n \t\t\t\tcontinue;\n \t\t\t} else if (!strcmp(*argv, \"--all\")) {\n \t\t\t\tif (argc > 1)\n@@ -185,7 +196,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)\n \t\tadd_object_array((struct object *)commit, *argv, &revs);\n \t}\n \n-\tfor_each_ref(name_ref, &tags_only);\n+\tfor_each_ref(name_ref, &data);\n \n \tif (transform_stdin) {\n \t\tchar buffer[2048];\n-- \n1.5.0.2139.gdafc9-dirty\n"},{"id":"34885","messageId":"7vmz3ctzer.fsf@assigned-by-dhcp.cox.net","threadId":"6555","inReplyTo":"20070217145921.GA16747@coredump.intra.peff.net","subject":"Re: [PATCH] name-rev: introduce the --ref-filter=<regex> option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-17T18:25:00Z","receivedAt":"2007-02-17T18:25:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Sat, Feb 17, 2007 at 03:02:36PM +0100, Johannes Schindelin wrote:\n>\n>> > Instead of (or, in addition to) --tags, to use only tags for naming,\n>> > you can now use --ref-filter=<regex> to specify which refs are\n>> > used for naming.\n>> > \n>> > Example:\n>> > \n>> > \t$ git name-rev --ref-filter='/v1' 33db5f4d\n>> > \t33db5f4d tags/v1.0rc1^0~1593\n>> \n>> Likes, dislikes?\n>\n> It's a neat idea, but I wonder if you could make it even more flexible\n> by simply accepting a list of possible refs, and then you could filter\n> using grep, or your own more complex selection algorithm.\n> Unfortunately, --stdin is already taken, but something like:\n>\n> git show-ref | grep tags/v1.4 | git name-rev --stdin-refs 33db5f4d\n\nFWIW, I like that.\n"},{"id":"34888","messageId":"7vabzctydf.fsf@assigned-by-dhcp.cox.net","threadId":"6555","inReplyTo":"Pine.LNX.4.63.0702171921130.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] name-rev: introduce the --ref-filter=<pattern> option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-17T18:47:24Z","receivedAt":"2007-02-17T18:47:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Instead of (or, in addition to) --tags, to use only tags for naming,\n> you can now use --ref-filter=<patter> to specify a shell pattern\n> which the refs must match to be used for naming.\n>\n> Example:\n>\n> \t$ git name-rev --ref-filter=*v1* 33db5f4d\n> \t33db5f4d tags/v1.0rc1^0~1593\n\nI am sorry I did not mention earlier, but doesn't --ref-filter\nsound too long?  How about '--refs=*v1*'?\n\nNo need to resend, just Ack / Nack would do.\n"},{"id":"34889","messageId":"7v3b54txrk.fsf@assigned-by-dhcp.cox.net","threadId":"6555","inReplyTo":"Pine.LNX.4.63.0702171921130.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] name-rev: introduce the --ref-filter=<pattern> option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-17T19:00:31Z","receivedAt":"2007-02-17T19:00:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Instead of (or, in addition to) --tags, to use only tags for naming,\n> you can now use --ref-filter=<patter> to specify a shell pattern\n> which the refs must match to be used for naming.\n>\n> Example:\n>\n> \t$ git name-rev --ref-filter=*v1* 33db5f4d\n> \t33db5f4d tags/v1.0rc1^0~1593\n>\n> Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\nThanks.  It's a bit counterintuitive that the first asterisk in\nyour example \"*v1*\" matches something that contains a slash, but\nat least the patch makes it usable for me.\n\nBy the way, v1.0rc1^0~1593 is the same as v1.0rc1~1593.\nTechnically, the latter loses the information that the starting\nref is a tag, but I wonder if it is worth keeping that\ninformation at the expense of (slightly) uglier output.\n"},{"id":"34899","messageId":"20070217231327.GA5382@coredump.intra.peff.net","threadId":"6555","inReplyTo":"7vmz3ctzer.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] git-name-rev: accept list of refs from user","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-02-17T23:13:28Z","receivedAt":"2007-02-17T23:13:28Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"This lets you do things like\n\n  git show-ref | grep /v1 | git name-rev --refs-from=- $commit\n\nor even\n\n  git show-ref | ./some_complex_ref_filter >refs\n  git name-rev --refs-from=refs --stdin <list_of_commits\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nOn Sat, Feb 17, 2007 at 10:25:00AM -0800, Junio C Hamano wrote:\n>> git show-ref | grep tags/v1.4 | git name-rev --stdin-refs 33db5f4d\n> FWIW, I like that.\n\nHere it is (I chose --refs-from= so you could use it with the existing\n--stdin flag). We might want to do the same for git-describe, I would\nthink (they can probably share the for_each_ref_from_file code).\n\nThe input format is \"sha1 ref\"; clearly it could also accept just \"ref\",\nand look up the sha1, but I expect most people will just be piping from\ngit-show-ref anyway.\n\n Documentation/git-name-rev.txt |   16 +++++++++++-\n builtin-name-rev.c             |   54 ++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 67 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt\nindex 37fbf66..d2fb3bb 100644\n--- a/Documentation/git-name-rev.txt\n+++ b/Documentation/git-name-rev.txt\n@@ -8,7 +8,7 @@ git-name-rev - Find symbolic names for given revs\n \n SYNOPSIS\n --------\n-'git-name-rev' [--tags] ( --all | --stdin | <committish>... )\n+'git-name-rev' [--tags] [--refs-from=<file>] ( --all | --stdin | <committish>... )\n \n DESCRIPTION\n -----------\n@@ -22,6 +22,13 @@ OPTIONS\n --tags::\n \tDo not use branch names, but only tags to name the commits\n \n+--refs-from=<file>::\n+\tInstead of choosing a name based on all refs, read refs from <file>,\n+\tone per line, in the form \"sha1 ref\". This is the same as the\n+\tdefault output generated by \"git show-ref\". If <file> is \"-\",\n+\tread from stdin. The --tags option is still respected when using\n+\t--refs-from.\n+\n --all::\n \tList all commits reachable from all refs\n \n@@ -52,6 +59,13 @@ Another nice thing you can do is:\n % git log | git name-rev --stdin\n ------------\n \n+You can filter the commits used to describe a commit using the --refs-from\n+option:\n+\n+------------\n+% git show-ref | grep tags/v1 | git name-rev --refs-from=- 26cfcfbf\n+------------\n+\n \n Author\n ------\ndiff --git a/builtin-name-rev.c b/builtin-name-rev.c\nindex b4f15cc..c8480d2 100644\n--- a/builtin-name-rev.c\n+++ b/builtin-name-rev.c\n@@ -5,7 +5,7 @@\n #include \"refs.h\"\n \n static const char name_rev_usage[] =\n-\t\"git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\\n\";\n+\"git-name-rev [--tags] [--refs-from=<file>] ( --all | --stdin | committish ... )\";\n \n typedef struct rev_name {\n \tconst char *tip_name;\n@@ -14,6 +14,7 @@ typedef struct rev_name {\n } rev_name;\n \n static long cutoff = LONG_MAX;\n+static const char *refs_from = NULL;\n \n static void name_rev(struct commit *commit,\n \t\tconst char *tip_name, int merge_traversals, int generation,\n@@ -103,6 +104,46 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void\n \treturn 0;\n }\n \n+static void trim_trailing_whitespace(char *buf)\n+{\n+\tint i = strlen(buf) - 1;\n+\twhile(i >= 0 && isspace(buf[i]))\n+\t\tbuf[i--] = '\\0';\n+}\n+\n+static void for_each_ref_from_file(const char *filename, each_ref_fn fn, void *data)\n+{\n+\tFILE *fh;\n+\tchar buf[PATH_MAX + 40 + 3]; /* \"PATH SHA1\\n\\0\" */\n+\tunsigned char sha1[20];\n+\n+\tif (!strcmp(filename, \"-\"))\n+\t\tfh = stdin;\n+\telse {\n+\t\tfh = fopen(filename, \"r\");\n+\t\tif (!fh)\n+\t\t\tdie(\"unable to open %s: %s\", filename, strerror(errno));\n+\t}\n+\n+\twhile (fgets(buf, sizeof buf, fh)) {\n+\t\tchar *name;\n+\n+\t\ttrim_trailing_whitespace(buf);\n+\n+\t\tname = strchr(buf, ' ');\n+\t\tif (!name)\n+\t\t\tdie(\"invalid input ref format: %s\\n\", buf);\n+\t\t*name++ = '\\0';\n+\n+\t\tif (get_sha1_hex(buf, sha1) < 0)\n+\t\t\tdie(\"invalid sha1: %s\\n\", buf);\n+\n+\t\tname_ref(name, sha1, 0, data);\n+\t}\n+\n+\tfclose(fh);\n+}\n+\n /* returns a static buffer */\n static const char* get_rev_name(struct object *o)\n {\n@@ -160,6 +201,9 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)\n \t\t\t\ttransform_stdin = 1;\n \t\t\t\tcutoff = 0;\n \t\t\t\tcontinue;\n+\t\t\t} else if (!strncmp(*argv, \"--refs-from=\", 12)) {\n+\t\t\t\trefs_from = (*argv)+12;\n+\t\t\t\tcontinue;\n \t\t\t}\n \t\t\tusage(name_rev_usage);\n \t\t}\n@@ -185,7 +229,13 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)\n \t\tadd_object_array((struct object *)commit, *argv, &revs);\n \t}\n \n-\tfor_each_ref(name_ref, &tags_only);\n+\tif (refs_from && !strcmp(refs_from, \"-\") && transform_stdin)\n+\t\tdie(\"--refs-from=- and --stdin are incompatible!\");\n+\n+\tif (refs_from)\n+\t\tfor_each_ref_from_file(refs_from, name_ref, &tags_only);\n+\telse\n+\t\tfor_each_ref(name_ref, &tags_only);\n \n \tif (transform_stdin) {\n \t\tchar buffer[2048];\n-- \n1.5.0.552.ge1b1c-dirty\n"},{"id":"34901","messageId":"20070217231943.GA30839@coredump.intra.peff.net","threadId":"6555","inReplyTo":"20070217231327.GA5382@coredump.intra.peff.net","subject":"Re: [PATCH] git-name-rev: accept list of refs from user","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-02-17T23:19:43Z","receivedAt":"2007-02-17T23:19:43Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Feb 17, 2007 at 06:13:28PM -0500, Jeff King wrote:\n\n>   git show-ref | grep /v1 | git name-rev --refs-from=- $commit\n\nBTW, I think this should be in addition to, not instead of, Johannes'\npatch. I think for the simple filtering case, his syntax is much quicker\nand more natural.\n\nOf course, there will be plenty of conflicts merging them. :) I can do\nthe merge and resubmit after you publish Johannes' patch; just let me\nknow.\n\n-Peff\n"},{"id":"34904","messageId":"7vr6soqs5h.fsf@assigned-by-dhcp.cox.net","threadId":"6555","inReplyTo":"20070217231943.GA30839@coredump.intra.peff.net","subject":"Re: [PATCH] git-name-rev: accept list of refs from user","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-17T23:30:02Z","receivedAt":"2007-02-17T23:30:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Sat, Feb 17, 2007 at 06:13:28PM -0500, Jeff King wrote:\n>\n>>   git show-ref | grep /v1 | git name-rev --refs-from=- $commit\n>\n> BTW, I think this should be in addition to, not instead of, Johannes'\n> patch. I think for the simple filtering case, his syntax is much quicker\n> and more natural.\n>\n> Of course, there will be plenty of conflicts merging them. :) I can do\n> the merge and resubmit after you publish Johannes' patch; just let me\n> know.\n\nI was hoping that everybody would be happy once Johannes's patch\nis extended to grok more than one --refs=<pattern> options.\n"},{"id":"34908","messageId":"20070217234046.GB6014@coredump.intra.peff.net","threadId":"6555","inReplyTo":"7vr6soqs5h.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-name-rev: accept list of refs from user","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-02-17T23:40:46Z","receivedAt":"2007-02-17T23:40:46Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Feb 17, 2007 at 03:30:02PM -0800, Junio C Hamano wrote:\n\n> I was hoping that everybody would be happy once Johannes's patch\n> is extended to grok more than one --refs=<pattern> options.\n\nI don't think just having text filters easily allows something like:\n\n  git show-ref |\n    perl -ne 'print if m#tags/v1\\.(\\d+)# && $1 > 3' |\n    git name-rev --refs-from=- $commit\n\nBut I don't know how many people will want to do something that complex.\nI suppose you could mimic it with many --refs, but the syntax gets a bit\npainful.\n\n-Peff\n"},{"id":"34910","messageId":"Pine.LNX.4.63.0702180054540.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6555","inReplyTo":"7vabzctydf.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] name-rev: introduce the --ref-filter=<pattern> option","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-17T23:55:41Z","receivedAt":"2007-02-17T23:55:41Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 17 Feb 2007, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > Instead of (or, in addition to) --tags, to use only tags for naming,\n> > you can now use --ref-filter=<patter> to specify a shell pattern\n> > which the refs must match to be used for naming.\n> >\n> > Example:\n> >\n> > \t$ git name-rev --ref-filter=*v1* 33db5f4d\n> > \t33db5f4d tags/v1.0rc1^0~1593\n> \n> I am sorry I did not mention earlier, but doesn't --ref-filter\n> sound too long?  How about '--refs=*v1*'?\n> \n> No need to resend, just Ack / Nack would do.\n\nAck. I am okay with any change, since I will probably not use it anyway. \nname-rev is usable to me, but since you said it is not to you, I wanted to \nchange _that_.\n\nCiao,\nDscho\n"},{"id":"34912","messageId":"Pine.LNX.4.63.0702180101030.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6555","inReplyTo":"20070217234046.GB6014@coredump.intra.peff.net","subject":"Re: [PATCH] git-name-rev: accept list of refs from user","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-18T00:02:28Z","receivedAt":"2007-02-18T00:02:28Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 17 Feb 2007, Jeff King wrote:\n\n> On Sat, Feb 17, 2007 at 03:30:02PM -0800, Junio C Hamano wrote:\n> \n> > I was hoping that everybody would be happy once Johannes's patch\n> > is extended to grok more than one --refs=<pattern> options.\n> \n> I don't think just having text filters easily allows something like:\n> \n>   git show-ref |\n>     perl -ne 'print if m#tags/v1\\.(\\d+)# && $1 > 3' |\n>     git name-rev --refs-from=- $commit\n\nDoes\n\n\tgit name-rev --refs='*v1.[4-]*' $commit\n\nwhat you are trying to achieve?\n\nHowever, another use case could be where you do not want to tag a certain \ncommit, but want to label it with a certin name just for this call to \nname-rev. But I don't know how useful that is.\n\nCiao,\nDscho\n"}]}