Patchwork [2,of,2,V2] show: implement underway view

login
register
mail settings
Submitter Gregory Szorc
Date April 13, 2017, 3:31 a.m.
Message ID <b223da52ad3b22bb76dc.1492054296@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/20156/
State Accepted
Headers show

Comments

Gregory Szorc - April 13, 2017, 3:31 a.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1492054275 25200
#      Wed Apr 12 20:31:15 2017 -0700
# Node ID b223da52ad3b22bb76dcb240677d330bce3eb6bf
# Parent  60177a9b778cb65fdefd4486ce51475a746c4cb6
show: implement underway view

This is the beginning of a wip/smartlog view. It is basically a manually
constructed (read: fast) revset function to collect "relevant"
changesets combined with a custom template and a graph displayer.
It obviously needs a lot of work.

I'd like to get *something* usable in 4.2 so `hg show` has some value
to end-users.

Let the bikeshedding begin.
Yuya Nishihara - April 13, 2017, 12:26 p.m.
On Wed, 12 Apr 2017 20:31:36 -0700, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1492054275 25200
> #      Wed Apr 12 20:31:15 2017 -0700
> # Node ID b223da52ad3b22bb76dcb240677d330bce3eb6bf
> # Parent  60177a9b778cb65fdefd4486ce51475a746c4cb6
> show: implement underway view

> +    # Add working directory parent.
> +    wdirrev = repo['.'].rev()
> +    if wdirrev != nullrev:
> +        relevant += revset.baseset(set([wdirrev]))

Nit: "wdir" means repo[None].
Durham Goode - April 15, 2017, 6:42 p.m.
On 4/12/17 8:31 PM, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1492054275 25200
> #      Wed Apr 12 20:31:15 2017 -0700
> # Node ID b223da52ad3b22bb76dcb240677d330bce3eb6bf
> # Parent  60177a9b778cb65fdefd4486ce51475a746c4cb6
> show: implement underway view
>
> This is the beginning of a wip/smartlog view. It is basically a manually
> constructed (read: fast) revset function to collect "relevant"
> changesets combined with a custom template and a graph displayer.
> It obviously needs a lot of work.
>
> I'd like to get *something* usable in 4.2 so `hg show` has some value
> to end-users.
>
> Let the bikeshedding begin.

My only concern is the name. It doesn't feel quite concise and intuitive 
enough for a command that will likely replace most invocations of log. 
Not that this should block the commit going in.

Some brainstorms:

hg show work  <-- my favorite
hg show local
hg show mycommits
hg show pending
hg show me
Gregory Szorc - April 15, 2017, 7:05 p.m.
On Sat, Apr 15, 2017 at 11:42 AM, Durham Goode <durham@fb.com> wrote:

> On 4/12/17 8:31 PM, Gregory Szorc wrote:
>
>> # HG changeset patch
>> # User Gregory Szorc <gregory.szorc@gmail.com>
>> # Date 1492054275 25200
>> #      Wed Apr 12 20:31:15 2017 -0700
>> # Node ID b223da52ad3b22bb76dcb240677d330bce3eb6bf
>> # Parent  60177a9b778cb65fdefd4486ce51475a746c4cb6
>> show: implement underway view
>>
>> This is the beginning of a wip/smartlog view. It is basically a manually
>> constructed (read: fast) revset function to collect "relevant"
>> changesets combined with a custom template and a graph displayer.
>> It obviously needs a lot of work.
>>
>> I'd like to get *something* usable in 4.2 so `hg show` has some value
>> to end-users.
>>
>> Let the bikeshedding begin.
>>
>
> My only concern is the name. It doesn't feel quite concise and intuitive
> enough for a command that will likely replace most invocations of log. Not
> that this should block the commit going in.
>
> Some brainstorms:
>
> hg show work  <-- my favorite
> hg show local
> hg show mycommits
> hg show pending
> hg show me
>

I agree the name isn't terrific.

If someone sends a patch to rename to `hg show work` I'll try to use my new
patch queuing powers...
Bryan O'Sullivan - April 17, 2017, 3:55 p.m.
On Sat, Apr 15, 2017 at 12:05 PM, Gregory Szorc <gregory.szorc@gmail.com>
wrote:

> If someone sends a patch to rename to `hg show work` I'll try to use my
> new patch queuing powers...
>

wip – for "work in progress"?
Gregory Szorc - April 17, 2017, 4:35 p.m.
> On Apr 17, 2017, at 08:55, Bryan O'Sullivan <bos@serpentine.com> wrote:
> 
> 
>> On Sat, Apr 15, 2017 at 12:05 PM, Gregory Szorc <gregory.szorc@gmail.com> wrote:
>> If someone sends a patch to rename to `hg show work` I'll try to use my new patch queuing powers...
> 
> wip – for "work in progress"?

