From: Michael Haggerty <mhagger@alum.mit.edu>
To: Junio C Hamano <gitster@pobox.com>
Cc: Tom Grennan <tmgrennan@gmail.com>,
pclouds@gmail.com, git@vger.kernel.org, krh@redhat.com,
jasampler@gmail.com
Subject: Re: [RFC/PATCH] tag: make list exclude !<pattern>
Date: Mon, 13 Feb 2012 10:37:24 +0100 [thread overview]
Message-ID: <4F38D9D4.5000203@alum.mit.edu> (raw)
In-Reply-To: <7vsjifgrwl.fsf@alter.siamese.dyndns.org>
On 02/13/2012 07:37 AM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> 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.
Please read my emails more carefully before insulting me.
It is perfectly clear to me that there are two types of exclusion that
we are talking about. And *both* of them are (or should be) relevant to
rev-parse.
Take the following repository with three branches:
o---o---o---o A
\ \
\ o---o C
\
o---o B
If I do "git rev-list A B ^C" then I get the commits marked "*" in the
following diagram
o---o---o---* A
\ \
\ o---o C
\
*---* B
By excluding C I have necessarily excluded a part of the history of A and B.
If we assume that the proposed feature is implemented and I do "git
rev-list $(git for-each-ref --format='%(refname)' A B ^C)", then I get
something different:
*---*---*---* A
\ \
\ o---o C
\
*---* B
I argue that this is a useful selection. For example, maybe I want to
remove the clutter of branch C from my view, but I still want to see the
*whole* history of branches A and B. The middle selection doesn't do it.
Obviously this is not really necessary if there are only three branches,
but if there are dozens, and if A, B, and C are patterns rather than
literal branch names, then it can be very convenient.
For example, suppose I want to see the status of all of my submissions
in your repository in the context of your main branches plus my local
branches. It would be great to be able to type
gitk --with-branch='refs/heads/*' \
--with-branch='remotes/gitster/*' \
--without-branch='remotes/gitster/*/**' \
--with-branch='remotes/gitster/mh/*'
I don't know of a way to do that now.
> 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
That's not what I want; see above.
> 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?
Not only that, but also that both concepts of negation are interesting
and useful within "git rev-list", and therefore we should make them
*combinable*.
To be very explicit, I advocate:
1. Implement an explicit syntax for "do not include references matching
this pattern in a list of references". Implement this syntax in
for-each-ref; something like
--with-ref=PATTERN / --without-ref=PATTERN
--with-branch=PATTERN / --without-branch=PATTERN
--with-tag=PATTERN / --without-tag=PATTERN
--with-remote=PATTERN / --without-remote=PATTERN
The point of having multiple with/without pairs would be that the first
would match full refnames explicitly (i.e., the pattern would usually
start with "refs/"), whereas the other pairs would implicitly prepend
"refs/heads/", "refs/tags/", or "refs/remotes/", respectively, to the
pattern for convenience. There should also be an "--all" option that is
equivalent to "--with-ref=**".
The output from for-each-ref would essentially be a *list of positive
references* matching the criteria. In other words,
"--without-branch=foo" would cause "refs/heads/foo" to be *excluded*
from the output altogether, *not* included as "^refs/heads/foo".
The order of the options should be significant, with the last matching
pattern winning.
2. The pattern matching of refnames should be like fnmatch, with the
addition of "**" as a wildcard meaning "any characters, including '/'".
3. Other reference-listing commands should take the same options as
appropriate; for example, "git branch --list" would take
--with(out)?-branch and --with(out)?-remote (and maybe
--with(out)?-ref); "git tag --list" would take --with(out)?-tag (and
maybe --with(out)?-ref), etc.
4. The *exact same options* should be added to rev-list, and would
effectively be expanded into a list of positive references; e.g.,
git rev-list --with-branch=A --with-branch=B --without-branch=C
would be equivalent to
git rev-list $(git for-each-ref --format='%(refname)'
--with-branch=A --with-branch=B --without-branch=C)
If A, B, and C happen to be branch names rather than patterns, the above
would be equivalent to
git rev-list refs/heads/A refs/heads/B
Note that this *differs* (in a useful way!) from
git rev-list refs/heads/A refs/heads/B --not refs/heads/C
or
git rev-list refs/heads/A refs/heads/B ^refs/heads/C
which are useful in other scenarios and whose meanings we would of
course retain.
If "--not" is used in git-rev-list, it would demarcate groups of options
that are passed separately to for-each-ref; for example,
git rev-list --all --with-branch=A --without-branch=B \
--not --with-branch=C --without-branch=D
would be equivalent to
git rev-list $(git for-each-ref --format='%(refname)' --all
--with-branch=A --without-branch=B)\
--not $(git for-each-ref --format='%(refname)'
--with-branch=C --without-branch=D)
Michael
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
next prev parent reply other threads:[~2012-02-13 9:37 UTC|newest]
Thread overview: 83+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-09 19:43 [RFC/PATCH] tag: make list exclude !<pattern> Tom Grennan
2012-02-09 19:43 ` Tom Grennan
2012-02-10 0:00 ` Tom Grennan
2012-02-10 6:34 ` Nguyen Thai Ngoc Duy
2012-02-10 18:55 ` Tom Grennan
2012-02-11 2:16 ` Tom Grennan
2012-02-11 3:06 ` Junio C Hamano
2012-02-11 7:50 ` Junio C Hamano
2012-02-11 10:13 ` Jakub Narebski
2012-02-11 14:06 ` Nguyen Thai Ngoc Duy
2012-02-11 18:31 ` Junio C Hamano
2012-02-11 19:47 ` Tom Grennan
2012-02-11 7:50 ` Michael Haggerty
2012-02-11 8:13 ` Junio C Hamano
2012-02-13 5:29 ` Michael Haggerty
2012-02-13 6:37 ` Junio C Hamano
2012-02-13 9:37 ` Michael Haggerty [this message]
2012-02-13 10:23 ` Junio C Hamano
2012-02-13 14:34 ` Michael Haggerty
2012-02-13 20:29 ` Junio C Hamano
2012-02-11 19:08 ` Tom Grennan
2012-02-22 1:28 ` [PATCHv3 0/5] " Tom Grennan
2012-02-22 1:28 ` [PATCHv3 1/5] refs: add match_pattern() Tom Grennan
2012-02-22 6:33 ` Junio C Hamano
2012-02-22 23:47 ` Tom Grennan
2012-02-23 0:17 ` Junio C Hamano
2012-02-23 0:59 ` Tom Grennan
2012-02-22 1:28 ` [PATCHv3 2/5] tag --points-at option wrapper Tom Grennan
2012-02-22 1:28 ` [PATCHv3 3/5] tag --exclude option Tom Grennan
2012-02-22 6:33 ` Junio C Hamano
2012-02-23 0:22 ` Tom Grennan
2012-02-23 1:00 ` Junio C Hamano
2012-03-01 1:45 ` [PATCH 0/5] modernize test style Tom Grennan
2012-03-03 2:15 ` [PATCHv2 " Tom Grennan
2012-03-03 8:04 ` Junio C Hamano
2012-03-03 17:42 ` Tom Grennan
2012-03-03 2:15 ` [PATCHv2 1/5] t7004 (tag): modernize style Tom Grennan
2012-03-03 21:31 ` Johannes Sixt
2012-03-03 2:15 ` [PATCHv2 2/5] t5512 (ls-remote): " Tom Grennan
2012-03-03 8:05 ` Junio C Hamano
2012-03-03 17:33 ` Tom Grennan
2012-03-03 2:15 ` [PATCHv2 3/5] t3200 (branch): " Tom Grennan
2012-03-03 2:15 ` [PATCHv2 4/5] t0040 (parse-options): " Tom Grennan
2012-03-03 2:15 ` [PATCHv2 5/5] t6300 (for-each-ref): " Tom Grennan
2012-03-03 2:15 ` [PATCHv2-w 101/105] t7004 (tag): " Tom Grennan
2012-03-03 2:15 ` [PATCHv2-w 102/105] t5512 (ls-remote): " Tom Grennan
2012-03-03 2:15 ` [PATCHv2-w 103/105] t3200 (branch): " Tom Grennan
2012-03-03 2:15 ` [PATCHv2-w 104/105] t0040 (parse-options): " Tom Grennan
2012-03-03 2:15 ` [PATCHv2-w 105/105] t6300 (for-each-ref): " Tom Grennan
2012-03-01 1:45 ` [PATCH 1/5] " Tom Grennan
2012-03-01 6:53 ` Johannes Sixt
2012-03-01 15:58 ` Tom Grennan
2012-03-01 1:45 ` [PATCH 2/5] t5512 (ls-remote): " Tom Grennan
2012-03-01 8:36 ` Thomas Rast
2012-03-01 1:45 ` [PATCH 3/5] t3200 (branch): " Tom Grennan
2012-03-01 1:45 ` [PATCH 4/5] t0040 (parse-options): " Tom Grennan
2012-03-01 1:45 ` [PATCH 5/5] t7004 (tag): " Tom Grennan
2012-03-01 1:45 ` [PATCH-w 101/105] t6300 (for-each-ref): " Tom Grennan
2012-03-01 2:13 ` Junio C Hamano
2012-03-01 3:20 ` Tom Grennan
2012-03-01 3:26 ` Junio C Hamano
2012-03-01 5:10 ` Tom Grennan
2012-03-01 5:57 ` Tom Grennan
2012-03-01 8:42 ` Thomas Rast
2012-03-01 15:48 ` Tom Grennan
2012-03-01 1:45 ` [PATCH-w 102/105] t5512 (ls-remote): " Tom Grennan
2012-03-01 1:45 ` [PATCH-w 103/105] t3200 (branch): " Tom Grennan
2012-03-01 1:45 ` [PATCH-w 104/105] t0040 (parse-options): " Tom Grennan
2012-03-01 1:45 ` [PATCH-w 105/105] t7004 (tag): " Tom Grennan
2012-02-22 1:28 ` [PATCHv3 4/5] branch --exclude option Tom Grennan
2012-02-22 1:28 ` [PATCHv3 5/5] for-each-ref " Tom Grennan
2012-02-11 2:16 ` [PATCHv2 1/4] refs: add common refname_match_patterns() Tom Grennan
2012-02-11 7:12 ` Michael Haggerty
2012-02-11 19:17 ` Tom Grennan
2012-02-13 5:00 ` Michael Haggerty
2012-02-13 17:27 ` Tom Grennan
2012-02-11 8:06 ` Junio C Hamano
2012-02-11 19:37 ` Tom Grennan
2012-02-11 23:43 ` Junio C Hamano
2012-02-13 16:29 ` Tom Grennan
2012-02-11 2:16 ` [PATCHv2 2/4] tag: use refs.c:refname_match_patterns() Tom Grennan
2012-02-11 2:16 ` [PATCHv2 3/4] branch: " Tom Grennan
2012-02-11 2:16 ` [PATCHv2 4/4] for-each-ref: " Tom Grennan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F38D9D4.5000203@alum.mit.edu \
--to=mhagger@alum.mit.edu \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jasampler@gmail.com \
--cc=krh@redhat.com \
--cc=pclouds@gmail.com \
--cc=tmgrennan@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).