Patchwork [V3] show: new extension for displaying various repository data

login
register
mail settings
Submitter Gregory Szorc
Date March 25, 2017, 2:31 a.m.
Message ID <42b0afe0f6ebea285569.1490409080@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/19651/
State Accepted
Delegated to: Yuya Nishihara
Headers show

Comments

Gregory Szorc - March 25, 2017, 2:31 a.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1490408340 25200
#      Fri Mar 24 19:19:00 2017 -0700
# Node ID 42b0afe0f6ebea285569e0061e1eab2fcffb686e
# Parent  aea8ec3f7dd1967a05ecce8f779e16f7ad14fdee
show: new extension for displaying various repository data

Currently, Mercurial has a number of commands to show information. And,
there are features coming down the pipe that will introduce more
commands for showing information.

Currently, when introducing a new class of data or a view that we
wish to expose to the user, the strategy is to introduce a new command
or overload an existing command, sometimes both. For example, there is
a desire to formalize the wip/smartlog/underway/mine functionality that
many have devised. There is also a desire to introduce a "topics"
concept. Others would like views of "the current stack." In the
current model, we'd need a new command for wip/smartlog/etc (that
behaves a lot like a pre-defined alias of `hg log`). For topics,
we'd likely overload `hg topic[s]` to both display and manipulate
topics.

Adding new commands for every pre-defined query doesn't scale well
and pollutes `hg help`. Overloading commands to perform read-only and
write operations is arguably an UX anti-pattern: while having all
functionality for a given concept in one command is nice, having a
single command doing multiple discrete operations is not. Furthermore,
a user may be surprised that a command they thought was read-only
actually changes something.

We discussed this at the Mercurial 4.0 Sprint in Paris and decided that
having a single command where we could hang pre-defined views of
various data would be a good idea. Having such a command would:

* Help prevent an explosion of new query-related commands
* Create a clear separation between read and write operations
  (mitigates footguns)
* Avoids overloading the meaning of commands that manipulate data
  (bookmark, tag, branch, etc) (while we can't take away the
  existing behavior for BC reasons, we now won't introduce this
  behavior on new commands)
* Allows users to discover informational views more easily by
  aggregating them in a single location
* Lowers the barrier to creating the new views (since the barrier
  to creating a top-level command is relatively high)

So, this commit introduces the `hg show` command via the "show"
extension. This command accepts a positional argument of the
"view" to show. New views can be registered with a decorator. To
prove it works, we implement the "bookmarks" view, which shows a
table of bookmarks and their associated nodes.

We introduce a new style to hold everything used by `hg show`.

For our initial bookmarks view, the output varies from `hg bookmarks`:

* Padding is performed in the template itself as opposed to Python
* Revision integers are not shown
* shortest() is used to display a 5 character node by default (as
  opposed to static 12 characters)

I chose to implement the "bookmarks" view first because it is simple
and shouldn't invite too much bikeshedding that detracts from the
evaluation of `hg show` itself. But there is an important point
to consider: we now have 2 ways to show a list of bookmarks. I'm not
a fan of introducing multiple ways to do very similar things. So it
might be worth discussing how we wish to tackle this issue for
bookmarks, tags, branches, MQ series, etc.

I also made the choice of explicitly declaring the default show
template not part of the standard BC guarantees. History has shown
that we make mistakes and poor choices with output formatting but
can't fix these mistakes later because random tools are parsing
output and we don't want to break these tools. Optimizing for human
consumption is one of my goals for `hg show`. So, by not covering
the formatting as part of BC, the barrier to future change is much
lower and humans benefit.

There are some improvements that can be made to formatting. For
example, we don't yet use label() in the templates. We obviously
want this for color. But I'm not sure if we should reuse the existing
log.* labels or invent new ones. I figure we can punt that to a
follow-up.

At the aforementioned Sprint, we discussed and discarded various
alternatives to `hg show`.

