comparison tests/test-show-stack.t @ 33197:c5a07a3abe7d

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.
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 01 Jul 2017 22:38:42 -0700
parents
children 9e7efe421395
comparison
equal deleted inserted replaced
33196:439b4d005b4a 33197:c5a07a3abe7d
1 $ cat >> $HGRCPATH << EOF
2 > [extensions]
3 > show =
4 > EOF
5
6 $ hg init repo0
7 $ cd repo0
8
9 Empty repo / no checkout results in error
10
11 $ hg show stack
12 abort: stack view only available when there is a working directory
13 [255]
14
15 Stack displays single draft changeset as root revision
16
17 $ echo 0 > foo
18 $ hg -q commit -A -m 'commit 0'
19 $ hg show stack
20 @ 9f171 commit 0
21
22 Stack displays multiple draft changesets
23
24 $ echo 1 > foo
25 $ hg commit -m 'commit 1'
26 $ echo 2 > foo
27 $ hg commit -m 'commit 2'
28 $ echo 3 > foo
29 $ hg commit -m 'commit 3'
30 $ echo 4 > foo
31 $ hg commit -m 'commit 4'
32 $ hg show stack
33 @ 2737b commit 4
34 o d1a69 commit 3
35 o 128c8 commit 2
36 o 181cc commit 1
37 o 9f171 commit 0
38
39 Public parent of draft base is displayed, separated from stack
40
41 $ hg phase --public -r 0
42 $ hg show stack
43 @ 2737b commit 4
44 o d1a69 commit 3
45 o 128c8 commit 2
46 o 181cc commit 1
47 / (stack base)
48 o 9f171 commit 0
49
50 $ hg phase --public -r 1
51 $ hg show stack
52 @ 2737b commit 4
53 o d1a69 commit 3
54 o 128c8 commit 2
55 / (stack base)
56 o 181cc commit 1
57
58 Draft descendants are shown
59
60 $ hg -q up 2
61 $ hg show stack
62 o 2737b commit 4
63 o d1a69 commit 3
64 @ 128c8 commit 2
65 / (stack base)
66 o 181cc commit 1
67
68 $ hg -q up 3
69 $ hg show stack
70 o 2737b commit 4
71 @ d1a69 commit 3
72 o 128c8 commit 2
73 / (stack base)
74 o 181cc commit 1
75
76 working dir on public changeset should display special message
77
78 $ hg -q up 1
79 $ hg show stack
80 (empty stack; working directory is a published changeset)
81
82 Branch point in descendants displayed at top of graph
83
84 $ hg -q up 3
85 $ echo b > foo
86 $ hg commit -m 'commit 5 (new dag branch)'
87 created new head
88 $ hg -q up 2
89 $ hg show stack
90 \ / (multiple children)
91 |
92 o d1a69 commit 3
93 @ 128c8 commit 2
94 / (stack base)
95 o 181cc commit 1
96
97 $ cd ..
98
99 Base is stopped at merges
100
101 $ hg init merge-base
102 $ cd merge-base
103 $ echo 0 > foo
104 $ hg -q commit -A -m initial
105 $ echo h1 > foo
106 $ hg commit -m 'head 1'
107 $ hg -q up 0
108 $ echo h2 > foo
109 $ hg -q commit -m 'head 2'
110 $ hg phase --public -r 0:tip
111 $ hg -q up 1
112 $ hg merge -t :local 2
113 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
114 (branch merge, don't forget to commit)
115 $ hg commit -m 'merge heads'
116
117 TODO doesn't yet handle case where wdir is a draft merge
118
119 $ hg show stack
120 @ 8ee90 merge heads
121 / (stack base)
122 o 59478 head 1
123
124 $ echo d1 > foo
125 $ hg commit -m 'draft 1'
126 $ echo d2 > foo
127 $ hg commit -m 'draft 2'
128
129 $ hg show stack
130 @ 430d5 draft 2
131 o 787b1 draft 1
132 / (stack base)
133 o 8ee90 merge heads
134
135 $ cd ..
136
137 Now move on to stacks when there are more commits after the base branchpoint
138
139 $ hg init public-rebase
140 $ cd public-rebase
141 $ echo 0 > foo
142 $ hg -q commit -A -m 'base'
143 $ hg phase --public -r .
144 $ echo d1 > foo
145 $ hg commit -m 'draft 1'
146 $ echo d2 > foo
147 $ hg commit -m 'draft 2'
148 $ hg -q up 0
149 $ echo 1 > foo
150 $ hg commit -m 'new 1'
151 created new head
152 $ echo 2 > foo
153 $ hg commit -m 'new 2'
154 $ hg -q up 2
155
156 Newer draft heads don't impact output
157
158 $ hg show stack
159 @ eaffc draft 2
160 o 2b218 draft 1
161 / (stack base)
162 o b66bb base
163
164 Newer public heads are rendered
165
166 $ hg phase --public -r '::tip'
167
168 $ hg show stack
169 o baa4b new 2
170 / (2 commits ahead)
171 :
172 : (stack head)
173 : @ eaffc draft 2
174 : o 2b218 draft 1
175 :/ (stack base)
176 o b66bb base
177
178 If rebase is available, we show a hint how to rebase to that head
179
180 $ hg --config extensions.rebase= show stack
181 o baa4b new 2
182 / (2 commits ahead; hg rebase --source 2b218 --dest baa4b)
183 :
184 : (stack head)
185 : @ eaffc draft 2
186 : o 2b218 draft 1
187 :/ (stack base)
188 o b66bb base
189
190 Similar tests but for multiple heads
191
192 $ hg -q up 0
193 $ echo h2 > foo
194 $ hg -q commit -m 'new head 2'
195 $ hg phase --public -r .
196 $ hg -q up 2
197
198 $ hg show stack
199 o baa4b new 2
200 / (2 commits ahead)
201 : o 9a848 new head 2
202 :/ (1 commits ahead)
203 :
204 : (stack head)
205 : @ eaffc draft 2
206 : o 2b218 draft 1
207 :/ (stack base)
208 o b66bb base
209
210 $ hg --config extensions.rebase= show stack
211 o baa4b new 2
212 / (2 commits ahead; hg rebase --source 2b218 --dest baa4b)
213 : o 9a848 new head 2
214 :/ (1 commits ahead; hg rebase --source 2b218 --dest 9a848)
215 :
216 : (stack head)
217 : @ eaffc draft 2
218 : o 2b218 draft 1
219 :/ (stack base)
220 o b66bb base