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

From: Junio C Hamano <[email-masked]>
Date: Sun, 12 Feb 2012 22:37:46 -0800

Michael Haggerty <[email-masked]> writes:

> Of *course* they operate on different namespaces.  But part of the way
> that revisions are selected using rev-list is by *selecting or excluding
> refnames* from which it should crawl.

I am appalled if that is truly the understanding of yours, after having
taken more than a few patches from you to fairly core parts of Git.

"rev-list A ^B" does not say "include A and exclude B from which rev-list
should crawl" AT ALL.  We _actively_ crawl from both A and B.  It is that
what are reachable from B is painted in a color different from the color
in which we paint what are reachable from A.

A better pair you could have mentioned would be for-each-ref vs rev-parse
(not rev-list).  What Tom wanted with "do not show the refs that match the
pattern" he originally wanted to give to "tag --list" would be

	for-each-ref A ^B

that is "show ref that matches A but do not show if it also matches B",
while what you want to say is "I want to paint A in positive color and
paint B in negative color, and I want to get a canonical notation to do
so", it is spelled with rev-parse, not for-each-ref, like this:

	rev-parse A ^B

In other words,

	git rev-list $(git rev-parse A ^B)

would be the equivalent to "git rev-list A ^B".

Maybe you are troubled that there are multiple concepts of negation, which
ultimately comes from the undeniable fact that for-each-ref and rev-parse
operate on entities in different concept domain (refnames and objects)?
And if we decide to use "^", then these two different concepts of negation
are both expressed with the same operator "prefix ^", leading to
confusion?

I am kind of sympathetic to that argument, and it might be a better idea
to avoid using "^" as the negation for matching operator, in order to make
it more apparent to the users that for-each-ref and rev-parse operate on
different concepts. But at the same time, if you know these are distinct
concepts, using the same "^" operator as a consistent way to express the
"negation" that is applicable in each concept domain does make it easier
for users as they gain experience. I tend to avoid making things too hard
for experienced users for the sake of flattening the very early learning
curve when possible, because nobody will stay novice forever.