We considered making `hg log <view>` perform this behavior. The main
reason we can't do this is because a positional argument to `hg log`
can be a file path and if there is a conflict between a path name and
a view name, behavior is ambiguous. We could have introduced
`hg log --view` or similar, but we felt that required too much typing
(we don't want to require a command flag to show a view) and wasn't
very discoverable. Furthermore, `hg log` is optimized for showing
changelog data and there are things that `hg display` could display
that aren't changelog centric.

There were concerns about using "show" as the command name.

Some users already have a "show" alias that is similar to `hg export`.

There were also concerns that Git users adapted to `git show` would
be confused by `hg show`'s different behavior. The main difference
here is `git show` prints an `hg export` like view of the current
commit by default and `hg show` requires an argument. `git show`
can also display any Git object. `git show` does not support
displaying more complex views: just single objects. If we
implemented `hg show <hash>` or `hg show <identifier>`, `hg show`
would be a superset of `git show`. Although, I'm hesitant to do that
at this time because I view `hg show` as a higher-level querying
command and there are namespace collisions between valid identifiers
and registered views.

There is also a prefix collision with `hg showconfig`, which is an
alias of `hg config`.

We also considered `hg view`, but that is already used by the "hgk"
extension.

`hg display` was also proposed at one point. It has a prefix collision
with `hg diff`. General consensus was "show" or "view" are the best
verbs. And since "view" was taken, "show" was chosen.

There are a number of inline TODOs in this patch. Some of these
represent decisions yet to be made. Others represent features
requiring non-trivial complexity. Rather than bloat the patch or
invite additional bikeshedding, I figured I'd document future
enhancements via TODO so we can get a minimal implmentation landed.
Something is better than nothing.
Yuya Nishihara - April 1, 2017, 11:42 a.m.
On Fri, 24 Mar 2017 19:31:20 -0700, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1490408340 25200
> #      Fri Mar 24 19:19:00 2017 -0700
> # Node ID 42b0afe0f6ebea285569e0061e1eab2fcffb686e
> # Parent  aea8ec3f7dd1967a05ecce8f779e16f7ad14fdee
> show: new extension for displaying various repository data

Looks good, and there seems no negative comment on this, so I'll queue it
tomorrow or next Monday.

A couple of comments in line.

> I chose to implement the "bookmarks" view first because it is simple
> and shouldn't invite too much bikeshedding that detracts from the
> evaluation of `hg show` itself. But there is an important point
> to consider: we now have 2 ways to show a list of bookmarks. I'm not
> a fan of introducing multiple ways to do very similar things. So it
> might be worth discussing how we wish to tackle this issue for
> bookmarks, tags, branches, MQ series, etc.

This is real concern, but can be settled later since "hg show" is still
experimental.

> +@command('show', commands.formatteropts, _('VIEW'))
> +def show(ui, repo, view=None, template=None):
> +    """show various repository information
> +
> +    A requested view of repository data is displayed.
> +
> +    If no view is requested, the list of available views is shown and the
> +    command aborts.
> +
> +    .. note::
> +
> +       There are no backwards compatibility guarantees for the output of this
> +       command. Output may change in any future Mercurial release.
> +
> +       Consumers wanting stable command output should specify a template via
> +       ``-T/--template``.
> +
> +    List of available views:
> +
> +    """

Is "hg show VIEW" supposed to not take any view-specific arguments?

> +    if ui.plain() and not template:
> +        raise error.Abort(_('"hg show" cannot be used in plain mode because '
> +                            'output is not stable'),
> +                          hint=_('unset HGPLAIN and invoke with -T/--template '
> +                                 'to control output'))
> +
> +    ui.pager('show')
> +    views = showview._table
> +
> +    if not view:
> +        # TODO consider using formatter here so available views can be
> +        # rendered to custom format.

I'll move ui.pager() here, ...

> +        ui.write(_('available views:\n'))
> +        ui.write('\n')
> +
> +        for name, func in sorted(views.items()):
> +            ui.write(('%s\n') % func.__doc__)
> +
> +        ui.write('\n')
> +        raise error.Abort(_('no view requested'),
> +                          hint=_('use "hg show VIEW" to choose a view'))
> +
> +    # TODO use same logic as dispatch to perform prefix matching.
> +    if view not in views:
> +        raise error.Abort(_('unknown view: %s') % view,
> +                          hint=_('run "hg show" to see available views'))
> +
> +    template = template or 'show'
> +    fmtopic = 'show%s' % views[view]._fmtopic

and ui.pager() here.

> +    with ui.formatter(fmtopic, {'template': template}) as fm:
> +        return views[view](ui, repo, fm)
> +
> +@showview('bookmarks', fmtopic='bookmarks')
> +def showbookmarks(ui, repo, fm):
> +    """bookmarks and their associated changeset"""
> +    marks = repo._bookmarks
> +    if not len(marks):

I would add "TODO json output is corrupted". Can be updated inflight.

> +        ui.write(_('(no bookmarks set)\n'))
> +        return
> +
> +    active = repo._activebookmark
> +    longestname = max(len(b) for b in marks)
> +    # TODO consider exposing longest shortest(node).
> +
> +    for bm, node in sorted(marks.items()):
> +        fm.startitem()
> +        fm.context(ctx=repo[node])
> +        fm.write('bookmark', '%s', bm)
> +        fm.write('node', fm.hexfunc(node), fm.hexfunc(node))
> +        fm.data(active=bm == active,
> +                longestbookmarklen=longestname)
Yuya Nishihara - April 3, 2017, 3:07 p.m.
On Sat, 1 Apr 2017 20:42:10 +0900, Yuya Nishihara wrote:
> On Fri, 24 Mar 2017 19:31:20 -0700, Gregory Szorc wrote:
> > # HG changeset patch
> > # User Gregory Szorc <gregory.szorc@gmail.com>
> > # Date 1490408340 25200
> > #      Fri Mar 24 19:19:00 2017 -0700
> > # Node ID 42b0afe0f6ebea285569e0061e1eab2fcffb686e
> > # Parent  aea8ec3f7dd1967a05ecce8f779e16f7ad14fdee
> > show: new extension for displaying various repository data
> 
> Looks good, and there seems no negative comment on this, so I'll queue it
> tomorrow or next Monday.

Finally pushed this.
Gregory Szorc - April 3, 2017, 3:17 p.m.
> On Apr 3, 2017, at 08:07, Yuya Nishihara <yuya@tcha.org> wrote:
> 
>> On Sat, 1 Apr 2017 20:42:10 +0900, Yuya Nishihara wrote:
>>> On Fri, 24 Mar 2017 19:31:20 -0700, Gregory Szorc wrote:
>>> # HG changeset patch
>>> # User Gregory Szorc <gregory.szorc@gmail.com>
>>> # Date 1490408340 25200
>>> #      Fri Mar 24 19:19:00 2017 -0700
>>> # Node ID 42b0afe0f6ebea285569e0061e1eab2fcffb686e
>>> # Parent  aea8ec3f7dd1967a05ecce8f779e16f7ad14fdee
>>> show: new extension for displaying various repository data
>> 
>> Looks good, and there seems no negative comment on this, so I'll queue it
>> tomorrow or next Monday.
> 
> Finally pushed this.

\o/

So, I could use some help adding new views to this. It is experimental and there is no BC, so I think I can encourage people to experiment :)

