Subject: Re: [RFC/PATCH] tag: make list exclude !<pattern>

From: Michael Haggerty <[email-masked]>
Date: Sat, 11 Feb 2012 08:50:44 +0100

On 02/11/2012 04:06 AM, Junio C Hamano wrote:
> Tom Grennan <[email-masked]> writes:
>> The following series implements !<pattern> with: git-tag, git-branch, and
>> git-for-each-ref.
>>
>> This still requires Documentation and unit test updates but I think these are
>> close to functionally complete.
>
> Do we allow a refname whose pathname component begins with '!', by the
> way?  If we do, how does a user look for a tag whose name is "!xyzzy"?
> "Naming your tag !xyzzy used to be allowed but it is now forbidden after
> this patch" is not an acceptable answer---it is called a regression.  If
> the negation operator were "^" or something that we explicitly forbid from
> a refname, we wouldn't have such a problem.

According to git-check-ref-format(1), '!' are allowed in reference
names.  (Whether that was a good idea is another question, but now we
have to support it.)

So using "^" would be an option.  A problem is that the new meaning is
not consistent with the use of "^" in rev-list, and therefore would (1)
be confusing and (2) prevent the addition of a similar syntax in rev-list.

Currently,

    git rev-list A B ^C

means "revisions reachable from A or B but not from C".  (For simplicity
assume that A, B, and C are literal reference names without wildcards.)
 The proposal, amended to use "^" instead of "!", is that

    git for-each-ref A B ^C

should mean "the reference names A and B but not C".  Therefore, the command

    git rev-list $(git for-each-ref A B ^C)

, which consistency suggests should do the same thing as the first
command, would in fact be equivalent to

    git rev-list A B

Moreover, it *would* be nice to have this kind of exclude-branch-name
syntax in rev-parse.  Many times I have wanted to type the equivalent of

    gitk --all --not-branch=remotes/korg/*

That is, "show the commits starting at *all branches except for the
specified branches*".  This is different than "show *the commits
starting at all branches* except for *the commits reachable from the
specified branches*", because I want to see the *complete* history of
the non-excluded branches.  (Is there an easy way to do this now?)  The
proposed functionality is a step forward; I could type

    gitk $(git for-each-ref !remotes/korg/*)

But it would be even nicer if this could be expressed directly in rev-parse.

In summary, I suggest we consider using a more verbose syntax for this
new functionality (probably via one or more new options, for example
--not-branch=PATTERN, --not-tag=PATTERN, and/or --not-ref=PATTERN) that
cannot be confused with the existing syntax for excluding commits.

Michael

-- 
Michael Haggerty
[email-masked]
http://softwareswirl.blogspot.com/