I like the brevity and its descriptiveness. I have concerns about "discovery" of wip. It isn't immediately obvious what "wip" means. I'm also trying to think if we expose acronyms elsewhere. I don't think we do?

I do support wip as an alias. But show doesn't currently accept substring matching and aliases like commands do. That should be implemented.

All that being said, this is a highly experimental extension. So I'll accept wip or work as a rename.

Patch

diff --git a/hgext/show.py b/hgext/show.py
--- a/hgext/show.py
+++ b/hgext/show.py
@@ -15,13 +15,17 @@  data.
 from __future__ import absolute_import
 
 from mercurial.i18n import _
+from mercurial.node import nullrev
 from mercurial import (
     cmdutil,
     commands,
     error,
     formatter,
+    graphmod,
     pycompat,
     registrar,
+    revset,
+    revsetlang,
 )
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
@@ -32,6 +36,7 @@  testedwith = 'ships-with-hg-core'
 
 cmdtable = {}
 command = cmdutil.command(cmdtable)
+revsetpredicate = registrar.revsetpredicate()
 
 class showcmdfunc(registrar._funcregistrarbase):
     """Register a function to be invoked for an `hg show <thing>`."""
@@ -128,6 +133,70 @@  def showbookmarks(ui, repo, fm):
         fm.data(active=bm == active,
                 longestbookmarklen=longestname)
 
+@revsetpredicate('_underway([commitage[, headage]])')
+def underwayrevset(repo, subset, x):
+    args = revset.getargsdict(x, 'underway', 'commitage headage')
+    if 'commitage' not in args:
+        args['commitage'] = None
+    if 'headage' not in args:
+        args['headage'] = None
+
+    # We assume callers of this revset add a topographical sort on the
+    # result. This means there is no benefit to making the revset lazy
+    # since the topographical sort needs to consume all revs.
+    #
+    # With this in mind, we build up the set manually instead of constructing
+    # a complex revset. This enables faster execution.
+
+    # Mutable changesets (non-public) are the most important changesets
+    # to return. ``not public()`` will also pull in obsolete changesets if
+    # there is a non-obsolete changeset with obsolete ancestors. This is
+    # why we exclude obsolete changesets from this query.
+    rs = 'not public() and not obsolete()'
+    rsargs = []
+    if args['commitage']:
+        rs += ' and date(%s)'
+        rsargs.append(revsetlang.getstring(args['commitage'],
+                                           _('commitage requires a string')))
+
+    mutable = repo.revs(rs, *rsargs)
+    relevant = revset.baseset(mutable)
+
+    # Add parents of mutable changesets to provide context.
+    relevant += repo.revs('parents(%ld)', mutable)
+
+    # We also pull in (public) heads if they a) aren't closing a branch
+    # b) are recent.
+    rs = 'head() and not closed()'
+    rsargs = []
+    if args['headage']:
+        rs += ' and date(%s)'
+        rsargs.append(revsetlang.getstring(args['headage'],
+                                           _('headage requires a string')))
+
+    relevant += repo.revs(rs, *rsargs)
+
+    # Add working directory parent.
+    wdirrev = repo['.'].rev()
+    if wdirrev != nullrev:
+        relevant += revset.baseset(set([wdirrev]))
+
+    return subset & relevant
+
+@showview('underway', fmtopic='underway')
+def showunderway(ui, repo, fm):
+    """changesets that aren't finished"""
+    # TODO support date-based limiting when calling revset.
+    revs = repo.revs('sort(_underway(), topo)')
+
+    revdag = graphmod.dagwalker(repo, revs)
+    displayer = cmdutil.changeset_templater(ui, repo, None, None,
+                                            tmpl=fm._t.load(fm._topic),
+                                            mapfile=None, buffered=True)
+
+    ui.setconfig('experimental', 'graphshorten', True)
+    cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
+
 # 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
diff --git a/mercurial/templates/map-cmdline.show b/mercurial/templates/map-cmdline.show
--- a/mercurial/templates/map-cmdline.show
+++ b/mercurial/templates/map-cmdline.show
@@ -1,2 +1,3 @@ 
 # TODO add label() once we figure out which namespace the labels belong on.
 showbookmarks = '{if(active, "*", " ")} {pad(bookmark, longestbookmarklen + 4)}{shortest(node, 5)}\n'