I'd *really* like to get some form of smartlog/wip/underway in show for 4.2. I've barely started that work. Is anyone willing to work on that? If not, I can try to hack on something basic.

I also think a "stack" view could be interesting...
Augie Fackler - April 3, 2017, 3:36 p.m.
On Mon, Apr 03, 2017 at 08:17:33AM -0700, Gregory Szorc wrote:
>
>
> > On Apr 3, 2017, at 08:07, Yuya Nishihara <yuya@tcha.org> wrote:
> >
> >> On Sat, 1 Apr 2017 20:42:10 +0900, Yuya Nishihara wrote:
> >>> On Fri, 24 Mar 2017 19:31:20 -0700, Gregory Szorc wrote:
> >>> # HG changeset patch
> >>> # User Gregory Szorc <gregory.szorc@gmail.com>
> >>> # Date 1490408340 25200
> >>> #      Fri Mar 24 19:19:00 2017 -0700
> >>> # Node ID 42b0afe0f6ebea285569e0061e1eab2fcffb686e
> >>> # Parent  aea8ec3f7dd1967a05ecce8f779e16f7ad14fdee
> >>> show: new extension for displaying various repository data
> >>
> >> Looks good, and there seems no negative comment on this, so I'll queue it
> >> tomorrow or next Monday.
> >
> > Finally pushed this.
>
> \o/
>
> So, I could use some help adding new views to this. It is experimental and there is no BC, so I think I can encourage people to experiment :)
>
> I'd *really* like to get some form of smartlog/wip/underway in show for 4.2. I've barely started that work. Is anyone willing to work on that? If not, I can try to hack on something basic.

Durham, do you have anyone that might be interested in getting
smartlog-type functionality in core as part of 'hg show'?

>
> I also think a "stack" view could be interesting...
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Durham Goode - April 3, 2017, 4:37 p.m.
On 4/3/17 8:36 AM, Augie Fackler wrote:
> On Mon, Apr 03, 2017 at 08:17:33AM -0700, Gregory Szorc wrote:
>>
>>
>>> On Apr 3, 2017, at 08:07, Yuya Nishihara <yuya@tcha.org> wrote:
>>>
>>>> On Sat, 1 Apr 2017 20:42:10 +0900, Yuya Nishihara wrote:
>>>>> On Fri, 24 Mar 2017 19:31:20 -0700, Gregory Szorc wrote:
>>>>> # HG changeset patch
>>>>> # User Gregory Szorc <gregory.szorc@gmail.com>
>>>>> # Date 1490408340 25200
>>>>> #      Fri Mar 24 19:19:00 2017 -0700
>>>>> # Node ID 42b0afe0f6ebea285569e0061e1eab2fcffb686e
>>>>> # Parent  aea8ec3f7dd1967a05ecce8f779e16f7ad14fdee
>>>>> show: new extension for displaying various repository data
>>>>
>>>> Looks good, and there seems no negative comment on this, so I'll queue it
>>>> tomorrow or next Monday.
>>>
>>> Finally pushed this.
>>
>> \o/
>>
>> So, I could use some help adding new views to this. It is experimental and there is no BC, so I think I can encourage people to experiment :)
>>
>> I'd *really* like to get some form of smartlog/wip/underway in show for 4.2. I've barely started that work. Is anyone willing to work on that? If not, I can try to hack on something basic.
>
> Durham, do you have anyone that might be interested in getting
> smartlog-type functionality in core as part of 'hg show'?

