threads / discuss / 46318

name-rev: anchor pattern without --exclude?

Subject: name-rev: anchor pattern without --exclude?

## tl;dr

5 messages between Jul 6, 2017 and Jul 6, 2017.

replies: 4people: 3as markdown or json

Kyle Meyer· Jul 6, 2017, 16:53 UTC · lore
Hello,

I'm trying to restrict name-rev's output to a ref whose name begins with the supplied pattern [*]. Looking at "man git-name-rev", builtin/name-rev.c, and wildmatch.c, I don't see a way to accomplish this with "--refs=<pattern>".

Say, for example, that I want to limit name-rev's output to a ref in the "refs/heads/" namespace.

    * cc8f7dc (master) c
    * ad6d6f0 b
    | * 49a2156 (refs/wip/wtree/refs/heads/master) d
    |/  
    * b91f97a a
    --------------------------------------------------
    $ git name-rev b91f97a
    b91f97a wip/wtree/refs/heads/master~1
    $ git name-rev --refs="refs/heads/*" b91f97a
    b91f97a wip/wtree/refs/heads/master~1
    $ git name-rev --refs="^refs/heads/*" b91f97a
    b91f97a undefined

Starting with v2.13.0, I can get my desired output using the --exclude option.

    $ git name-rev --refs="refs/heads/*" --exclude="*/refs/heads/*" b91f97a
    b91f97a master~2

But, unfortunately, I'm trying to find a solution that works with earlier Git versions (back to v1.9.4).

Am I overlooking a way to do this without the --exclude option?
[*] A bit more information on why I'm trying to do this: In Magit, we
    have a work-in-progress feature that takes "snapshots" of changes
    before they are committed.  These snapshots are stored as
    "refs/wip/{wtree,index}/<full refname>".
    We want to use name-rev to map a commit to a name in "refs/heads/",
    ignoring these snapshot refs.
-- 
Kyle
Junio C Hamano· Jul 6, 2017, 17:03 UTC · re: Kyle Meyer · lore

Re: name-rev: anchor pattern without --exclude?

Kyle Meyer <kyle@kyleam.com> writes:
Show 7 quoted lines
> [*] A bit more information on why I'm trying to do this: In Magit, we
>     have a work-in-progress feature that takes "snapshots" of changes
>     before they are committed.  These snapshots are stored as
>     "refs/wip/{wtree,index}/<full refname>".
>
>     We want to use name-rev to map a commit to a name in "refs/heads/",
>     ignoring these snapshot refs.

What is the <full refname> in the above supposed to represent? When a user sees two refs "refs/wip/{wtree,index}/<full refname>", does it mean: "These two represent a snapshot for changes while the user was working on this branch"?

Isn't name-rev a wrong tool to find that information? What is the answer desired by your application when two or more branches point at the same commit you are interested in? Pick one at random? An error saying it cannot decide where to place the snapshot?

I am wondering if you are looking for "symbolic-ref HEAD".
Kyle Meyer· Jul 6, 2017, 17:23 UTC · re: Junio C Hamano · lore

Re: name-rev: anchor pattern without --exclude?

Junio C Hamano <gitster@pobox.com> writes:
Show 11 quoted lines
> Kyle Meyer <kyle@kyleam.com> writes:
>
>> [*] A bit more information on why I'm trying to do this: In Magit, we
>>     have a work-in-progress feature that takes "snapshots" of changes
>>     before they are committed.  These snapshots are stored as
>>     "refs/wip/{wtree,index}/<full refname>".
>>
>>     We want to use name-rev to map a commit to a name in "refs/heads/",
>>     ignoring these snapshot refs.
>
> What is the <full refname> in the above supposed to represent?
It's the current branch, as returned by "git symbolic-ref HEAD".
> When a user sees two refs "refs/wip/{wtree,index}/<full refname>",
> does it mean: "These two represent a snapshot for changes while the
> user was working on this branch"?
Yes.
> Isn't name-rev a wrong tool to find that information?

Sorry for the confusion. We're using "symbolic-ref HEAD" to get the above information. I was just trying to explain why we're dealing with ref names that contain a "refs/heads" substring (like refs/wip/wtree/refs/heads/master in the example I gave).

> What is the answer desired by your application when two or more
> branches point at the same commit you are interested in?  Pick one at
> random?  An error saying it cannot decide where to place the snapshot?

Our use of name-rev is just to get a friendly name for a hash. If two branches point to the same commit, we're fine with whatever decision "git name-rev" makes; we just want to limit it to refs in the "refs/heads/" namespace.

-- 
Kyle
Bryan Turner· Jul 6, 2017, 18:02 UTC · re: Kyle Meyer · lore

Re: name-rev: anchor pattern without --exclude?

On Thu, Jul 6, 2017 at 10:23 AM, Kyle Meyer <kyle@kyleam.com> wrote:
Show 11 quoted lines
> Junio C Hamano <gitster@pobox.com> writes:
>> Kyle Meyer <kyle@kyleam.com> writes:
>
>> What is the answer desired by your application when two or more
>> branches point at the same commit you are interested in?  Pick one at
>> random?  An error saying it cannot decide where to place the snapshot?
>
> Our use of name-rev is just to get a friendly name for a hash.  If two
> branches point to the same commit, we're fine with whatever decision
> "git name-rev" makes; we just want to limit it to refs in the
> "refs/heads/" namespace.

If you don't need the ancestor traversals "git name-rev" provides, "git for-each-ref --count 1 --format "%(refname:short)" --points-at <hash> refs/heads/" might work. That only goes back to Git 2.7.0, though; still quite a ways off your 1.9 target. ("git branch --points-at" does the same thing, I should add, and only for branches, but you can't directly limit its output like you can with "for-each-ref".. Perhaps that doesn't matter for your use case.) If you want names like "master~2", from your example, though, "--points-at" won't do what you need.

Bryan
>
> --
> Kyle
Kyle Meyer· Jul 6, 2017, 18:26 UTC · re: Bryan Turner · lore

Re: name-rev: anchor pattern without --exclude?

Bryan Turner <bturner@atlassian.com> writes:
[...]
Show 9 quoted lines
> If you don't need the ancestor traversals "git name-rev" provides,
> "git for-each-ref --count 1 --format "%(refname:short)" --points-at
> <hash> refs/heads/" might work. That only goes back to Git 2.7.0,
> though; still quite a ways off your 1.9 target. ("git branch
> --points-at" does the same thing, I should add, and only for branches,
> but you can't directly limit its output like you can with
> "for-each-ref".. Perhaps that doesn't matter for your use case.) If
> you want names like "master~2", from your example, though,
> "--points-at" won't do what you need.

Thanks for the suggestion. Unfortunately, I do want to consider names like "master~2". I was just hoping that I had overlooked another way to achieve the

    git name-rev --refs="refs/heads/*" --exclude="*/refs/heads/*" <commit>
example I gave in my initial post.
-- 
Kyle

← back to recent threads