[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

magic selectors (was Re: [Monotone-devel] Proposal for human readable re

From: Nathaniel Smith
Subject: magic selectors (was Re: [Monotone-devel] Proposal for human readable revision IDs)
Date: Fri, 9 Sep 2005 16:16:54 -0700
User-agent: Mutt/1.5.9i

On Tue, Sep 06, 2005 at 01:22:27PM -0700, Howard Spindel wrote:
> monotone diff <filename> --revision=p:1  where "p" stands for 
> predecessor and the number following the p shows how many 
> predecessors back you want to go?  By using a combined selector, you 
> could restrict this to predecessors that you checked in if you wanted.
> One could also consider a successor selection method.  Example:
> monotone diff <filename> --revision=t:Release2.0 --revision=s:1

Your second example is tricky, because it introduces a concept of a
"base" revision or such -- somehow the second --revision option is not
self-contained, but is relative to the stuff typed in the other
--revision switch.  I'm not sure off the top of my head how such a
design should work.

For the basic idea, though, here's a proposal that just popped into my
head: introduce some new selectors.  Let's make them all CAPITALIZED
because 1) they're all sort of "magic", and that marks them off from
the point of view of users.  2) we're running out of letters and this
lets us reuse some :-).

Some selectors:
  -- working copy base: the version in MT/revision.  Requires a
      working copy.
     Possible letters: B?
     Usage: 'monotone diff -rB:' is equivalent to 'monotone diff'

  -- update target: the version(s) that 'monotone update' will take
      you to (maybe allow a branch as the selector value, and that
      means what 'monotone update -bfoo' does?)  Requires a working
     possible letters: U?
     usage: 'monotone diff -rB: -rU:' prints the changes that will be
      applied to the working copy if 'monotone update' is run.

  -- branch point: the minimal common ancestor(s) of the current version
      and the heads of some other branch.  In sh:
       (monotone automate ancestors $(cat MT/revision) &&
        monotone automate heads $BRANCH | monotone automate ancestors 
address@hidden) \
       | sort | uniq -d | monotone erase_ancestors address@hidden
      Requires a working copy.
     possible letters: B? ("branch"), S? ("split")
      'monotone diff -rS:net.venge.monotone'
        -- what does this branch have that net.venge.monotone doesn't?
      'monotone diff -rS:net.venge.monotone -rh:net.venge.monotone'
        -- what does net.venge.monotone have that this branch doesn't?

  -- predecessor: takes a number (defaults to 1), and after evaluating
      the rest of the selector, replaces each selected revision with
      the set of revisions that are reachable by taking a length-n
      walk upwards from that revision.
     possible letters: P? ("predecessor", "parent") A? ("ancestor")

  -- successor: same as predecessor, but with a downward walk.
     Possible letters: S? C? ("child"), D? ("descendent")

  -- heads: after evaluating the rest of the selector, runs
      erase_ancestors on the set so generated.
     possible letters: H?
     (NB: different from non-magic "h:" which gives heads of a branch
     -- this will probably confuse people?)

  -- disambiguation: Takes a single number.  When the rest of the
      selector does not specify a unique revision, then this can be
      used to pick the nth of the revisions that were narrowed down to
      (ordered lexicographically, say).
     possible letters: N?  D?
     usage: 'monotone diff -rfoo' <get a message saying that there are
      three revisions matching foo, with a list.  list has a number in
      front of each> 'monotone diff -rfoo/N:2' (to pick the second
      item in that list)
     usage: 'monotone update' <get a message saying there are multiple
      update targets, use 'update -rU:/N:<number>' to pick from
      following list:>


We've been resisting adding any sort of recursive syntax to
selectors; to date a correct way to interpret them has been to
calculate the set specified by each piece, and then intersect those
sets.  Predecessor/successors/heads/disambiguate all violate this, and
raise funky questions -- e.g., what order they are applied in matters.

One solution would be to define a order -- first intersective
selectors, then predecessor, then successor, then head, then
disambiguation.  (or maybe only one of predecessor and successor is
allowed?  doing one after the other is meaningful (it gives you
"siblings" or "cousins" or somesuch), but may be confusing, and how
do we pick which order is better?)

Another solution would be to actually make them "procedural", say that
they're evaluated from left to right.  This gives the same result for
the current selectors, and adds some flexibility -- you can chain
things together.  It's also the sort of design that people seem to
find intuitively appealing to reason about, AFAICT; maybe this is the
best approach.

The whole thing is a chunk of complexity, but between being something
that only power users need to know about, and how often people request
things along these lines, may be justified.  An important question,
though, is whether they actually _will_ help with the cases people
keep complaining about -- perhaps dealing with these would be too
complex, they're too hard to type, etc.?  Would people actually use
them?  ...I guess only experience can really answer this.


-- Nathaniel

Eternity is very long, especially towards the end.
  -- Woody Allen

reply via email to

[Prev in Thread] Current Thread [Next in Thread]