There's a couple options here. The simplest V1 would be to have the hg 
show view just be an alias for this:

hg log --config experimental.graphstyle.grandparent='2.' -G -r 
'::(draft() & (date(-14) | ::bookmark())) & draft() + ancestor(draft() & 
(date(-14) | ::bookmark())) + . + present(master) + present(@)'

(in human words:  draft ancestors of your bookmarks and your last 2 
weeks of unbookmarked drafts, plus the common ancestor of those, plus 
your working copy location, plus master-or-@)

with some fancy template alias (I've provided our '{sl}' template here 
https://bpaste.net/show/72b096bea240). It's not quite fast enough on a 
huge repo, but for everyone else it's probably fine.


The second option is we could reuse our existing smartlog extension 
implementation.  It results in better output because it's smarter about 
sorting (to avoid line crosses, instead of just outputting in rev order) 
and smarter about figuring out what is 'master' in the repo and about 
efficiently doing the computation (not using revsets in some cases). But 
it's about 500 lines of not-pretty code that we probably wouldn't have 
time to pretty-up.
Gregory Szorc - April 3, 2017, 4:46 p.m.
On Mon, Apr 3, 2017 at 9:37 AM, Durham Goode <durham@fb.com> wrote:

> On 4/3/17 8:36 AM, Augie Fackler wrote:
>
>> On Mon, Apr 03, 2017 at 08:17:33AM -0700, Gregory Szorc wrote:
>>
>>>
>>>
>>> On Apr 3, 2017, at 08:07, Yuya Nishihara <yuya@tcha.org> wrote:
>>>>
>>>> On Sat, 1 Apr 2017 20:42:10 +0900, Yuya Nishihara wrote:
>>>>>
>>>>>> On Fri, 24 Mar 2017 19:31:20 -0700, Gregory Szorc wrote:
>>>>>> # HG changeset patch
>>>>>> # User Gregory Szorc <gregory.szorc@gmail.com>
>>>>>> # Date 1490408340 25200
>>>>>> #      Fri Mar 24 19:19:00 2017 -0700
>>>>>> # Node ID 42b0afe0f6ebea285569e0061e1eab2fcffb686e
>>>>>> # Parent  aea8ec3f7dd1967a05ecce8f779e16f7ad14fdee
>>>>>> show: new extension for displaying various repository data
>>>>>>
>>>>>
>>>>> Looks good, and there seems no negative comment on this, so I'll queue
>>>>> it
>>>>> tomorrow or next Monday.
>>>>>
>>>>
>>>> Finally pushed this.
>>>>
>>>
>>> \o/
>>>
>>> So, I could use some help adding new views to this. It is experimental
>>> and there is no BC, so I think I can encourage people to experiment :)
>>>
>>> I'd *really* like to get some form of smartlog/wip/underway in show for
>>> 4.2. I've barely started that work. Is anyone willing to work on that? If
>>> not, I can try to hack on something basic.
>>>
>>
>> Durham, do you have anyone that might be interested in getting
>> smartlog-type functionality in core as part of 'hg show'?
>>
>
> There's a couple options here. The simplest V1 would be to have the hg
> show view just be an alias for this:
>
> hg log --config experimental.graphstyle.grandparent='2.' -G -r
> '::(draft() & (date(-14) | ::bookmark())) & draft() + ancestor(draft() &
> (date(-14) | ::bookmark())) + . + present(master) + present(@)'
>
> (in human words:  draft ancestors of your bookmarks and your last 2 weeks
> of unbookmarked drafts, plus the common ancestor of those, plus your
> working copy location, plus master-or-@)
>
> with some fancy template alias (I've provided our '{sl}' template here
> https://bpaste.net/show/72b096bea240). It's not quite fast enough on a
> huge repo, but for everyone else it's probably fine.
>

That's similar to how `hg wip` is implemented. I was also thinking that
initially implementing it in terms of a pre-defined revset + template would
be a good first start.


>
>
> The second option is we could reuse our existing smartlog extension
> implementation.  It results in better output because it's smarter about
> sorting (to avoid line crosses, instead of just outputting in rev order)
> and smarter about figuring out what is 'master' in the repo and about
> efficiently doing the computation (not using revsets in some cases). But
> it's about 500 lines of not-pretty code that we probably wouldn't have time
> to pretty-up.
>

Since there are no BC guarantees for show yet, let's land a revset +
template implementation in 4.2 then iterate with smartlog's features in the
4.3 cycle.

Sound like a plan?
Jun Wu - April 3, 2017, 5:05 p.m.
Excerpts from Durham Goode's message of 2017-04-03 09:37:49 -0700:
> The second option is we could reuse our existing smartlog extension 
> implementation.  It results in better output because it's smarter about 
> sorting (to avoid line crosses, instead of just outputting in rev order) 

The sorting is in core by 2188f170f5b6. A revset like 
"sort(revs, topo, topo.firstbranch=master)" behaves exactly like smartlog.

> and smarter about figuring out what is 'master' in the repo and about 

This may be implemented as a separate revset with some if conditions.

> efficiently doing the computation (not using revsets in some cases). But 
> it's about 500 lines of not-pretty code that we probably wouldn't have 
> time to pretty-up.

The only thing that remains in smartlog is the ability to indent commits by
phases:

    o draft
    |
    o draft
   /
  o public
  |

This feature is currently implemented in a very hacky and
cannot-handle-all-cases way. A major rewrite of graphmod may be needed to
enable this to be implemented cleanly.
Durham Goode - April 3, 2017, 5:58 p.m.
On 4/3/17 9:46 AM, Gregory Szorc wrote:
> On Mon, Apr 3, 2017 at 9:37 AM, Durham Goode <durham@fb.com
> <mailto:durham@fb.com>> wrote:
>
>     On 4/3/17 8:36 AM, Augie Fackler wrote:
>
>         On Mon, Apr 03, 2017 at 08:17:33AM -0700, Gregory Szorc wrote:
>
>
>
>                 On Apr 3, 2017, at 08:07, Yuya Nishihara <yuya@tcha.org
>                 <mailto:yuya@tcha.org>> wrote:
>
>                     On Sat, 1 Apr 2017 20:42:10 +0900, Yuya Nishihara wrote:
>
>                         On Fri, 24 Mar 2017 19:31:20 -0700, Gregory
>                         Szorc wrote:
>                         # HG changeset patch
>                         # User Gregory Szorc <gregory.szorc@gmail.com
>                         <mailto:gregory.szorc@gmail.com>>
>                         # Date 1490408340 25200
>                         #      Fri Mar 24 19:19:00 2017 -0700
>                         # Node ID 42b0afe0f6ebea285569e0061e1eab2fcffb686e
>                         # Parent  aea8ec3f7dd1967a05ecce8f779e16f7ad14fdee
>                         show: new extension for displaying various
>                         repository data
>
>
>                     Looks good, and there seems no negative comment on
>                     this, so I'll queue it
>                     tomorrow or next Monday.
>
>
>                 Finally pushed this.
>
>
>             \o/
>
>             So, I could use some help adding new views to this. It is
>             experimental and there is no BC, so I think I can encourage
>             people to experiment :)
>
>             I'd *really* like to get some form of smartlog/wip/underway
>             in show for 4.2. I've barely started that work. Is anyone
>             willing to work on that? If not, I can try to hack on
>             something basic.
>
>
>         Durham, do you have anyone that might be interested in getting
>         smartlog-type functionality in core as part of 'hg show'?
>
>
>     There's a couple options here. The simplest V1 would be to have the
>     hg show view just be an alias for this:
>
>     hg log --config experimental.graphstyle.grandparent='2.' -G -r
>     '::(draft() & (date(-14) | ::bookmark())) & draft() +
>     ancestor(draft() & (date(-14) | ::bookmark())) + . + present(master)
>     + present(@)'
>
>     (in human words:  draft ancestors of your bookmarks and your last 2
>     weeks of unbookmarked drafts, plus the common ancestor of those,
>     plus your working copy location, plus master-or-@)
>
>     with some fancy template alias (I've provided our '{sl}' template
>     here https://bpaste.net/show/72b096bea240
>     <https://urldefense.proofpoint.com/v2/url?u=https-3A__bpaste.net_show_72b096bea240&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=nuarHzhP1wi1T9iURRCj1A&m=74unOuh78CSF2f62gL8Nc1VGzXr9oTZ-cRnncG5wblk&s=DVsTAmn_B3aOcSjpN1pZUXCsW4Hg5hwpoidEXdsE2UE&e=>).
>     It's not quite fast enough on a huge repo, but for everyone else
>     it's probably fine.
>
>
> That's similar to how `hg wip` is implemented. I was also thinking that
> initially implementing it in terms of a pre-defined revset + template
> would be a good first start.
>
>
>
>
>     The second option is we could reuse our existing smartlog extension
>     implementation.  It results in better output because it's smarter
>     about sorting (to avoid line crosses, instead of just outputting in
>     rev order) and smarter about figuring out what is 'master' in the
>     repo and about efficiently doing the computation (not using revsets
>     in some cases). But it's about 500 lines of not-pretty code that we
>     probably wouldn't have time to pretty-up.
>
>
> Since there are no BC guarantees for show yet, let's land a revset +
> template implementation in 4.2 then iterate with smartlog's features in
> the 4.3 cycle.
>
> Sound like a plan?

Sounds good.  What are we calling it?  "hg show mycommits"?
Gregory Szorc - April 3, 2017, 6:29 p.m.
On Mon, Apr 3, 2017 at 10:58 AM, Durham Goode <durham@fb.com> wrote:

>
>
> On 4/3/17 9:46 AM, Gregory Szorc wrote:
>
>> On Mon, Apr 3, 2017 at 9:37 AM, Durham Goode <durham@fb.com
>> <mailto:durham@fb.com>> wrote:
>>
>>     On 4/3/17 8:36 AM, Augie Fackler wrote:
>>
>>         On Mon, Apr 03, 2017 at 08:17:33AM -0700, Gregory Szorc wrote:
>>
>>
>>
>>                 On Apr 3, 2017, at 08:07, Yuya Nishihara <yuya@tcha.org
>>                 <mailto:yuya@tcha.org>> wrote:
>>
>>                     On Sat, 1 Apr 2017 20:42:10 +0900, Yuya Nishihara
>> wrote:
>>
>>                         On Fri, 24 Mar 2017 19:31:20 -0700, Gregory
>>                         Szorc wrote:
>>                         # HG changeset patch
>>                         # User Gregory Szorc <gregory.szorc@gmail.com
>>                         <mailto:gregory.szorc@gmail.com>>
>>
>>                         # Date 1490408340 25200
>>                         #      Fri Mar 24 19:19:00 2017 -0700
>>                         # Node ID 42b0afe0f6ebea285569e0061e1eab
>> 2fcffb686e
>>                         # Parent  aea8ec3f7dd1967a05ecce8f779e16
>> f7ad14fdee
>>                         show: new extension for displaying various
>>                         repository data
>>
>>
>>                     Looks good, and there seems no negative comment on
>>                     this, so I'll queue it
>>                     tomorrow or next Monday.
>>
>>
>>                 Finally pushed this.
>>
>>
>>             \o/
>>
>>             So, I could use some help adding new views to this. It is
>>             experimental and there is no BC, so I think I can encourage
>>             people to experiment :)
>>
>>             I'd *really* like to get some form of smartlog/wip/underway
>>             in show for 4.2. I've barely started that work. Is anyone
>>             willing to work on that? If not, I can try to hack on
>>             something basic.
>>
>>
>>         Durham, do you have anyone that might be interested in getting
>>         smartlog-type functionality in core as part of 'hg show'?
>>
>>
>>     There's a couple options here. The simplest V1 would be to have the
>>     hg show view just be an alias for this:
>>
>>     hg log --config experimental.graphstyle.grandparent='2.' -G -r
>>     '::(draft() & (date(-14) | ::bookmark())) & draft() +
>>     ancestor(draft() & (date(-14) | ::bookmark())) + . + present(master)
>>     + present(@)'
>>
>>     (in human words:  draft ancestors of your bookmarks and your last 2
>>     weeks of unbookmarked drafts, plus the common ancestor of those,
>>     plus your working copy location, plus master-or-@)
>>
>>     with some fancy template alias (I've provided our '{sl}' template
>>     here https://bpaste.net/show/72b096bea240
>>     <https://urldefense.proofpoint.com/v2/url?u=https-3A__
>> bpaste.net_show_72b096bea240&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3
>> MUw&r=nuarHzhP1wi1T9iURRCj1A&m=74unOuh78CSF2f62gL8Nc1VGzXr9
>> oTZ-cRnncG5wblk&s=DVsTAmn_B3aOcSjpN1pZUXCsW4Hg5hwpoidEXdsE2UE&e=>).
>>     It's not quite fast enough on a huge repo, but for everyone else
>>     it's probably fine.
>>
>>
>> That's similar to how `hg wip` is implemented. I was also thinking that
>> initially implementing it in terms of a pre-defined revset + template
>> would be a good first start.
>>
>>
>>
>>
>>     The second option is we could reuse our existing smartlog extension
>>     implementation.  It results in better output because it's smarter
>>     about sorting (to avoid line crosses, instead of just outputting in
>>     rev order) and smarter about figuring out what is 'master' in the
>>     repo and about efficiently doing the computation (not using revsets
>>     in some cases). But it's about 500 lines of not-pretty code that we
>>     probably wouldn't have time to pretty-up.
>>
>>
>> Since there are no BC guarantees for show yet, let's land a revset +
>> template implementation in 4.2 then iterate with smartlog's features in
>> the 4.3 cycle.
>>
>> Sound like a plan?
>>
>
> Sounds good.  What are we calling it?  "hg show mycommits"?
>

