[PATCH V2] show: implement "stack" view

Gregory Szorc gregory.szorc at gmail.com
Tue Jul 4 22:25:58 EDT 2017


On Tue, Jul 4, 2017 at 5:17 PM, Sean Farley <sean at farley.io> wrote:

>
> Gregory Szorc <gregory.szorc at gmail.com> writes:
>
> > # HG changeset patch
> > # User Gregory Szorc <gregory.szorc at gmail.com>
> > # Date 1498973922 25200
> > #      Sat Jul 01 22:38:42 2017 -0700
> > # Node ID eaf601d0ea04ad80ee3d763cb3274286a780f16d
> > # Parent  6d678ab1b10d0fddc73003d21aa3c7ec43194e2e
> > show: implement "stack" view
> >
> > People often want to know what they are working on *now*. As part of
> > this, they also commonly want to know how that work is related to other
> > changesets in the repo so they can perform common actions like rebase,
> > histedit, and merge.
> >
> > `hg show work` made headway into this space. However, it is geared
> > towards a complete repo view as opposed to just the current line of
> > work. If you have a lot of in-flight work or the repo has many heads,
> > the output can be overwhelming. The closest thing Mercurial has to
> > "show me the current thing I'm working on" that doesn't require custom
> > revsets is `hg qseries`. And this requires MQ, which completely changes
> > workflows and repository behavior and has horrible performance on large
> > repos. But as sub-optimal as MQ is, it does some things right, such as
> > expose a model of the repo that is easy for people to reason about.
> > This simplicity is why I think a lot of people prefer to use MQ, despite
> > its shortcomings.
> >
> > One common development workflow is to author a series of linear
> > changesets, using bookmarks, branches, anonymous heads, or even topics
> > (3rd party extension). I'll call this a "stack." You periodically
> > rewrite history in place (using `hg histedit`) and reparent the stack
> > against newer changesets (using `hg rebase`). This workflow can be
> > difficult because there is no obvious way to quickly see the current
> > "stack" nor its relation to other changesets. Figuring out arguments to
> > `hg rebase` can be difficult and may require highlighting and pasting
> > multiple changeset nodes to construct a command.
> >
> > The goal of this commit is to make stack based workflows simpler
> > by exposing a view of the current stack and its relationship to
> > other releant changesets, notably the parent of the base changeset
> > in the stack and newer heads that the stack could be rebased or merged
> > into.
> >
> > Introduced is the `hg show stack` view. Essentially, it finds all
> > mutable changesets from the working directory revision in both
> > directions, stopping at a merge or branch point. This limits the
> > revisions to a DAG linear range.
> >
> > The stack is rendered as a concise list of changesets. Alongside the
> > stack is a visualization of the DAG, similar to `hg log -G`.
> >
> > Newer public heads from the branch point of the stack are rendered
> > above the stack. The presence of these heads helps people understand
> > the DAG model and the relationship between the stack and changes made
> > since the branch point of that stack. If the "rebase" command is
> > available, a `hg rebase` command is printed for each head so a user
> > can perform a simple copy and paste to perform a rebase.
> >
> > This view is alpha quality. There are tons of TODOs documented
> > inline. But I think it is good enough for a first iteration.
> >
> > diff --git a/hgext/show.py b/hgext/show.py
> > --- a/hgext/show.py
> > +++ b/hgext/show.py
> > @@ -32,9 +32,11 @@ from mercurial.node import nullrev
> >  from mercurial import (
> >      cmdutil,
> >      commands,
> > +    destutil,
> >      error,
> >      formatter,
> >      graphmod,
> > +    phases,
> >      pycompat,
> >      registrar,
> >      revset,
> > @@ -171,6 +173,166 @@ def showbookmarks(ui, repo, fm):
> >          fm.data(active=bm == active,
> >                  longestbookmarklen=longestname)
> >
> > + at showview('stack', csettopic='stack')
> > +def showstack(ui, repo, displayer):
> > +    """current line of work"""
> > +    wdirctx = repo['.']
> > +    if wdirctx.rev() == nullrev:
> > +        raise error.Abort(_('stack view only available when there is a '
> > +                            'working directory'))
> > +
> > +    if wdirctx.phase() == phases.public:
> > +        ui.write(_('(empty stack; working directory is a published '
> > +                   'changeset)\n'))
> > +        return
> > +
> > +    # TODO extract "find stack" into a function to facilitate
> > +    # customization and reuse.
> > +
> > +    baserev = destutil.stackbase(ui, repo)
> > +    basectx = None
> > +
> > +    if baserev is None:
> > +        baserev = wdirctx.rev()
> > +        stackrevs = {wdirctx.rev()}
> > +    else:
> > +        stackrevs = set(repo.revs('%d::.', baserev))
> > +
> > +    ctx = repo[baserev]
> > +    if ctx.p1().rev() != nullrev:
> > +        basectx = ctx.p1()
> > +
> > +    # And relevant descendants.
> > +    branchpointattip = False
> > +    cl = repo.changelog
> > +
> > +    for rev in cl.descendants([wdirctx.rev()]):
>
> I think for the first iteration of this, we could use the dead-simple:
> 'draft() and branch(.)' revset. Later we could try throwing in some
> 'only' revset logic (which would handle the branch point stuff) but my
> gut feeling is to keep this simple (perhaps specify this revset as an
> option?)
>

This landed using the histedit default base revset in destutil, which
should be "good enough." We don't yet have a way to customize the revset or
to customize the stack tip or which future heads are shown.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.mercurial-scm.org/pipermail/mercurial-devel/attachments/20170704/c5496cbe/attachment.html>


More information about the Mercurial-devel mailing list