##// END OF EJS Templates
hgk: use set instead of dict
Benoit Boissinot -
r8459:1e63816c default
parent child Browse files
Show More
@@ -1,359 +1,359 b''
1 # Minimal support for git commands on an hg repository
1 # Minimal support for git commands on an hg repository
2 #
2 #
3 # Copyright 2005, 2006 Chris Mason <mason@suse.com>
3 # Copyright 2005, 2006 Chris Mason <mason@suse.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
7
7
8 '''browsing the repository in a graphical way
8 '''browsing the repository in a graphical way
9
9
10 The hgk extension allows browsing the history of a repository in a
10 The hgk extension allows browsing the history of a repository in a
11 graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not
11 graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not
12 distributed with Mercurial.)
12 distributed with Mercurial.)
13
13
14 hgk consists of two parts: a Tcl script that does the displaying and
14 hgk consists of two parts: a Tcl script that does the displaying and
15 querying of information, and an extension to mercurial named hgk.py,
15 querying of information, and an extension to mercurial named hgk.py,
16 which provides hooks for hgk to get information. hgk can be found in
16 which provides hooks for hgk to get information. hgk can be found in
17 the contrib directory, and hgk.py can be found in the hgext directory.
17 the contrib directory, and hgk.py can be found in the hgext directory.
18
18
19 To load the hgext.py extension, add it to your .hgrc file (you have to
19 To load the hgext.py extension, add it to your .hgrc file (you have to
20 use your global $HOME/.hgrc file, not one in a repository). You can
20 use your global $HOME/.hgrc file, not one in a repository). You can
21 specify an absolute path:
21 specify an absolute path:
22
22
23 [extensions]
23 [extensions]
24 hgk=/usr/local/lib/hgk.py
24 hgk=/usr/local/lib/hgk.py
25
25
26 Mercurial can also scan the default python library path for a file
26 Mercurial can also scan the default python library path for a file
27 named 'hgk.py' if you set hgk empty:
27 named 'hgk.py' if you set hgk empty:
28
28
29 [extensions]
29 [extensions]
30 hgk=
30 hgk=
31
31
32 The hg view command will launch the hgk Tcl script. For this command
32 The hg view command will launch the hgk Tcl script. For this command
33 to work, hgk must be in your search path. Alternately, you can specify
33 to work, hgk must be in your search path. Alternately, you can specify
34 the path to hgk in your .hgrc file:
34 the path to hgk in your .hgrc file:
35
35
36 [hgk]
36 [hgk]
37 path=/location/of/hgk
37 path=/location/of/hgk
38
38
39 hgk can make use of the extdiff extension to visualize revisions.
39 hgk can make use of the extdiff extension to visualize revisions.
40 Assuming you had already configured extdiff vdiff command, just add:
40 Assuming you had already configured extdiff vdiff command, just add:
41
41
42 [hgk]
42 [hgk]
43 vdiff=vdiff
43 vdiff=vdiff
44
44
45 Revisions context menu will now display additional entries to fire
45 Revisions context menu will now display additional entries to fire
46 vdiff on hovered and selected revisions.'''
46 vdiff on hovered and selected revisions.'''
47
47
48 import os
48 import os
49 from mercurial import commands, util, patch, revlog, cmdutil
49 from mercurial import commands, util, patch, revlog, cmdutil
50 from mercurial.node import nullid, nullrev, short
50 from mercurial.node import nullid, nullrev, short
51 from mercurial.i18n import _
51 from mercurial.i18n import _
52
52
53 def difftree(ui, repo, node1=None, node2=None, *files, **opts):
53 def difftree(ui, repo, node1=None, node2=None, *files, **opts):
54 """diff trees from two commits"""
54 """diff trees from two commits"""
55 def __difftree(repo, node1, node2, files=[]):
55 def __difftree(repo, node1, node2, files=[]):
56 assert node2 is not None
56 assert node2 is not None
57 mmap = repo[node1].manifest()
57 mmap = repo[node1].manifest()
58 mmap2 = repo[node2].manifest()
58 mmap2 = repo[node2].manifest()
59 m = cmdutil.match(repo, files)
59 m = cmdutil.match(repo, files)
60 modified, added, removed = repo.status(node1, node2, m)[:3]
60 modified, added, removed = repo.status(node1, node2, m)[:3]
61 empty = short(nullid)
61 empty = short(nullid)
62
62
63 for f in modified:
63 for f in modified:
64 # TODO get file permissions
64 # TODO get file permissions
65 ui.write(":100664 100664 %s %s M\t%s\t%s\n" %
65 ui.write(":100664 100664 %s %s M\t%s\t%s\n" %
66 (short(mmap[f]), short(mmap2[f]), f, f))
66 (short(mmap[f]), short(mmap2[f]), f, f))
67 for f in added:
67 for f in added:
68 ui.write(":000000 100664 %s %s N\t%s\t%s\n" %
68 ui.write(":000000 100664 %s %s N\t%s\t%s\n" %
69 (empty, short(mmap2[f]), f, f))
69 (empty, short(mmap2[f]), f, f))
70 for f in removed:
70 for f in removed:
71 ui.write(":100664 000000 %s %s D\t%s\t%s\n" %
71 ui.write(":100664 000000 %s %s D\t%s\t%s\n" %
72 (short(mmap[f]), empty, f, f))
72 (short(mmap[f]), empty, f, f))
73 ##
73 ##
74
74
75 while True:
75 while True:
76 if opts['stdin']:
76 if opts['stdin']:
77 try:
77 try:
78 line = raw_input().split(' ')
78 line = raw_input().split(' ')
79 node1 = line[0]
79 node1 = line[0]
80 if len(line) > 1:
80 if len(line) > 1:
81 node2 = line[1]
81 node2 = line[1]
82 else:
82 else:
83 node2 = None
83 node2 = None
84 except EOFError:
84 except EOFError:
85 break
85 break
86 node1 = repo.lookup(node1)
86 node1 = repo.lookup(node1)
87 if node2:
87 if node2:
88 node2 = repo.lookup(node2)
88 node2 = repo.lookup(node2)
89 else:
89 else:
90 node2 = node1
90 node2 = node1
91 node1 = repo.changelog.parents(node1)[0]
91 node1 = repo.changelog.parents(node1)[0]
92 if opts['patch']:
92 if opts['patch']:
93 if opts['pretty']:
93 if opts['pretty']:
94 catcommit(ui, repo, node2, "")
94 catcommit(ui, repo, node2, "")
95 m = cmdutil.match(repo, files)
95 m = cmdutil.match(repo, files)
96 chunks = patch.diff(repo, node1, node2, match=m,
96 chunks = patch.diff(repo, node1, node2, match=m,
97 opts=patch.diffopts(ui, {'git': True}))
97 opts=patch.diffopts(ui, {'git': True}))
98 for chunk in chunks:
98 for chunk in chunks:
99 repo.ui.write(chunk)
99 repo.ui.write(chunk)
100 else:
100 else:
101 __difftree(repo, node1, node2, files=files)
101 __difftree(repo, node1, node2, files=files)
102 if not opts['stdin']:
102 if not opts['stdin']:
103 break
103 break
104
104
105 def catcommit(ui, repo, n, prefix, ctx=None):
105 def catcommit(ui, repo, n, prefix, ctx=None):
106 nlprefix = '\n' + prefix;
106 nlprefix = '\n' + prefix;
107 if ctx is None:
107 if ctx is None:
108 ctx = repo[n]
108 ctx = repo[n]
109 ui.write("tree %s\n" % short(ctx.changeset()[0])) # use ctx.node() instead ??
109 ui.write("tree %s\n" % short(ctx.changeset()[0])) # use ctx.node() instead ??
110 for p in ctx.parents():
110 for p in ctx.parents():
111 ui.write("parent %s\n" % p)
111 ui.write("parent %s\n" % p)
112
112
113 date = ctx.date()
113 date = ctx.date()
114 description = ctx.description().replace("\0", "")
114 description = ctx.description().replace("\0", "")
115 lines = description.splitlines()
115 lines = description.splitlines()
116 if lines and lines[-1].startswith('committer:'):
116 if lines and lines[-1].startswith('committer:'):
117 committer = lines[-1].split(': ')[1].rstrip()
117 committer = lines[-1].split(': ')[1].rstrip()
118 else:
118 else:
119 committer = ctx.user()
119 committer = ctx.user()
120
120
121 ui.write("author %s %s %s\n" % (ctx.user(), int(date[0]), date[1]))
121 ui.write("author %s %s %s\n" % (ctx.user(), int(date[0]), date[1]))
122 ui.write("committer %s %s %s\n" % (committer, int(date[0]), date[1]))
122 ui.write("committer %s %s %s\n" % (committer, int(date[0]), date[1]))
123 ui.write("revision %d\n" % ctx.rev())
123 ui.write("revision %d\n" % ctx.rev())
124 ui.write("branch %s\n\n" % ctx.branch())
124 ui.write("branch %s\n\n" % ctx.branch())
125
125
126 if prefix != "":
126 if prefix != "":
127 ui.write("%s%s\n" % (prefix, description.replace('\n', nlprefix).strip()))
127 ui.write("%s%s\n" % (prefix, description.replace('\n', nlprefix).strip()))
128 else:
128 else:
129 ui.write(description + "\n")
129 ui.write(description + "\n")
130 if prefix:
130 if prefix:
131 ui.write('\0')
131 ui.write('\0')
132
132
133 def base(ui, repo, node1, node2):
133 def base(ui, repo, node1, node2):
134 """output common ancestor information"""
134 """output common ancestor information"""
135 node1 = repo.lookup(node1)
135 node1 = repo.lookup(node1)
136 node2 = repo.lookup(node2)
136 node2 = repo.lookup(node2)
137 n = repo.changelog.ancestor(node1, node2)
137 n = repo.changelog.ancestor(node1, node2)
138 ui.write(short(n) + "\n")
138 ui.write(short(n) + "\n")
139
139
140 def catfile(ui, repo, type=None, r=None, **opts):
140 def catfile(ui, repo, type=None, r=None, **opts):
141 """cat a specific revision"""
141 """cat a specific revision"""
142 # in stdin mode, every line except the commit is prefixed with two
142 # in stdin mode, every line except the commit is prefixed with two
143 # spaces. This way the our caller can find the commit without magic
143 # spaces. This way the our caller can find the commit without magic
144 # strings
144 # strings
145 #
145 #
146 prefix = ""
146 prefix = ""
147 if opts['stdin']:
147 if opts['stdin']:
148 try:
148 try:
149 (type, r) = raw_input().split(' ');
149 (type, r) = raw_input().split(' ');
150 prefix = " "
150 prefix = " "
151 except EOFError:
151 except EOFError:
152 return
152 return
153
153
154 else:
154 else:
155 if not type or not r:
155 if not type or not r:
156 ui.warn(_("cat-file: type or revision not supplied\n"))
156 ui.warn(_("cat-file: type or revision not supplied\n"))
157 commands.help_(ui, 'cat-file')
157 commands.help_(ui, 'cat-file')
158
158
159 while r:
159 while r:
160 if type != "commit":
160 if type != "commit":
161 ui.warn(_("aborting hg cat-file only understands commits\n"))
161 ui.warn(_("aborting hg cat-file only understands commits\n"))
162 return 1;
162 return 1;
163 n = repo.lookup(r)
163 n = repo.lookup(r)
164 catcommit(ui, repo, n, prefix)
164 catcommit(ui, repo, n, prefix)
165 if opts['stdin']:
165 if opts['stdin']:
166 try:
166 try:
167 (type, r) = raw_input().split(' ');
167 (type, r) = raw_input().split(' ');
168 except EOFError:
168 except EOFError:
169 break
169 break
170 else:
170 else:
171 break
171 break
172
172
173 # git rev-tree is a confusing thing. You can supply a number of
173 # git rev-tree is a confusing thing. You can supply a number of
174 # commit sha1s on the command line, and it walks the commit history
174 # commit sha1s on the command line, and it walks the commit history
175 # telling you which commits are reachable from the supplied ones via
175 # telling you which commits are reachable from the supplied ones via
176 # a bitmask based on arg position.
176 # a bitmask based on arg position.
177 # you can specify a commit to stop at by starting the sha1 with ^
177 # you can specify a commit to stop at by starting the sha1 with ^
178 def revtree(ui, args, repo, full="tree", maxnr=0, parents=False):
178 def revtree(ui, args, repo, full="tree", maxnr=0, parents=False):
179 def chlogwalk():
179 def chlogwalk():
180 count = len(repo)
180 count = len(repo)
181 i = count
181 i = count
182 l = [0] * 100
182 l = [0] * 100
183 chunk = 100
183 chunk = 100
184 while True:
184 while True:
185 if chunk > i:
185 if chunk > i:
186 chunk = i
186 chunk = i
187 i = 0
187 i = 0
188 else:
188 else:
189 i -= chunk
189 i -= chunk
190
190
191 for x in xrange(0, chunk):
191 for x in xrange(0, chunk):
192 if i + x >= count:
192 if i + x >= count:
193 l[chunk - x:] = [0] * (chunk - x)
193 l[chunk - x:] = [0] * (chunk - x)
194 break
194 break
195 if full != None:
195 if full != None:
196 l[x] = repo[i + x]
196 l[x] = repo[i + x]
197 l[x].changeset() # force reading
197 l[x].changeset() # force reading
198 else:
198 else:
199 l[x] = 1
199 l[x] = 1
200 for x in xrange(chunk-1, -1, -1):
200 for x in xrange(chunk-1, -1, -1):
201 if l[x] != 0:
201 if l[x] != 0:
202 yield (i + x, full != None and l[x] or None)
202 yield (i + x, full != None and l[x] or None)
203 if i == 0:
203 if i == 0:
204 break
204 break
205
205
206 # calculate and return the reachability bitmask for sha
206 # calculate and return the reachability bitmask for sha
207 def is_reachable(ar, reachable, sha):
207 def is_reachable(ar, reachable, sha):
208 if len(ar) == 0:
208 if len(ar) == 0:
209 return 1
209 return 1
210 mask = 0
210 mask = 0
211 for i in xrange(len(ar)):
211 for i in xrange(len(ar)):
212 if sha in reachable[i]:
212 if sha in reachable[i]:
213 mask |= 1 << i
213 mask |= 1 << i
214
214
215 return mask
215 return mask
216
216
217 reachable = []
217 reachable = []
218 stop_sha1 = []
218 stop_sha1 = []
219 want_sha1 = []
219 want_sha1 = []
220 count = 0
220 count = 0
221
221
222 # figure out which commits they are asking for and which ones they
222 # figure out which commits they are asking for and which ones they
223 # want us to stop on
223 # want us to stop on
224 for i in xrange(len(args)):
224 for i in xrange(len(args)):
225 if args[i].startswith('^'):
225 if args[i].startswith('^'):
226 s = repo.lookup(args[i][1:])
226 s = repo.lookup(args[i][1:])
227 stop_sha1.append(s)
227 stop_sha1.append(s)
228 want_sha1.append(s)
228 want_sha1.append(s)
229 elif args[i] != 'HEAD':
229 elif args[i] != 'HEAD':
230 want_sha1.append(repo.lookup(args[i]))
230 want_sha1.append(repo.lookup(args[i]))
231
231
232 # calculate the graph for the supplied commits
232 # calculate the graph for the supplied commits
233 for i in xrange(len(want_sha1)):
233 for i in xrange(len(want_sha1)):
234 reachable.append({});
234 reachable.append(set());
235 n = want_sha1[i];
235 n = want_sha1[i];
236 visit = [n];
236 visit = [n];
237 reachable[i][n] = 1
237 reachable[i].add(n)
238 while visit:
238 while visit:
239 n = visit.pop(0)
239 n = visit.pop(0)
240 if n in stop_sha1:
240 if n in stop_sha1:
241 continue
241 continue
242 for p in repo.changelog.parents(n):
242 for p in repo.changelog.parents(n):
243 if p not in reachable[i]:
243 if p not in reachable[i]:
244 reachable[i][p] = 1
244 reachable[i].add(p)
245 visit.append(p)
245 visit.append(p)
246 if p in stop_sha1:
246 if p in stop_sha1:
247 continue
247 continue
248
248
249 # walk the repository looking for commits that are in our
249 # walk the repository looking for commits that are in our
250 # reachability graph
250 # reachability graph
251 for i, ctx in chlogwalk():
251 for i, ctx in chlogwalk():
252 n = repo.changelog.node(i)
252 n = repo.changelog.node(i)
253 mask = is_reachable(want_sha1, reachable, n)
253 mask = is_reachable(want_sha1, reachable, n)
254 if mask:
254 if mask:
255 parentstr = ""
255 parentstr = ""
256 if parents:
256 if parents:
257 pp = repo.changelog.parents(n)
257 pp = repo.changelog.parents(n)
258 if pp[0] != nullid:
258 if pp[0] != nullid:
259 parentstr += " " + short(pp[0])
259 parentstr += " " + short(pp[0])
260 if pp[1] != nullid:
260 if pp[1] != nullid:
261 parentstr += " " + short(pp[1])
261 parentstr += " " + short(pp[1])
262 if not full:
262 if not full:
263 ui.write("%s%s\n" % (short(n), parentstr))
263 ui.write("%s%s\n" % (short(n), parentstr))
264 elif full == "commit":
264 elif full == "commit":
265 ui.write("%s%s\n" % (short(n), parentstr))
265 ui.write("%s%s\n" % (short(n), parentstr))
266 catcommit(ui, repo, n, ' ', ctx)
266 catcommit(ui, repo, n, ' ', ctx)
267 else:
267 else:
268 (p1, p2) = repo.changelog.parents(n)
268 (p1, p2) = repo.changelog.parents(n)
269 (h, h1, h2) = map(short, (n, p1, p2))
269 (h, h1, h2) = map(short, (n, p1, p2))
270 (i1, i2) = map(repo.changelog.rev, (p1, p2))
270 (i1, i2) = map(repo.changelog.rev, (p1, p2))
271
271
272 date = ctx.date()[0]
272 date = ctx.date()[0]
273 ui.write("%s %s:%s" % (date, h, mask))
273 ui.write("%s %s:%s" % (date, h, mask))
274 mask = is_reachable(want_sha1, reachable, p1)
274 mask = is_reachable(want_sha1, reachable, p1)
275 if i1 != nullrev and mask > 0:
275 if i1 != nullrev and mask > 0:
276 ui.write("%s:%s " % (h1, mask)),
276 ui.write("%s:%s " % (h1, mask)),
277 mask = is_reachable(want_sha1, reachable, p2)
277 mask = is_reachable(want_sha1, reachable, p2)
278 if i2 != nullrev and mask > 0:
278 if i2 != nullrev and mask > 0:
279 ui.write("%s:%s " % (h2, mask))
279 ui.write("%s:%s " % (h2, mask))
280 ui.write("\n")
280 ui.write("\n")
281 if maxnr and count >= maxnr:
281 if maxnr and count >= maxnr:
282 break
282 break
283 count += 1
283 count += 1
284
284
285 def revparse(ui, repo, *revs, **opts):
285 def revparse(ui, repo, *revs, **opts):
286 """parse given revisions"""
286 """parse given revisions"""
287 def revstr(rev):
287 def revstr(rev):
288 if rev == 'HEAD':
288 if rev == 'HEAD':
289 rev = 'tip'
289 rev = 'tip'
290 return revlog.hex(repo.lookup(rev))
290 return revlog.hex(repo.lookup(rev))
291
291
292 for r in revs:
292 for r in revs:
293 revrange = r.split(':', 1)
293 revrange = r.split(':', 1)
294 ui.write('%s\n' % revstr(revrange[0]))
294 ui.write('%s\n' % revstr(revrange[0]))
295 if len(revrange) == 2:
295 if len(revrange) == 2:
296 ui.write('^%s\n' % revstr(revrange[1]))
296 ui.write('^%s\n' % revstr(revrange[1]))
297
297
298 # git rev-list tries to order things by date, and has the ability to stop
298 # git rev-list tries to order things by date, and has the ability to stop
299 # at a given commit without walking the whole repo. TODO add the stop
299 # at a given commit without walking the whole repo. TODO add the stop
300 # parameter
300 # parameter
301 def revlist(ui, repo, *revs, **opts):
301 def revlist(ui, repo, *revs, **opts):
302 """print revisions"""
302 """print revisions"""
303 if opts['header']:
303 if opts['header']:
304 full = "commit"
304 full = "commit"
305 else:
305 else:
306 full = None
306 full = None
307 copy = [x for x in revs]
307 copy = [x for x in revs]
308 revtree(ui, copy, repo, full, opts['max_count'], opts['parents'])
308 revtree(ui, copy, repo, full, opts['max_count'], opts['parents'])
309
309
310 def config(ui, repo, **opts):
310 def config(ui, repo, **opts):
311 """print extension options"""
311 """print extension options"""
312 def writeopt(name, value):
312 def writeopt(name, value):
313 ui.write('k=%s\nv=%s\n' % (name, value))
313 ui.write('k=%s\nv=%s\n' % (name, value))
314
314
315 writeopt('vdiff', ui.config('hgk', 'vdiff', ''))
315 writeopt('vdiff', ui.config('hgk', 'vdiff', ''))
316
316
317
317
318 def view(ui, repo, *etc, **opts):
318 def view(ui, repo, *etc, **opts):
319 "start interactive history viewer"
319 "start interactive history viewer"
320 os.chdir(repo.root)
320 os.chdir(repo.root)
321 optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems() if v])
321 optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems() if v])
322 cmd = ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc))
322 cmd = ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc))
323 ui.debug(_("running %s\n") % cmd)
323 ui.debug(_("running %s\n") % cmd)
324 util.system(cmd)
324 util.system(cmd)
325
325
326 cmdtable = {
326 cmdtable = {
327 "^view":
327 "^view":
328 (view,
328 (view,
329 [('l', 'limit', '', _('limit number of changes displayed'))],
329 [('l', 'limit', '', _('limit number of changes displayed'))],
330 _('hg view [-l LIMIT] [REVRANGE]')),
330 _('hg view [-l LIMIT] [REVRANGE]')),
331 "debug-diff-tree":
331 "debug-diff-tree":
332 (difftree,
332 (difftree,
333 [('p', 'patch', None, _('generate patch')),
333 [('p', 'patch', None, _('generate patch')),
334 ('r', 'recursive', None, _('recursive')),
334 ('r', 'recursive', None, _('recursive')),
335 ('P', 'pretty', None, _('pretty')),
335 ('P', 'pretty', None, _('pretty')),
336 ('s', 'stdin', None, _('stdin')),
336 ('s', 'stdin', None, _('stdin')),
337 ('C', 'copy', None, _('detect copies')),
337 ('C', 'copy', None, _('detect copies')),
338 ('S', 'search', "", _('search'))],
338 ('S', 'search', "", _('search'))],
339 _('hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]...')),
339 _('hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]...')),
340 "debug-cat-file":
340 "debug-cat-file":
341 (catfile,
341 (catfile,
342 [('s', 'stdin', None, _('stdin'))],
342 [('s', 'stdin', None, _('stdin'))],
343 _('hg debug-cat-file [OPTION]... TYPE FILE')),
343 _('hg debug-cat-file [OPTION]... TYPE FILE')),
344 "debug-config":
344 "debug-config":
345 (config, [], _('hg debug-config')),
345 (config, [], _('hg debug-config')),
346 "debug-merge-base":
346 "debug-merge-base":
347 (base, [], _('hg debug-merge-base node node')),
347 (base, [], _('hg debug-merge-base node node')),
348 "debug-rev-parse":
348 "debug-rev-parse":
349 (revparse,
349 (revparse,
350 [('', 'default', '', _('ignored'))],
350 [('', 'default', '', _('ignored'))],
351 _('hg debug-rev-parse REV')),
351 _('hg debug-rev-parse REV')),
352 "debug-rev-list":
352 "debug-rev-list":
353 (revlist,
353 (revlist,
354 [('H', 'header', None, _('header')),
354 [('H', 'header', None, _('header')),
355 ('t', 'topo-order', None, _('topo-order')),
355 ('t', 'topo-order', None, _('topo-order')),
356 ('p', 'parents', None, _('parents')),
356 ('p', 'parents', None, _('parents')),
357 ('n', 'max-count', 0, _('max-count'))],
357 ('n', 'max-count', 0, _('max-count'))],
358 _('hg debug-rev-list [options] revs')),
358 _('hg debug-rev-list [options] revs')),
359 }
359 }
General Comments 0
You need to be logged in to leave comments. Login now