[PATCH RFC] show: implement "stack" view
Augie Fackler
raf at durin42.com
Sun Jun 18 21:53:30 EDT 2017
On Sat, Jun 17, 2017 at 01:02:49PM -0600, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc at gmail.com>
> # Date 1497726059 21600
> # Sat Jun 17 13:00:59 2017 -0600
> # Node ID c9a3d8cdbb925614419216d6e99d9a70f03d926d
> # Parent 9fcb6df413c9ca475e705ecc15df07584dadb0c1
> 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."
We don't use the term stack yet in Mercurial, other than (oddly
enough!) the help for MQ. I'm not wholly opposed to coming up with a
noun for this (stack might even be the right choice), but I think it
might be worth doing a survey of the existing terms of art for this in
our features (eg I know patchbomb calls it a series - that might be
the only other place this is explicitly named right now?)
> 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.
Does this have some affordance so that other extensions
(remote{names,branches} specifically come to mind) can redefine the
stack boundary? On Mercurial itself just sniffing for draft changes
will show a lot of things I don't care about anymore since they're
pushed upstream. :)
>
> The stack is rendered as a concise list of changesets. Alongside the
> stack is a visualization of the DAG, similar to `hg log -G`.
Assuming this retains the same lack of BC that we're embracing in `hg
show`, I'm happy to land something eagerly and iterate (my nagging
concerns about noun choice aside.)
[... elided entire implementation, which I didn't read yet ...]
> diff --git a/tests/test-show-stack.t b/tests/test-show-stack.t
> new file mode 100644
> --- /dev/null
> +++ b/tests/test-show-stack.t
> @@ -0,0 +1,235 @@
> + $ cat >> $HGRCPATH << EOF
> + > [extensions]
> + > show =
> + > EOF
> +
> + $ hg init repo0
> + $ cd repo0
> +
> +Empty repo / no checkout results in error
> +
> + $ hg show stack
> + abort: stack view only available when there is a working directory
> + [255]
> +
> +Stack displays single draft changeset as root revision
> +
> + $ echo 0 > foo
> + $ hg -q commit -A -m 'commit 0'
> + $ hg show stack
> + @ 9f171 commit 0
> +
> +Stack displays multiple draft changesets
> +
> + $ echo 1 > foo
> + $ hg commit -m 'commit 1'
> + $ echo 2 > foo
> + $ hg commit -m 'commit 2'
> + $ echo 3 > foo
> + $ hg commit -m 'commit 3'
> + $ echo 4 > foo
> + $ hg commit -m 'commit 4'
> + $ hg show stack
> + @ 2737b commit 4
> + o d1a69 commit 3
> + o 128c8 commit 2
> + o 181cc commit 1
> + o 9f171 commit 0
> +
> +Public parent of draft base is displayed, separated from stack
> +
> + $ hg phase --public -r 0
> + $ hg show stack
> + @ 2737b commit 4
> + o d1a69 commit 3
> + o 128c8 commit 2
> + o 181cc commit 1
> + / (stack base)
> + o 9f171 commit 0
> +
> + $ hg phase --public -r 1
> + $ hg show stack
> + @ 2737b commit 4
> + o d1a69 commit 3
> + o 128c8 commit 2
> + / (stack base)
> + o 181cc commit 1
> +
> +Draft descendants are shown
> +
> + $ hg -q up 2
> + $ hg show stack
> + o 2737b commit 4
> + o d1a69 commit 3
> + @ 128c8 commit 2
> + / (stack base)
> + o 181cc commit 1
> +
> + $ hg -q up 3
> + $ hg show stack
> + o 2737b commit 4
> + @ d1a69 commit 3
> + o 128c8 commit 2
> + / (stack base)
> + o 181cc commit 1
> +
> +working dir on public changeset should display special message
> +
> + $ hg -q up 1
> + $ hg show stack
> + (empty stack; working directory is a published changeset)
> +
> +Branch point in descendants displayed at top of graph
> +
> + $ hg -q up 3
> + $ echo b > foo
> + $ hg commit -m 'commit 5 (new dag branch)'
> + created new head
> + $ hg -q up 2
> + $ hg show stack
> + \ / (multiple children)
> + |
> + o d1a69 commit 3
> + @ 128c8 commit 2
> + / (stack base)
> + o 181cc commit 1
> +
> + $ cd ..
> +
> +Base is stopped at merges
> +
> + $ hg init merge-base
> + $ cd merge-base
> + $ echo 0 > foo
> + $ hg -q commit -A -m initial
> + $ echo h1 > foo
> + $ hg commit -m 'head 1'
> + $ hg -q up 0
> + $ echo h2 > foo
> + $ hg -q commit -m 'head 2'
> + $ hg phase --public -r 0:tip
> + $ hg -q up 1
> + $ hg merge -t :local 2
> + 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
> + (branch merge, don't forget to commit)
> + $ hg commit -m 'merge heads'
> +
> +TODO doesn't yet handle case where wdir is a draft merge
> +
> + $ hg show stack
> + @ 8ee90 merge heads
> + / (stack base)
> + o 59478 head 1
> +
> + $ echo d1 > foo
> + $ hg commit -m 'draft 1'
> + $ echo d2 > foo
> + $ hg commit -m 'draft 2'
> +
> + $ hg show stack
> + @ 430d5 draft 2
> + o 787b1 draft 1
> + / (stack base)
> + o 8ee90 merge heads
> +
> + $ cd ..
> +
> +Now move on to stacks when there are more commits after the base branchpoint
> +
> + $ hg init public-rebase
> + $ cd public-rebase
> + $ echo 0 > foo
> + $ hg -q commit -A -m 'base'
> + $ hg phase --public -r .
> + $ echo d1 > foo
> + $ hg commit -m 'draft 1'
> + $ echo d2 > foo
> + $ hg commit -m 'draft 2'
> + $ hg -q up 0
> + $ echo 1 > foo
> + $ hg commit -m 'new 1'
> + created new head
> + $ echo 2 > foo
> + $ hg commit -m 'new 2'
> + $ hg -q up 2
> +
> +Newer draft heads don't impact output
> +
> + $ hg show stack
> + @ eaffc draft 2
> + o 2b218 draft 1
> + / (stack base)
> + o b66bb base
> +
> +Newer public heads are rendered
> +
> + $ hg phase --public -r '::tip'
> +
> + $ hg show stack
> + (new heads)
> +
> + o baa4b new 2
> + / (2 commits ahead)
> + :
> + : (current stack)
> + :
> + : @ eaffc draft 2
> + : o 2b218 draft 1
> + :/ (stack base)
> + o b66bb base
> +
> +If rebase is available, we show a hint how to rebase to that head
> +
> + $ hg --config extensions.rebase= show stack
> + (new heads)
> +
> + o baa4b new 2
> + / (2 commits ahead)
> + : hg rebase -s 2b218 -d baa4b
> + :
> + : (current stack)
> + :
> + : @ eaffc draft 2
> + : o 2b218 draft 1
> + :/ (stack base)
> + o b66bb base
> +
> +Similar tests but for multiple heads
> +
> + $ hg -q up 0
> + $ echo h2 > foo
> + $ hg -q commit -m 'new head 2'
> + $ hg phase --public -r .
> + $ hg -q up 2
> +
> + $ hg show stack
> + (new heads)
> +
> + o baa4b new 2
> + / (2 commits ahead)
> + : o 9a848 new head 2
> + :/ (1 commits ahead)
> + :
> + : (current stack)
> + :
> + : @ eaffc draft 2
> + : o 2b218 draft 1
> + :/ (stack base)
> + o b66bb base
> +
> + $ hg --config extensions.rebase= show stack
> + (new heads)
> +
> + o baa4b new 2
> + / (2 commits ahead)
> + : hg rebase -s 2b218 -d baa4b
> + : o 9a848 new head 2
> + :/ (1 commits ahead)
> + : hg rebase -s 2b218 -d 9a848
> + :
> + : (current stack)
> + :
> + : @ eaffc draft 2
> + : o 2b218 draft 1
> + :/ (stack base)
> + o b66bb base
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list