##// END OF EJS Templates
show: rename "underway" to "work"...
Gregory Szorc -
r32058:0bb157be stable
parent child Browse files
Show More
@@ -1,222 +1,222 b''
1 1 # show.py - Extension implementing `hg show`
2 2 #
3 3 # Copyright 2017 Gregory Szorc <gregory.szorc@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 """unified command to show various repository information (EXPERIMENTAL)
9 9
10 10 This extension provides the :hg:`show` command, which provides a central
11 11 command for displaying commonly-accessed repository data and views of that
12 12 data.
13 13 """
14 14
15 15 from __future__ import absolute_import
16 16
17 17 from mercurial.i18n import _
18 18 from mercurial.node import nullrev
19 19 from mercurial import (
20 20 cmdutil,
21 21 error,
22 22 formatter,
23 23 graphmod,
24 24 pycompat,
25 25 registrar,
26 26 revset,
27 27 revsetlang,
28 28 )
29 29
30 30 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
31 31 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
32 32 # be specifying the version(s) of Mercurial they are tested with, or
33 33 # leave the attribute unspecified.
34 34 testedwith = 'ships-with-hg-core'
35 35
36 36 cmdtable = {}
37 37 command = cmdutil.command(cmdtable)
38 38 revsetpredicate = registrar.revsetpredicate()
39 39
40 40 class showcmdfunc(registrar._funcregistrarbase):
41 41 """Register a function to be invoked for an `hg show <thing>`."""
42 42
43 43 # Used by _formatdoc().
44 44 _docformat = '%s -- %s'
45 45
46 46 def _extrasetup(self, name, func, fmtopic=None):
47 47 """Called with decorator arguments to register a show view.
48 48
49 49 ``name`` is the sub-command name.
50 50
51 51 ``func`` is the function being decorated.
52 52
53 53 ``fmtopic`` is the topic in the style that will be rendered for
54 54 this view.
55 55 """
56 56 func._fmtopic = fmtopic
57 57
58 58 showview = showcmdfunc()
59 59
60 60 @command('show', [
61 61 # TODO: Switch this template flag to use commands.formatteropts if
62 62 # 'hg show' becomes stable before --template/-T is stable. For now,
63 63 # we are putting it here without the '(EXPERIMENTAL)' flag because it
64 64 # is an important part of the 'hg show' user experience and the entire
65 65 # 'hg show' experience is experimental.
66 66 ('T', 'template', '', ('display with template'), _('TEMPLATE')),
67 67 ], _('VIEW'))
68 68 def show(ui, repo, view=None, template=None):
69 69 """show various repository information
70 70
71 71 A requested view of repository data is displayed.
72 72
73 73 If no view is requested, the list of available views is shown and the
74 74 command aborts.
75 75
76 76 .. note::
77 77
78 78 There are no backwards compatibility guarantees for the output of this
79 79 command. Output may change in any future Mercurial release.
80 80
81 81 Consumers wanting stable command output should specify a template via
82 82 ``-T/--template``.
83 83
84 84 List of available views:
85 85 """
86 86 if ui.plain() and not template:
87 87 hint = _('invoke with -T/--template to control output format')
88 88 raise error.Abort(_('must specify a template in plain mode'), hint=hint)
89 89
90 90 views = showview._table
91 91
92 92 if not view:
93 93 ui.pager('show')
94 94 # TODO consider using formatter here so available views can be
95 95 # rendered to custom format.
96 96 ui.write(_('available views:\n'))
97 97 ui.write('\n')
98 98
99 99 for name, func in sorted(views.items()):
100 100 ui.write(('%s\n') % func.__doc__)
101 101
102 102 ui.write('\n')
103 103 raise error.Abort(_('no view requested'),
104 104 hint=_('use "hg show VIEW" to choose a view'))
105 105
106 106 # TODO use same logic as dispatch to perform prefix matching.
107 107 if view not in views:
108 108 raise error.Abort(_('unknown view: %s') % view,
109 109 hint=_('run "hg show" to see available views'))
110 110
111 111 template = template or 'show'
112 112 fmtopic = 'show%s' % views[view]._fmtopic
113 113
114 114 ui.pager('show')
115 115 with ui.formatter(fmtopic, {'template': template}) as fm:
116 116 return views[view](ui, repo, fm)
117 117
118 118 @showview('bookmarks', fmtopic='bookmarks')
119 119 def showbookmarks(ui, repo, fm):
120 120 """bookmarks and their associated changeset"""
121 121 marks = repo._bookmarks
122 122 if not len(marks):
123 123 # This is a bit hacky. Ideally, templates would have a way to
124 124 # specify an empty output, but we shouldn't corrupt JSON while
125 125 # waiting for this functionality.
126 126 if not isinstance(fm, formatter.jsonformatter):
127 127 ui.write(_('(no bookmarks set)\n'))
128 128 return
129 129
130 130 active = repo._activebookmark
131 131 longestname = max(len(b) for b in marks)
132 132 # TODO consider exposing longest shortest(node).
133 133
134 134 for bm, node in sorted(marks.items()):
135 135 fm.startitem()
136 136 fm.context(ctx=repo[node])
137 137 fm.write('bookmark', '%s', bm)
138 138 fm.write('node', fm.hexfunc(node), fm.hexfunc(node))
139 139 fm.data(active=bm == active,
140 140 longestbookmarklen=longestname)
141 141
142 142 @revsetpredicate('_underway([commitage[, headage]])')
143 143 def underwayrevset(repo, subset, x):
144 144 args = revset.getargsdict(x, 'underway', 'commitage headage')
145 145 if 'commitage' not in args:
146 146 args['commitage'] = None
147 147 if 'headage' not in args:
148 148 args['headage'] = None
149 149
150 150 # We assume callers of this revset add a topographical sort on the
151 151 # result. This means there is no benefit to making the revset lazy
152 152 # since the topographical sort needs to consume all revs.
153 153 #
154 154 # With this in mind, we build up the set manually instead of constructing
155 155 # a complex revset. This enables faster execution.
156 156
157 157 # Mutable changesets (non-public) are the most important changesets
158 158 # to return. ``not public()`` will also pull in obsolete changesets if
159 159 # there is a non-obsolete changeset with obsolete ancestors. This is
160 160 # why we exclude obsolete changesets from this query.
161 161 rs = 'not public() and not obsolete()'
162 162 rsargs = []
163 163 if args['commitage']:
164 164 rs += ' and date(%s)'
165 165 rsargs.append(revsetlang.getstring(args['commitage'],
166 166 _('commitage requires a string')))
167 167
168 168 mutable = repo.revs(rs, *rsargs)
169 169 relevant = revset.baseset(mutable)
170 170
171 171 # Add parents of mutable changesets to provide context.
172 172 relevant += repo.revs('parents(%ld)', mutable)
173 173
174 174 # We also pull in (public) heads if they a) aren't closing a branch
175 175 # b) are recent.
176 176 rs = 'head() and not closed()'
177 177 rsargs = []
178 178 if args['headage']:
179 179 rs += ' and date(%s)'
180 180 rsargs.append(revsetlang.getstring(args['headage'],
181 181 _('headage requires a string')))
182 182
183 183 relevant += repo.revs(rs, *rsargs)
184 184
185 185 # Add working directory parent.
186 186 wdirrev = repo['.'].rev()
187 187 if wdirrev != nullrev:
188 188 relevant += revset.baseset(set([wdirrev]))
189 189
190 190 return subset & relevant
191 191
192 @showview('underway', fmtopic='underway')
193 def showunderway(ui, repo, fm):
192 @showview('work', fmtopic='work')
193 def showwork(ui, repo, fm):
194 194 """changesets that aren't finished"""
195 195 # TODO support date-based limiting when calling revset.
196 196 revs = repo.revs('sort(_underway(), topo)')
197 197
198 198 revdag = graphmod.dagwalker(repo, revs)
199 199 displayer = cmdutil.changeset_templater(ui, repo, None, None,
200 200 tmpl=fm._t.load(fm._topic),
201 201 mapfile=None, buffered=True)
202 202
203 203 ui.setconfig('experimental', 'graphshorten', True)
204 204 cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
205 205
206 206 # Adjust the docstring of the show command so it shows all registered views.
207 207 # This is a bit hacky because it runs at the end of module load. When moved
208 208 # into core or when another extension wants to provide a view, we'll need
209 209 # to do this more robustly.
210 210 # TODO make this more robust.
211 211 def _updatedocstring():
212 212 longest = max(map(len, showview._table.keys()))
213 213 entries = []
214 214 for key in sorted(showview._table.keys()):
215 215 entries.append(pycompat.sysstr(' %s %s' % (
216 216 key.ljust(longest), showview._table[key]._origdoc)))
217 217
218 218 cmdtable['show'][0].__doc__ = pycompat.sysstr('%s\n\n%s\n ') % (
219 219 cmdtable['show'][0].__doc__.rstrip(),
220 220 pycompat.sysstr('\n\n').join(entries))
221 221
222 222 _updatedocstring()
@@ -1,3 +1,3 b''
1 1 # TODO add label() once we figure out which namespace the labels belong on.
2 2 showbookmarks = '{if(active, "*", " ")} {pad(bookmark, longestbookmarklen + 4)}{shortest(node, 5)}\n'
3 showunderway = '{shortest(node, 5)}{if(branches, " ({branch})")}{if(bookmarks, " ({bookmarks})")} {desc|firstline}'
3 showwork = '{shortest(node, 5)}{if(branches, " ({branch})")}{if(bookmarks, " ({bookmarks})")} {desc|firstline}'
@@ -1,168 +1,168 b''
1 1 $ cat >> $HGRCPATH << EOF
2 2 > [extensions]
3 3 > show =
4 4 > EOF
5 5
6 6 $ hg init repo0
7 7 $ cd repo0
8 8
9 9 Command works on an empty repo
10 10
11 $ hg show underway
11 $ hg show work
12 12
13 13 Single draft changeset shown
14 14
15 15 $ echo 0 > foo
16 16 $ hg -q commit -A -m 'commit 0'
17 17
18 $ hg show underway
18 $ hg show work
19 19 @ 9f171 commit 0
20 20
21 21 Even when it isn't the wdir
22 22
23 23 $ hg -q up null
24 24
25 $ hg show underway
25 $ hg show work
26 26 o 9f171 commit 0
27 27
28 28 Single changeset is still there when public because it is a head
29 29
30 30 $ hg phase --public -r 0
31 $ hg show underway
31 $ hg show work
32 32 o 9f171 commit 0
33 33
34 34 A draft child will show both it and public parent
35 35
36 36 $ hg -q up 0
37 37 $ echo 1 > foo
38 38 $ hg commit -m 'commit 1'
39 39
40 $ hg show underway
40 $ hg show work
41 41 @ 181cc commit 1
42 42 o 9f171 commit 0
43 43
44 44 Multiple draft children will be shown
45 45
46 46 $ echo 2 > foo
47 47 $ hg commit -m 'commit 2'
48 48
49 $ hg show underway
49 $ hg show work
50 50 @ 128c8 commit 2
51 51 o 181cc commit 1
52 52 o 9f171 commit 0
53 53
54 54 Bumping first draft changeset to public will hide its parent
55 55
56 56 $ hg phase --public -r 1
57 $ hg show underway
57 $ hg show work
58 58 @ 128c8 commit 2
59 59 o 181cc commit 1
60 60 |
61 61 ~
62 62
63 63 Multiple DAG heads will be shown
64 64
65 65 $ hg -q up -r 1
66 66 $ echo 3 > foo
67 67 $ hg commit -m 'commit 3'
68 68 created new head
69 69
70 $ hg show underway
70 $ hg show work
71 71 @ f0abc commit 3
72 72 | o 128c8 commit 2
73 73 |/
74 74 o 181cc commit 1
75 75 |
76 76 ~
77 77
78 78 Even when wdir is something else
79 79
80 80 $ hg -q up null
81 81
82 $ hg show underway
82 $ hg show work
83 83 o f0abc commit 3
84 84 | o 128c8 commit 2
85 85 |/
86 86 o 181cc commit 1
87 87 |
88 88 ~
89 89
90 90 Draft child shows public head (multiple heads)
91 91
92 92 $ hg -q up 0
93 93 $ echo 4 > foo
94 94 $ hg commit -m 'commit 4'
95 95 created new head
96 96
97 $ hg show underway
97 $ hg show work
98 98 @ 668ca commit 4
99 99 | o f0abc commit 3
100 100 | | o 128c8 commit 2
101 101 | |/
102 102 | o 181cc commit 1
103 103 |/
104 104 o 9f171 commit 0
105 105
106 106 $ cd ..
107 107
108 108 Branch name appears in output
109 109
110 110 $ hg init branches
111 111 $ cd branches
112 112 $ echo 0 > foo
113 113 $ hg -q commit -A -m 'commit 0'
114 114 $ echo 1 > foo
115 115 $ hg commit -m 'commit 1'
116 116 $ echo 2 > foo
117 117 $ hg commit -m 'commit 2'
118 118 $ hg phase --public -r .
119 119 $ hg -q up -r 1
120 120 $ hg branch mybranch
121 121 marked working directory as branch mybranch
122 122 (branches are permanent and global, did you want a bookmark?)
123 123 $ echo 3 > foo
124 124 $ hg commit -m 'commit 3'
125 125 $ echo 4 > foo
126 126 $ hg commit -m 'commit 4'
127 127
128 $ hg show underway
128 $ hg show work
129 129 @ f8dd3 (mybranch) commit 4
130 130 o 90cfc (mybranch) commit 3
131 131 | o 128c8 commit 2
132 132 |/
133 133 o 181cc commit 1
134 134 |
135 135 ~
136 136
137 137 $ cd ..
138 138
139 139 Bookmark name appears in output
140 140
141 141 $ hg init bookmarks
142 142 $ cd bookmarks
143 143 $ echo 0 > foo
144 144 $ hg -q commit -A -m 'commit 0'
145 145 $ echo 1 > foo
146 146 $ hg commit -m 'commit 1'
147 147 $ echo 2 > foo
148 148 $ hg commit -m 'commit 2'
149 149 $ hg phase --public -r .
150 150 $ hg bookmark @
151 151 $ hg -q up -r 1
152 152 $ echo 3 > foo
153 153 $ hg commit -m 'commit 3'
154 154 created new head
155 155 $ echo 4 > foo
156 156 $ hg commit -m 'commit 4'
157 157 $ hg bookmark mybook
158 158
159 $ hg show underway
159 $ hg show work
160 160 @ cac82 (mybook) commit 4
161 161 o f0abc commit 3
162 162 | o 128c8 (@) commit 2
163 163 |/
164 164 o 181cc commit 1
165 165 |
166 166 ~
167 167
168 168 $ cd ..
@@ -1,130 +1,130 b''
1 1 $ cat >> $HGRCPATH << EOF
2 2 > [extensions]
3 3 > show =
4 4 > EOF
5 5
6 6 No arguments shows available views
7 7
8 8 $ hg init empty
9 9 $ cd empty
10 10 $ hg show
11 11 available views:
12 12
13 13 bookmarks -- bookmarks and their associated changeset
14 underway -- changesets that aren't finished
14 work -- changesets that aren't finished
15 15
16 16 abort: no view requested
17 17 (use "hg show VIEW" to choose a view)
18 18 [255]
19 19
20 20 `hg help show` prints available views
21 21
22 22 $ hg help show
23 23 hg show VIEW
24 24
25 25 show various repository information
26 26
27 27 A requested view of repository data is displayed.
28 28
29 29 If no view is requested, the list of available views is shown and the
30 30 command aborts.
31 31
32 32 Note:
33 33 There are no backwards compatibility guarantees for the output of this
34 34 command. Output may change in any future Mercurial release.
35 35
36 36 Consumers wanting stable command output should specify a template via
37 37 "-T/--template".
38 38
39 39 List of available views:
40 40
41 41 bookmarks bookmarks and their associated changeset
42 42
43 underway changesets that aren't finished
43 work changesets that aren't finished
44 44
45 45 (use 'hg help -e show' to show help for the show extension)
46 46
47 47 options:
48 48
49 49 -T --template TEMPLATE display with template
50 50
51 51 (some details hidden, use --verbose to show complete help)
52 52
53 53 Unknown view prints error
54 54
55 55 $ hg show badview
56 56 abort: unknown view: badview
57 57 (run "hg show" to see available views)
58 58 [255]
59 59
60 60 HGPLAIN results in abort
61 61
62 62 $ HGPLAIN=1 hg show bookmarks
63 63 abort: must specify a template in plain mode
64 64 (invoke with -T/--template to control output format)
65 65 [255]
66 66
67 67 But not if a template is specified
68 68
69 69 $ HGPLAIN=1 hg show bookmarks -T '{bookmark}\n'
70 70 (no bookmarks set)
71 71
72 72 $ cd ..
73 73
74 74 bookmarks view with no bookmarks prints empty message
75 75
76 76 $ hg init books
77 77 $ cd books
78 78 $ touch f0
79 79 $ hg -q commit -A -m initial
80 80
81 81 $ hg show bookmarks
82 82 (no bookmarks set)
83 83
84 84 bookmarks view shows bookmarks in an aligned table
85 85
86 86 $ echo book1 > f0
87 87 $ hg commit -m 'commit for book1'
88 88 $ echo book2 > f0
89 89 $ hg commit -m 'commit for book2'
90 90
91 91 $ hg bookmark -r 1 book1
92 92 $ hg bookmark a-longer-bookmark
93 93
94 94 $ hg show bookmarks
95 95 * a-longer-bookmark 7b570
96 96 book1 b757f
97 97
98 98 A custom bookmarks template works
99 99
100 100 $ hg show bookmarks -T '{node} {bookmark} {active}\n'
101 101 7b5709ab64cbc34da9b4367b64afff47f2c4ee83 a-longer-bookmark True
102 102 b757f780b8ffd71267c6ccb32e0882d9d32a8cc0 book1 False
103 103
104 104 bookmarks JSON works
105 105
106 106 $ hg show bookmarks -T json
107 107 [
108 108 {
109 109 "active": true,
110 110 "bookmark": "a-longer-bookmark",
111 111 "longestbookmarklen": 17,
112 112 "node": "7b5709ab64cbc34da9b4367b64afff47f2c4ee83"
113 113 },
114 114 {
115 115 "active": false,
116 116 "bookmark": "book1",
117 117 "longestbookmarklen": 17,
118 118 "node": "b757f780b8ffd71267c6ccb32e0882d9d32a8cc0"
119 119 }
120 120 ]
121 121
122 122 JSON works with no bookmarks
123 123
124 124 $ hg book -d a-longer-bookmark
125 125 $ hg book -d book1
126 126 $ hg show bookmarks -T json
127 127 [
128 128 ]
129 129
130 130 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now