I was thinking "mine" (or similar implying ownership) would display all
(recent?) changesets you've participated in, including published
changesets. This could be used to easily drive status report type queries.

For smartlog, I think we want naming that reinforces that changesets being
shown are incomplete and/or immutable. I used "underway" in a RFC patch
several months ago. "inprogress" is also acceptable (we didn't want to use
"inprogress" as a command name because of the "in" prefix match with
"incoming"). We could also get creative with naming and use something like
"flight" or "inflight." "mutable" or "unfinished" might also work. Let's
get *something* landed and bikeshed on naming later. No BC is a wonderful
thing.

Patch

diff --git a/contrib/wix/templates.wxs b/contrib/wix/templates.wxs
--- a/contrib/wix/templates.wxs
+++ b/contrib/wix/templates.wxs
@@ -32,6 +32,7 @@ 
           <File Name="map-cmdline.changelog" KeyPath="yes" />
           <File Name="map-cmdline.compact" />
           <File Name="map-cmdline.default" />
+          <File Name="map-cmdline.show" />
           <File Name="map-cmdline.bisect" />
           <File Name="map-cmdline.xml" />
           <File Name="map-cmdline.status" />
diff --git a/hgext/show.py b/hgext/show.py
new file mode 100644
--- /dev/null
+++ b/hgext/show.py
@@ -0,0 +1,135 @@ 
+# show.py - Extension implementing `hg show`
+#
+# Copyright 2017 Gregory Szorc <gregory.szorc@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+"""unified command to show various repository information (EXPERIMENTAL)
+
+This extension provides the :hg:`show` command, which provides a central
+command for displaying commonly-accessed repository data and views of that
+data.
+"""
+
+from __future__ import absolute_import
+
+from mercurial.i18n import _
+from mercurial import (
+    cmdutil,
+    commands,
+    error,
+    registrar,
+)
+
+# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
+# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
+# be specifying the version(s) of Mercurial they are tested with, or
+# leave the attribute unspecified.
+testedwith = 'ships-with-hg-core'
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
+class showcmdfunc(registrar._funcregistrarbase):
+    """Register a function to be invoked for an `hg show <thing>`."""
+
+    # Used by _formatdoc().
+    _docformat = '%s -- %s'
+
+    def _extrasetup(self, name, func, fmtopic=None):
+        """Called with decorator arguments to register a show view.
+
+        ``name`` is the sub-command name.
+
+        ``func`` is the function being decorated.
+
+        ``fmtopic`` is the topic in the style that will be rendered for
+        this view.
+        """
+        func._fmtopic = fmtopic
+
+showview = showcmdfunc()
+
+@command('show', commands.formatteropts, _('VIEW'))
+def show(ui, repo, view=None, template=None):
+    """show various repository information
+
+    A requested view of repository data is displayed.
+
+    If no view is requested, the list of available views is shown and the
+    command aborts.
+
+    .. note::
+
+       There are no backwards compatibility guarantees for the output of this
+       command. Output may change in any future Mercurial release.
+
+       Consumers wanting stable command output should specify a template via
+       ``-T/--template``.
+
+    List of available views:
+
+    """
+    if ui.plain() and not template:
+        raise error.Abort(_('"hg show" cannot be used in plain mode because '
+                            'output is not stable'),
+                          hint=_('unset HGPLAIN and invoke with -T/--template '
+                                 'to control output'))
+
+    ui.pager('show')
+    views = showview._table
+
+    if not view:
+        # TODO consider using formatter here so available views can be
+        # rendered to custom format.
+        ui.write(_('available views:\n'))
+        ui.write('\n')
+
+        for name, func in sorted(views.items()):
+            ui.write(('%s\n') % func.__doc__)
+
+        ui.write('\n')
+        raise error.Abort(_('no view requested'),
+                          hint=_('use "hg show VIEW" to choose a view'))
+
+    # TODO use same logic as dispatch to perform prefix matching.
+    if view not in views:
+        raise error.Abort(_('unknown view: %s') % view,
+                          hint=_('run "hg show" to see available views'))
+
+    template = template or 'show'
+    fmtopic = 'show%s' % views[view]._fmtopic
+
+    with ui.formatter(fmtopic, {'template': template}) as fm:
+        return views[view](ui, repo, fm)
+
+@showview('bookmarks', fmtopic='bookmarks')
+def showbookmarks(ui, repo, fm):
+    """bookmarks and their associated changeset"""
+    marks = repo._bookmarks
+    if not len(marks):
+        ui.write(_('(no bookmarks set)\n'))
+        return
+
+    active = repo._activebookmark
+    longestname = max(len(b) for b in marks)
+    # TODO consider exposing longest shortest(node).
+
+    for bm, node in sorted(marks.items()):
+        fm.startitem()
+        fm.context(ctx=repo[node])
+        fm.write('bookmark', '%s', bm)
+        fm.write('node', fm.hexfunc(node), fm.hexfunc(node))
+        fm.data(active=bm == active,
+                longestbookmarklen=longestname)
+
+# Adjust the docstring of the show command so it shows all registered views.
+# This is a bit hacky because it runs at the end of module load. When moved
+# into core or when another extension wants to provide a view, we'll need
+# to do this more robustly.
+# TODO make this more robust.
+longest = max(map(len, showview._table.keys()))
+for key in sorted(showview._table.keys()):
+    cmdtable['show'][0].__doc__ += ' %s   %s\n' % (
+        key.ljust(longest), showview._table[key]._origdoc)
diff --git a/mercurial/templates/map-cmdline.show b/mercurial/templates/map-cmdline.show
new file mode 100644
--- /dev/null
+++ b/mercurial/templates/map-cmdline.show
@@ -0,0 +1,2 @@ 
+# TODO add label() once we figure out which namespace the labels belong on.
+showbookmarks = '{if(active, "*", " ")} {pad(bookmark, longestbookmarklen + 4)}{shortest(node, 5)}\n'
diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -1108,11 +1108,11 @@  Error if no style:
 
   $ hg log --style notexist
   abort: style 'notexist' not found
-  (available styles: bisect, changelog, compact, default, phases, status, xml)
+  (available styles: bisect, changelog, compact, default, phases, show, status, xml)
   [255]
 
   $ hg log -T list
-  available styles: bisect, changelog, compact, default, phases, status, xml
+  available styles: bisect, changelog, compact, default, phases, show, status, xml
   abort: specify a template
   [255]
 
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -148,7 +148,7 @@  log on directory
 
   $ hg log -f -l1 --style something
   abort: style 'something' not found
-  (available styles: bisect, changelog, compact, default, phases, status, xml)
+  (available styles: bisect, changelog, compact, default, phases, show, status, xml)
   [255]
 
 -f, phases style
diff --git a/tests/test-show.t b/tests/test-show.t
new file mode 100644
--- /dev/null
+++ b/tests/test-show.t
@@ -0,0 +1,117 @@ 
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > show =
+  > EOF
+
+No arguments shows available views
+
+  $ hg init empty
+  $ cd empty
+  $ hg show
+  available views:
+  
+  bookmarks -- bookmarks and their associated changeset
+  
+  abort: no view requested
+  (use "hg show VIEW" to choose a view)
+  [255]
+
+`hg help show` prints available views
+
+  $ hg help show
+  hg show VIEW
+  
+  show various repository information
+  
+      A requested view of repository data is displayed.
+  
+      If no view is requested, the list of available views is shown and the
+      command aborts.
+  
+      Note:
+         There are no backwards compatibility guarantees for the output of this
+         command. Output may change in any future Mercurial release.
+  
+         Consumers wanting stable command output should specify a template via
+         "-T/--template".
+  
+      List of available views:
+  
+       bookmarks   bookmarks and their associated changeset
+  
+  (use 'hg help -e show' to show help for the show extension)
+  
+  options:
+  
+  (some details hidden, use --verbose to show complete help)
+
+Unknown view prints error
+
+  $ hg show badview
+  abort: unknown view: badview
+  (run "hg show" to see available views)
+  [255]
+
+HGPLAIN results in abort
+
+  $ HGPLAIN=1 hg show bookmarks
+  abort: "hg show" cannot be used in plain mode because output is not stable
+  (unset HGPLAIN and invoke with -T/--template to control output)
+  [255]
+
+But not if a template is specified
+
+  $ HGPLAIN=1 hg show bookmarks -T '{bookmark}\n'
+  (no bookmarks set)
+
+  $ cd ..
+
+bookmarks view with no bookmarks prints empty message
+
+  $ hg init books
+  $ cd books
+  $ touch f0
+  $ hg -q commit -A -m initial
+
+  $ hg show bookmarks
+  (no bookmarks set)
+
+bookmarks view shows bookmarks in an aligned table
+
+  $ echo book1 > f0
+  $ hg commit -m 'commit for book1'
+  $ echo book2 > f0
+  $ hg commit -m 'commit for book2'
+
+  $ hg bookmark -r 1 book1
+  $ hg bookmark a-longer-bookmark
+
+  $ hg show bookmarks
+  * a-longer-bookmark    7b570
+    book1                b757f
+
+A custom bookmarks template works
+
+  $ hg show bookmarks -T '{node} {bookmark} {active}\n'
+  7b5709ab64cbc34da9b4367b64afff47f2c4ee83 a-longer-bookmark True
+  b757f780b8ffd71267c6ccb32e0882d9d32a8cc0 book1 False
+
+bookmarks JSON works
+
+  $ hg show bookmarks -T json
+  [
+   {
+    "active": true,
+    "bookmark": "a-longer-bookmark",
+    "longestbookmarklen": 17,
+    "node": "7b5709ab64cbc34da9b4367b64afff47f2c4ee83"
+   },
+   {
+    "active": false,
+    "bookmark": "book1",
+    "longestbookmarklen": 17,
+    "node": "b757f780b8ffd71267c6ccb32e0882d9d32a8cc0"
+   }
+  ]
+
+  $ cd ..