RFC: revset relation operator

Matt Mackall mpm at selenic.com
Tue Oct 13 14:40:32 CDT 2015


On Wed, 2015-10-14 at 00:42 +0900, Yuya Nishihara wrote:
> On Mon, 12 Oct 2015 20:55:15 -0500, Matt Mackall wrote:
> > On Mon, 2015-10-12 at 16:37 -0700, Gregory Szorc wrote:
> > > On Mon, Oct 12, 2015 at 2:26 PM, Matt Mackall <mpm at selenic.com> wrote:
> > > 
> > > > On Mon, 2015-10-12 at 10:07 -0400, Augie Fackler wrote:
> > > > > On Sun, Oct 11, 2015 at 05:45:24PM -0500, Matt Mackall wrote:
> > > > > > It would be nice if we had a convenience syntax for finding things
> > > > > > related to a given changeset. Currently, we have a couple of these for
> > > > > > parents, ancestors, and descendants.
> > > > > >
> > > > > >  foo^  # first parent
> > > > > >  foo^2 # second parent
> > > > > >  foo^^ # first parent of first parent
> > > > > >  foo~2 # same
> > > > > >  ::foo # ancestors, inclusive
> > > > > >  foo:: # descendants, inclusize
> > > > > >
> > > > > > But we have nothing directly equivalent to parents(), nor any shorthand
> > > > > > for children(), successors(), origin(), destination(), or any other
> > > > type
> > > > > > of relation we may add. We'd also like a way to specify next, previous,
> > > > > > all, all exclusive, last, etc.
> > > > > >
> > > > > > So my proposal[1] is to add a bracketed postfix (one of {}, [], or <>,
> > > > > > but perhaps {} is the least bad) that looks like this:
> > > > > >
> > > > > >  foo{1}     # children(foo)
> > > > > >  foo{2}     # children(children(foo))
> > > > > >  foo{}      # defaults to 1, so children(foo)
> > > > > >  foo{0}     # synonym for foo
> > > > > >  foo{-1}    # parents(foo) (both of 'em)
> > > > > >  foo{-}     # same
> > > > > >  foo{*}     # foo:: - foo (exclusive)
> > > > > >  foo{**}    # foo:: (inclusive)
> > > > > >  foo{-*}    # ::foo - foo
> > > > > >  foo{$}     # heads(foo::) aka "the last children"
> > > > > >  foo{-4}::foo # last five changesets in a branch
> > > > > >
> > > > > > This makes a lot of our most common expressions shorter. To talk about
> > > > > > other types of relations, we use a suffix character:
> > > > > >
> > > > > >  foo{1g}    # immediate grafts of foo
> > > > > >  foo{-g}    # origin for grafts
> > > > > >  foo{o}     # successor(foo)
> > > > > >  foo{$o}    # final successor of foo
> > > > >
> > > > > Neat. The one-character suffix thing gives me a little pause as
> > > > > possibly-not-entirely-self-documenting. Maybe it could be whole [a-z]
> > > > > words, and we could allow unambiguous prefixes?
> > > >
> > > > s/prefixes/suffixes/, sure. Definitely makes more sense for the long
> > > > form.
> > > >
> > > > I think the specific feedback I'm looking for here is how do folks feel
> > > > about:
> > > >
> > > > - using {} for the operator
> > > > - allowing empty {} to be children()
> > > > - allowing bare "-" with no numeral
> > > > - using * and ** (and -* and -**) for all
> > > > - using $ (and -$) for end/last
> > > > - suffix characters/words for relation dimension
> > > > - any common operations I might be forgetting
> > > >
> > > > This is kind of a lot of new weird syntax all at once and I haven't
> > > > completely convinced myself that it's not too horrible.
> > > >
> > > 
> > > To be honest, my immediate reaction was this syntax was a bit complex
> > > (although powerful!) and I was somewhat surprised to see the proposal from
> > > you, as you are normally the one encouraging simplicity :)
> > > 
> > > The amount of things you can include inside the brackets I feel is a bit
> > > overwhelming.
> > > 
> > > I find the numbers pretty intuitive for finding "neighbors."
> > > 
> > > I'm not a huge fan of '{-}' and '{}' because they add cognitive dissonance.
> 
> and it would be confusing in revset() template function.

Right, hadn't considered that.

> > Ok, but bear in mind that perhaps the most urgently needed thing here is
> > a shorthand for immediate children to complement ^.
> 
> How about two-letter operator such as ++?
> 
>   .++      first children of .
>   1000++n  nth children of 1000
>   .+++n    gah, "(.++) + n"
> 
> I agree it isn't extensible, but it is easy to type.

We must also solve the successors problem. Having two parallel sets of
operators and functions is going to be a problem as we're quickly
running out of viable symbols. And adding a complete set of
heads/roots/parents/children/ancestors/descendants funcs for each type
of relation is going to be clutter.

I suppose I should spell out the goals a bit more. The things that must
be solved:

- we have no shorthand for children, a frequent op
- we have no shorthand for precursors/successors, soon to be important
- the operations available on non-DAG relations are very incomplete

Things that would be nice to solve, but less urgent:

- graft/rebase/etc relations
- parents() shorthand (^ is incomplete)
- iterated parents()/children() like foo{5}
- heads() shorthand
- the "nontrivial:: - nontrivial" problem

-- 
Mathematics is the supreme nostalgia of our time.



More information about the Mercurial-devel mailing list