+showunderway = '{shortest(node, 5)}{if(branches, " ({branch})")}{if(bookmarks, " ({bookmarks})")} {desc|firstline}'
diff --git a/tests/test-show-underway.t b/tests/test-show-underway.t
new file mode 100644
--- /dev/null
+++ b/tests/test-show-underway.t
@@ -0,0 +1,168 @@ 
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > show =
+  > EOF
+
+  $ hg init repo0
+  $ cd repo0
+
+Command works on an empty repo
+
+  $ hg show underway
+
+Single draft changeset shown
+
+  $ echo 0 > foo
+  $ hg -q commit -A -m 'commit 0'
+
+  $ hg show underway
+  @  9f171 commit 0
+
+Even when it isn't the wdir
+
+  $ hg -q up null
+
+  $ hg show underway
+  o  9f171 commit 0
+
+Single changeset is still there when public because it is a head
+
+  $ hg phase --public -r 0
+  $ hg show underway
+  o  9f171 commit 0
+
+A draft child will show both it and public parent
+
+  $ hg -q up 0
+  $ echo 1 > foo
+  $ hg commit -m 'commit 1'
+
+  $ hg show underway
+  @  181cc commit 1
+  o  9f171 commit 0
+
+Multiple draft children will be shown
+
+  $ echo 2 > foo
+  $ hg commit -m 'commit 2'
+
+  $ hg show underway
+  @  128c8 commit 2
+  o  181cc commit 1
+  o  9f171 commit 0
+
+Bumping first draft changeset to public will hide its parent
+
+  $ hg phase --public -r 1
+  $ hg show underway
+  @  128c8 commit 2
+  o  181cc commit 1
+  |
+  ~
+
+Multiple DAG heads will be shown
+
+  $ hg -q up -r 1
+  $ echo 3 > foo
+  $ hg commit -m 'commit 3'
+  created new head
+
+  $ hg show underway
+  @  f0abc commit 3
+  | o  128c8 commit 2
+  |/
+  o  181cc commit 1
+  |
+  ~
+
+Even when wdir is something else
+
+  $ hg -q up null
+
+  $ hg show underway
+  o  f0abc commit 3
+  | o  128c8 commit 2
+  |/
+  o  181cc commit 1
+  |
+  ~
+
+Draft child shows public head (multiple heads)
+
+  $ hg -q up 0
+  $ echo 4 > foo
+  $ hg commit -m 'commit 4'
+  created new head
+
+  $ hg show underway
+  @  668ca commit 4
+  | o  f0abc commit 3
+  | | o  128c8 commit 2
+  | |/
+  | o  181cc commit 1
+  |/
+  o  9f171 commit 0
+
+  $ cd ..
+
+Branch name appears in output
+
+  $ hg init branches
+  $ cd branches
+  $ echo 0 > foo
+  $ hg -q commit -A -m 'commit 0'
+  $ echo 1 > foo
+  $ hg commit -m 'commit 1'
+  $ echo 2 > foo
+  $ hg commit -m 'commit 2'
+  $ hg phase --public -r .
+  $ hg -q up -r 1
+  $ hg branch mybranch
+  marked working directory as branch mybranch
+  (branches are permanent and global, did you want a bookmark?)
+  $ echo 3 > foo
+  $ hg commit -m 'commit 3'
+  $ echo 4 > foo
+  $ hg commit -m 'commit 4'
+
+  $ hg show underway
+  @  f8dd3 (mybranch) commit 4
+  o  90cfc (mybranch) commit 3
+  | o  128c8 commit 2
+  |/
+  o  181cc commit 1
+  |
+  ~
+
+  $ cd ..
+
+Bookmark name appears in output
+
+  $ hg init bookmarks
+  $ cd bookmarks
+  $ echo 0 > foo
+  $ hg -q commit -A -m 'commit 0'
+  $ echo 1 > foo
+  $ hg commit -m 'commit 1'
+  $ echo 2 > foo
+  $ hg commit -m 'commit 2'
+  $ hg phase --public -r .
+  $ hg bookmark @
+  $ hg -q up -r 1
+  $ echo 3 > foo
+  $ hg commit -m 'commit 3'
+  created new head
+  $ echo 4 > foo
+  $ hg commit -m 'commit 4'
+  $ hg bookmark mybook
+
+  $ hg show underway
+  @  cac82 (mybook) commit 4
+  o  f0abc commit 3
+  | o  128c8 (@) commit 2
+  |/
+  o  181cc commit 1
+  |
+  ~
+
+  $ cd ..
diff --git a/tests/test-show.t b/tests/test-show.t
--- a/tests/test-show.t
+++ b/tests/test-show.t
@@ -11,6 +11,7 @@  No arguments shows available views
   available views:
   
   bookmarks -- bookmarks and their associated changeset
+  underway -- changesets that aren't finished
   
   abort: no view requested
   (use "hg show VIEW" to choose a view)
@@ -39,6 +40,8 @@  No arguments shows available views
   
       bookmarks   bookmarks and their associated changeset
   
+      underway    changesets that aren't finished
+  
   (use 'hg help -e show' to show help for the show extension)
   
   options: