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