##// END OF EJS Templates
help: add -e/--extension switch to display extension help text
Henri Wiechers -
r14284:1f9e11f6 default
parent child Browse files
Show More
@@ -1,4994 +1,4998 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.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 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from node import hex, bin, nullid, nullrev, short
8 from node import hex, bin, nullid, nullrev, short
9 from lock import release
9 from lock import release
10 from i18n import _, gettext
10 from i18n import _, gettext
11 import os, re, sys, difflib, time, tempfile
11 import os, re, sys, difflib, time, tempfile
12 import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
12 import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
13 import patch, help, url, encoding, templatekw, discovery
13 import patch, help, url, encoding, templatekw, discovery
14 import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
14 import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
15 import merge as mergemod
15 import merge as mergemod
16 import minirst, revset, templatefilters
16 import minirst, revset, templatefilters
17 import dagparser, context, simplemerge
17 import dagparser, context, simplemerge
18 import random, setdiscovery, treediscovery, dagutil
18 import random, setdiscovery, treediscovery, dagutil
19
19
20 # Commands start here, listed alphabetically
20 # Commands start here, listed alphabetically
21
21
22 def add(ui, repo, *pats, **opts):
22 def add(ui, repo, *pats, **opts):
23 """add the specified files on the next commit
23 """add the specified files on the next commit
24
24
25 Schedule files to be version controlled and added to the
25 Schedule files to be version controlled and added to the
26 repository.
26 repository.
27
27
28 The files will be added to the repository at the next commit. To
28 The files will be added to the repository at the next commit. To
29 undo an add before that, see :hg:`forget`.
29 undo an add before that, see :hg:`forget`.
30
30
31 If no names are given, add all files to the repository.
31 If no names are given, add all files to the repository.
32
32
33 .. container:: verbose
33 .. container:: verbose
34
34
35 An example showing how new (unknown) files are added
35 An example showing how new (unknown) files are added
36 automatically by :hg:`add`::
36 automatically by :hg:`add`::
37
37
38 $ ls
38 $ ls
39 foo.c
39 foo.c
40 $ hg status
40 $ hg status
41 ? foo.c
41 ? foo.c
42 $ hg add
42 $ hg add
43 adding foo.c
43 adding foo.c
44 $ hg status
44 $ hg status
45 A foo.c
45 A foo.c
46
46
47 Returns 0 if all files are successfully added.
47 Returns 0 if all files are successfully added.
48 """
48 """
49
49
50 m = cmdutil.match(repo, pats, opts)
50 m = cmdutil.match(repo, pats, opts)
51 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
51 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
52 opts.get('subrepos'), prefix="")
52 opts.get('subrepos'), prefix="")
53 return rejected and 1 or 0
53 return rejected and 1 or 0
54
54
55 def addremove(ui, repo, *pats, **opts):
55 def addremove(ui, repo, *pats, **opts):
56 """add all new files, delete all missing files
56 """add all new files, delete all missing files
57
57
58 Add all new files and remove all missing files from the
58 Add all new files and remove all missing files from the
59 repository.
59 repository.
60
60
61 New files are ignored if they match any of the patterns in
61 New files are ignored if they match any of the patterns in
62 ``.hgignore``. As with add, these changes take effect at the next
62 ``.hgignore``. As with add, these changes take effect at the next
63 commit.
63 commit.
64
64
65 Use the -s/--similarity option to detect renamed files. With a
65 Use the -s/--similarity option to detect renamed files. With a
66 parameter greater than 0, this compares every removed file with
66 parameter greater than 0, this compares every removed file with
67 every added file and records those similar enough as renames. This
67 every added file and records those similar enough as renames. This
68 option takes a percentage between 0 (disabled) and 100 (files must
68 option takes a percentage between 0 (disabled) and 100 (files must
69 be identical) as its parameter. Detecting renamed files this way
69 be identical) as its parameter. Detecting renamed files this way
70 can be expensive. After using this option, :hg:`status -C` can be
70 can be expensive. After using this option, :hg:`status -C` can be
71 used to check which files were identified as moved or renamed.
71 used to check which files were identified as moved or renamed.
72
72
73 Returns 0 if all files are successfully added.
73 Returns 0 if all files are successfully added.
74 """
74 """
75 try:
75 try:
76 sim = float(opts.get('similarity') or 100)
76 sim = float(opts.get('similarity') or 100)
77 except ValueError:
77 except ValueError:
78 raise util.Abort(_('similarity must be a number'))
78 raise util.Abort(_('similarity must be a number'))
79 if sim < 0 or sim > 100:
79 if sim < 0 or sim > 100:
80 raise util.Abort(_('similarity must be between 0 and 100'))
80 raise util.Abort(_('similarity must be between 0 and 100'))
81 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
81 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
82
82
83 def annotate(ui, repo, *pats, **opts):
83 def annotate(ui, repo, *pats, **opts):
84 """show changeset information by line for each file
84 """show changeset information by line for each file
85
85
86 List changes in files, showing the revision id responsible for
86 List changes in files, showing the revision id responsible for
87 each line
87 each line
88
88
89 This command is useful for discovering when a change was made and
89 This command is useful for discovering when a change was made and
90 by whom.
90 by whom.
91
91
92 Without the -a/--text option, annotate will avoid processing files
92 Without the -a/--text option, annotate will avoid processing files
93 it detects as binary. With -a, annotate will annotate the file
93 it detects as binary. With -a, annotate will annotate the file
94 anyway, although the results will probably be neither useful
94 anyway, although the results will probably be neither useful
95 nor desirable.
95 nor desirable.
96
96
97 Returns 0 on success.
97 Returns 0 on success.
98 """
98 """
99 if opts.get('follow'):
99 if opts.get('follow'):
100 # --follow is deprecated and now just an alias for -f/--file
100 # --follow is deprecated and now just an alias for -f/--file
101 # to mimic the behavior of Mercurial before version 1.5
101 # to mimic the behavior of Mercurial before version 1.5
102 opts['file'] = True
102 opts['file'] = True
103
103
104 datefunc = ui.quiet and util.shortdate or util.datestr
104 datefunc = ui.quiet and util.shortdate or util.datestr
105 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
105 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
106
106
107 if not pats:
107 if not pats:
108 raise util.Abort(_('at least one filename or pattern is required'))
108 raise util.Abort(_('at least one filename or pattern is required'))
109
109
110 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
110 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
111 ('number', lambda x: str(x[0].rev())),
111 ('number', lambda x: str(x[0].rev())),
112 ('changeset', lambda x: short(x[0].node())),
112 ('changeset', lambda x: short(x[0].node())),
113 ('date', getdate),
113 ('date', getdate),
114 ('file', lambda x: x[0].path()),
114 ('file', lambda x: x[0].path()),
115 ]
115 ]
116
116
117 if (not opts.get('user') and not opts.get('changeset')
117 if (not opts.get('user') and not opts.get('changeset')
118 and not opts.get('date') and not opts.get('file')):
118 and not opts.get('date') and not opts.get('file')):
119 opts['number'] = True
119 opts['number'] = True
120
120
121 linenumber = opts.get('line_number') is not None
121 linenumber = opts.get('line_number') is not None
122 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
122 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
123 raise util.Abort(_('at least one of -n/-c is required for -l'))
123 raise util.Abort(_('at least one of -n/-c is required for -l'))
124
124
125 funcmap = [func for op, func in opmap if opts.get(op)]
125 funcmap = [func for op, func in opmap if opts.get(op)]
126 if linenumber:
126 if linenumber:
127 lastfunc = funcmap[-1]
127 lastfunc = funcmap[-1]
128 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
128 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
129
129
130 def bad(x, y):
130 def bad(x, y):
131 raise util.Abort("%s: %s" % (x, y))
131 raise util.Abort("%s: %s" % (x, y))
132
132
133 ctx = cmdutil.revsingle(repo, opts.get('rev'))
133 ctx = cmdutil.revsingle(repo, opts.get('rev'))
134 m = cmdutil.match(repo, pats, opts)
134 m = cmdutil.match(repo, pats, opts)
135 m.bad = bad
135 m.bad = bad
136 follow = not opts.get('no_follow')
136 follow = not opts.get('no_follow')
137 for abs in ctx.walk(m):
137 for abs in ctx.walk(m):
138 fctx = ctx[abs]
138 fctx = ctx[abs]
139 if not opts.get('text') and util.binary(fctx.data()):
139 if not opts.get('text') and util.binary(fctx.data()):
140 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
140 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
141 continue
141 continue
142
142
143 lines = fctx.annotate(follow=follow, linenumber=linenumber)
143 lines = fctx.annotate(follow=follow, linenumber=linenumber)
144 pieces = []
144 pieces = []
145
145
146 for f in funcmap:
146 for f in funcmap:
147 l = [f(n) for n, dummy in lines]
147 l = [f(n) for n, dummy in lines]
148 if l:
148 if l:
149 sized = [(x, encoding.colwidth(x)) for x in l]
149 sized = [(x, encoding.colwidth(x)) for x in l]
150 ml = max([w for x, w in sized])
150 ml = max([w for x, w in sized])
151 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
151 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
152
152
153 if pieces:
153 if pieces:
154 for p, l in zip(zip(*pieces), lines):
154 for p, l in zip(zip(*pieces), lines):
155 ui.write("%s: %s" % (" ".join(p), l[1]))
155 ui.write("%s: %s" % (" ".join(p), l[1]))
156
156
157 def archive(ui, repo, dest, **opts):
157 def archive(ui, repo, dest, **opts):
158 '''create an unversioned archive of a repository revision
158 '''create an unversioned archive of a repository revision
159
159
160 By default, the revision used is the parent of the working
160 By default, the revision used is the parent of the working
161 directory; use -r/--rev to specify a different revision.
161 directory; use -r/--rev to specify a different revision.
162
162
163 The archive type is automatically detected based on file
163 The archive type is automatically detected based on file
164 extension (or override using -t/--type).
164 extension (or override using -t/--type).
165
165
166 Valid types are:
166 Valid types are:
167
167
168 :``files``: a directory full of files (default)
168 :``files``: a directory full of files (default)
169 :``tar``: tar archive, uncompressed
169 :``tar``: tar archive, uncompressed
170 :``tbz2``: tar archive, compressed using bzip2
170 :``tbz2``: tar archive, compressed using bzip2
171 :``tgz``: tar archive, compressed using gzip
171 :``tgz``: tar archive, compressed using gzip
172 :``uzip``: zip archive, uncompressed
172 :``uzip``: zip archive, uncompressed
173 :``zip``: zip archive, compressed using deflate
173 :``zip``: zip archive, compressed using deflate
174
174
175 The exact name of the destination archive or directory is given
175 The exact name of the destination archive or directory is given
176 using a format string; see :hg:`help export` for details.
176 using a format string; see :hg:`help export` for details.
177
177
178 Each member added to an archive file has a directory prefix
178 Each member added to an archive file has a directory prefix
179 prepended. Use -p/--prefix to specify a format string for the
179 prepended. Use -p/--prefix to specify a format string for the
180 prefix. The default is the basename of the archive, with suffixes
180 prefix. The default is the basename of the archive, with suffixes
181 removed.
181 removed.
182
182
183 Returns 0 on success.
183 Returns 0 on success.
184 '''
184 '''
185
185
186 ctx = cmdutil.revsingle(repo, opts.get('rev'))
186 ctx = cmdutil.revsingle(repo, opts.get('rev'))
187 if not ctx:
187 if not ctx:
188 raise util.Abort(_('no working directory: please specify a revision'))
188 raise util.Abort(_('no working directory: please specify a revision'))
189 node = ctx.node()
189 node = ctx.node()
190 dest = cmdutil.make_filename(repo, dest, node)
190 dest = cmdutil.make_filename(repo, dest, node)
191 if os.path.realpath(dest) == repo.root:
191 if os.path.realpath(dest) == repo.root:
192 raise util.Abort(_('repository root cannot be destination'))
192 raise util.Abort(_('repository root cannot be destination'))
193
193
194 kind = opts.get('type') or archival.guesskind(dest) or 'files'
194 kind = opts.get('type') or archival.guesskind(dest) or 'files'
195 prefix = opts.get('prefix')
195 prefix = opts.get('prefix')
196
196
197 if dest == '-':
197 if dest == '-':
198 if kind == 'files':
198 if kind == 'files':
199 raise util.Abort(_('cannot archive plain files to stdout'))
199 raise util.Abort(_('cannot archive plain files to stdout'))
200 dest = sys.stdout
200 dest = sys.stdout
201 if not prefix:
201 if not prefix:
202 prefix = os.path.basename(repo.root) + '-%h'
202 prefix = os.path.basename(repo.root) + '-%h'
203
203
204 prefix = cmdutil.make_filename(repo, prefix, node)
204 prefix = cmdutil.make_filename(repo, prefix, node)
205 matchfn = cmdutil.match(repo, [], opts)
205 matchfn = cmdutil.match(repo, [], opts)
206 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
206 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
207 matchfn, prefix, subrepos=opts.get('subrepos'))
207 matchfn, prefix, subrepos=opts.get('subrepos'))
208
208
209 def backout(ui, repo, node=None, rev=None, **opts):
209 def backout(ui, repo, node=None, rev=None, **opts):
210 '''reverse effect of earlier changeset
210 '''reverse effect of earlier changeset
211
211
212 Prepare a new changeset with the effect of REV undone in the
212 Prepare a new changeset with the effect of REV undone in the
213 current working directory.
213 current working directory.
214
214
215 If REV is the parent of the working directory, then this new changeset
215 If REV is the parent of the working directory, then this new changeset
216 is committed automatically. Otherwise, hg needs to merge the
216 is committed automatically. Otherwise, hg needs to merge the
217 changes and the merged result is left uncommitted.
217 changes and the merged result is left uncommitted.
218
218
219 By default, the pending changeset will have one parent,
219 By default, the pending changeset will have one parent,
220 maintaining a linear history. With --merge, the pending changeset
220 maintaining a linear history. With --merge, the pending changeset
221 will instead have two parents: the old parent of the working
221 will instead have two parents: the old parent of the working
222 directory and a new child of REV that simply undoes REV.
222 directory and a new child of REV that simply undoes REV.
223
223
224 Before version 1.7, the behavior without --merge was equivalent to
224 Before version 1.7, the behavior without --merge was equivalent to
225 specifying --merge followed by :hg:`update --clean .` to cancel
225 specifying --merge followed by :hg:`update --clean .` to cancel
226 the merge and leave the child of REV as a head to be merged
226 the merge and leave the child of REV as a head to be merged
227 separately.
227 separately.
228
228
229 See :hg:`help dates` for a list of formats valid for -d/--date.
229 See :hg:`help dates` for a list of formats valid for -d/--date.
230
230
231 Returns 0 on success.
231 Returns 0 on success.
232 '''
232 '''
233 if rev and node:
233 if rev and node:
234 raise util.Abort(_("please specify just one revision"))
234 raise util.Abort(_("please specify just one revision"))
235
235
236 if not rev:
236 if not rev:
237 rev = node
237 rev = node
238
238
239 if not rev:
239 if not rev:
240 raise util.Abort(_("please specify a revision to backout"))
240 raise util.Abort(_("please specify a revision to backout"))
241
241
242 date = opts.get('date')
242 date = opts.get('date')
243 if date:
243 if date:
244 opts['date'] = util.parsedate(date)
244 opts['date'] = util.parsedate(date)
245
245
246 cmdutil.bail_if_changed(repo)
246 cmdutil.bail_if_changed(repo)
247 node = cmdutil.revsingle(repo, rev).node()
247 node = cmdutil.revsingle(repo, rev).node()
248
248
249 op1, op2 = repo.dirstate.parents()
249 op1, op2 = repo.dirstate.parents()
250 a = repo.changelog.ancestor(op1, node)
250 a = repo.changelog.ancestor(op1, node)
251 if a != node:
251 if a != node:
252 raise util.Abort(_('cannot backout change on a different branch'))
252 raise util.Abort(_('cannot backout change on a different branch'))
253
253
254 p1, p2 = repo.changelog.parents(node)
254 p1, p2 = repo.changelog.parents(node)
255 if p1 == nullid:
255 if p1 == nullid:
256 raise util.Abort(_('cannot backout a change with no parents'))
256 raise util.Abort(_('cannot backout a change with no parents'))
257 if p2 != nullid:
257 if p2 != nullid:
258 if not opts.get('parent'):
258 if not opts.get('parent'):
259 raise util.Abort(_('cannot backout a merge changeset without '
259 raise util.Abort(_('cannot backout a merge changeset without '
260 '--parent'))
260 '--parent'))
261 p = repo.lookup(opts['parent'])
261 p = repo.lookup(opts['parent'])
262 if p not in (p1, p2):
262 if p not in (p1, p2):
263 raise util.Abort(_('%s is not a parent of %s') %
263 raise util.Abort(_('%s is not a parent of %s') %
264 (short(p), short(node)))
264 (short(p), short(node)))
265 parent = p
265 parent = p
266 else:
266 else:
267 if opts.get('parent'):
267 if opts.get('parent'):
268 raise util.Abort(_('cannot use --parent on non-merge changeset'))
268 raise util.Abort(_('cannot use --parent on non-merge changeset'))
269 parent = p1
269 parent = p1
270
270
271 # the backout should appear on the same branch
271 # the backout should appear on the same branch
272 branch = repo.dirstate.branch()
272 branch = repo.dirstate.branch()
273 hg.clean(repo, node, show_stats=False)
273 hg.clean(repo, node, show_stats=False)
274 repo.dirstate.setbranch(branch)
274 repo.dirstate.setbranch(branch)
275 revert_opts = opts.copy()
275 revert_opts = opts.copy()
276 revert_opts['date'] = None
276 revert_opts['date'] = None
277 revert_opts['all'] = True
277 revert_opts['all'] = True
278 revert_opts['rev'] = hex(parent)
278 revert_opts['rev'] = hex(parent)
279 revert_opts['no_backup'] = None
279 revert_opts['no_backup'] = None
280 revert(ui, repo, **revert_opts)
280 revert(ui, repo, **revert_opts)
281 if not opts.get('merge') and op1 != node:
281 if not opts.get('merge') and op1 != node:
282 try:
282 try:
283 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
283 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
284 return hg.update(repo, op1)
284 return hg.update(repo, op1)
285 finally:
285 finally:
286 ui.setconfig('ui', 'forcemerge', '')
286 ui.setconfig('ui', 'forcemerge', '')
287
287
288 commit_opts = opts.copy()
288 commit_opts = opts.copy()
289 commit_opts['addremove'] = False
289 commit_opts['addremove'] = False
290 if not commit_opts['message'] and not commit_opts['logfile']:
290 if not commit_opts['message'] and not commit_opts['logfile']:
291 # we don't translate commit messages
291 # we don't translate commit messages
292 commit_opts['message'] = "Backed out changeset %s" % short(node)
292 commit_opts['message'] = "Backed out changeset %s" % short(node)
293 commit_opts['force_editor'] = True
293 commit_opts['force_editor'] = True
294 commit(ui, repo, **commit_opts)
294 commit(ui, repo, **commit_opts)
295 def nice(node):
295 def nice(node):
296 return '%d:%s' % (repo.changelog.rev(node), short(node))
296 return '%d:%s' % (repo.changelog.rev(node), short(node))
297 ui.status(_('changeset %s backs out changeset %s\n') %
297 ui.status(_('changeset %s backs out changeset %s\n') %
298 (nice(repo.changelog.tip()), nice(node)))
298 (nice(repo.changelog.tip()), nice(node)))
299 if opts.get('merge') and op1 != node:
299 if opts.get('merge') and op1 != node:
300 hg.clean(repo, op1, show_stats=False)
300 hg.clean(repo, op1, show_stats=False)
301 ui.status(_('merging with changeset %s\n')
301 ui.status(_('merging with changeset %s\n')
302 % nice(repo.changelog.tip()))
302 % nice(repo.changelog.tip()))
303 try:
303 try:
304 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
304 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
305 return hg.merge(repo, hex(repo.changelog.tip()))
305 return hg.merge(repo, hex(repo.changelog.tip()))
306 finally:
306 finally:
307 ui.setconfig('ui', 'forcemerge', '')
307 ui.setconfig('ui', 'forcemerge', '')
308 return 0
308 return 0
309
309
310 def bisect(ui, repo, rev=None, extra=None, command=None,
310 def bisect(ui, repo, rev=None, extra=None, command=None,
311 reset=None, good=None, bad=None, skip=None, extend=None,
311 reset=None, good=None, bad=None, skip=None, extend=None,
312 noupdate=None):
312 noupdate=None):
313 """subdivision search of changesets
313 """subdivision search of changesets
314
314
315 This command helps to find changesets which introduce problems. To
315 This command helps to find changesets which introduce problems. To
316 use, mark the earliest changeset you know exhibits the problem as
316 use, mark the earliest changeset you know exhibits the problem as
317 bad, then mark the latest changeset which is free from the problem
317 bad, then mark the latest changeset which is free from the problem
318 as good. Bisect will update your working directory to a revision
318 as good. Bisect will update your working directory to a revision
319 for testing (unless the -U/--noupdate option is specified). Once
319 for testing (unless the -U/--noupdate option is specified). Once
320 you have performed tests, mark the working directory as good or
320 you have performed tests, mark the working directory as good or
321 bad, and bisect will either update to another candidate changeset
321 bad, and bisect will either update to another candidate changeset
322 or announce that it has found the bad revision.
322 or announce that it has found the bad revision.
323
323
324 As a shortcut, you can also use the revision argument to mark a
324 As a shortcut, you can also use the revision argument to mark a
325 revision as good or bad without checking it out first.
325 revision as good or bad without checking it out first.
326
326
327 If you supply a command, it will be used for automatic bisection.
327 If you supply a command, it will be used for automatic bisection.
328 Its exit status will be used to mark revisions as good or bad:
328 Its exit status will be used to mark revisions as good or bad:
329 status 0 means good, 125 means to skip the revision, 127
329 status 0 means good, 125 means to skip the revision, 127
330 (command not found) will abort the bisection, and any other
330 (command not found) will abort the bisection, and any other
331 non-zero exit status means the revision is bad.
331 non-zero exit status means the revision is bad.
332
332
333 Returns 0 on success.
333 Returns 0 on success.
334 """
334 """
335 def extendbisectrange(nodes, good):
335 def extendbisectrange(nodes, good):
336 # bisect is incomplete when it ends on a merge node and
336 # bisect is incomplete when it ends on a merge node and
337 # one of the parent was not checked.
337 # one of the parent was not checked.
338 parents = repo[nodes[0]].parents()
338 parents = repo[nodes[0]].parents()
339 if len(parents) > 1:
339 if len(parents) > 1:
340 side = good and state['bad'] or state['good']
340 side = good and state['bad'] or state['good']
341 num = len(set(i.node() for i in parents) & set(side))
341 num = len(set(i.node() for i in parents) & set(side))
342 if num == 1:
342 if num == 1:
343 return parents[0].ancestor(parents[1])
343 return parents[0].ancestor(parents[1])
344 return None
344 return None
345
345
346 def print_result(nodes, good):
346 def print_result(nodes, good):
347 displayer = cmdutil.show_changeset(ui, repo, {})
347 displayer = cmdutil.show_changeset(ui, repo, {})
348 if len(nodes) == 1:
348 if len(nodes) == 1:
349 # narrowed it down to a single revision
349 # narrowed it down to a single revision
350 if good:
350 if good:
351 ui.write(_("The first good revision is:\n"))
351 ui.write(_("The first good revision is:\n"))
352 else:
352 else:
353 ui.write(_("The first bad revision is:\n"))
353 ui.write(_("The first bad revision is:\n"))
354 displayer.show(repo[nodes[0]])
354 displayer.show(repo[nodes[0]])
355 extendnode = extendbisectrange(nodes, good)
355 extendnode = extendbisectrange(nodes, good)
356 if extendnode is not None:
356 if extendnode is not None:
357 ui.write(_('Not all ancestors of this changeset have been'
357 ui.write(_('Not all ancestors of this changeset have been'
358 ' checked.\nUse bisect --extend to continue the '
358 ' checked.\nUse bisect --extend to continue the '
359 'bisection from\nthe common ancestor, %s.\n')
359 'bisection from\nthe common ancestor, %s.\n')
360 % extendnode)
360 % extendnode)
361 else:
361 else:
362 # multiple possible revisions
362 # multiple possible revisions
363 if good:
363 if good:
364 ui.write(_("Due to skipped revisions, the first "
364 ui.write(_("Due to skipped revisions, the first "
365 "good revision could be any of:\n"))
365 "good revision could be any of:\n"))
366 else:
366 else:
367 ui.write(_("Due to skipped revisions, the first "
367 ui.write(_("Due to skipped revisions, the first "
368 "bad revision could be any of:\n"))
368 "bad revision could be any of:\n"))
369 for n in nodes:
369 for n in nodes:
370 displayer.show(repo[n])
370 displayer.show(repo[n])
371 displayer.close()
371 displayer.close()
372
372
373 def check_state(state, interactive=True):
373 def check_state(state, interactive=True):
374 if not state['good'] or not state['bad']:
374 if not state['good'] or not state['bad']:
375 if (good or bad or skip or reset) and interactive:
375 if (good or bad or skip or reset) and interactive:
376 return
376 return
377 if not state['good']:
377 if not state['good']:
378 raise util.Abort(_('cannot bisect (no known good revisions)'))
378 raise util.Abort(_('cannot bisect (no known good revisions)'))
379 else:
379 else:
380 raise util.Abort(_('cannot bisect (no known bad revisions)'))
380 raise util.Abort(_('cannot bisect (no known bad revisions)'))
381 return True
381 return True
382
382
383 # backward compatibility
383 # backward compatibility
384 if rev in "good bad reset init".split():
384 if rev in "good bad reset init".split():
385 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
385 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
386 cmd, rev, extra = rev, extra, None
386 cmd, rev, extra = rev, extra, None
387 if cmd == "good":
387 if cmd == "good":
388 good = True
388 good = True
389 elif cmd == "bad":
389 elif cmd == "bad":
390 bad = True
390 bad = True
391 else:
391 else:
392 reset = True
392 reset = True
393 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
393 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
394 raise util.Abort(_('incompatible arguments'))
394 raise util.Abort(_('incompatible arguments'))
395
395
396 if reset:
396 if reset:
397 p = repo.join("bisect.state")
397 p = repo.join("bisect.state")
398 if os.path.exists(p):
398 if os.path.exists(p):
399 os.unlink(p)
399 os.unlink(p)
400 return
400 return
401
401
402 state = hbisect.load_state(repo)
402 state = hbisect.load_state(repo)
403
403
404 if command:
404 if command:
405 changesets = 1
405 changesets = 1
406 try:
406 try:
407 while changesets:
407 while changesets:
408 # update state
408 # update state
409 status = util.system(command)
409 status = util.system(command)
410 if status == 125:
410 if status == 125:
411 transition = "skip"
411 transition = "skip"
412 elif status == 0:
412 elif status == 0:
413 transition = "good"
413 transition = "good"
414 # status < 0 means process was killed
414 # status < 0 means process was killed
415 elif status == 127:
415 elif status == 127:
416 raise util.Abort(_("failed to execute %s") % command)
416 raise util.Abort(_("failed to execute %s") % command)
417 elif status < 0:
417 elif status < 0:
418 raise util.Abort(_("%s killed") % command)
418 raise util.Abort(_("%s killed") % command)
419 else:
419 else:
420 transition = "bad"
420 transition = "bad"
421 ctx = cmdutil.revsingle(repo, rev)
421 ctx = cmdutil.revsingle(repo, rev)
422 rev = None # clear for future iterations
422 rev = None # clear for future iterations
423 state[transition].append(ctx.node())
423 state[transition].append(ctx.node())
424 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
424 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
425 check_state(state, interactive=False)
425 check_state(state, interactive=False)
426 # bisect
426 # bisect
427 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
427 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
428 # update to next check
428 # update to next check
429 cmdutil.bail_if_changed(repo)
429 cmdutil.bail_if_changed(repo)
430 hg.clean(repo, nodes[0], show_stats=False)
430 hg.clean(repo, nodes[0], show_stats=False)
431 finally:
431 finally:
432 hbisect.save_state(repo, state)
432 hbisect.save_state(repo, state)
433 print_result(nodes, good)
433 print_result(nodes, good)
434 return
434 return
435
435
436 # update state
436 # update state
437
437
438 if rev:
438 if rev:
439 nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
439 nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
440 else:
440 else:
441 nodes = [repo.lookup('.')]
441 nodes = [repo.lookup('.')]
442
442
443 if good or bad or skip:
443 if good or bad or skip:
444 if good:
444 if good:
445 state['good'] += nodes
445 state['good'] += nodes
446 elif bad:
446 elif bad:
447 state['bad'] += nodes
447 state['bad'] += nodes
448 elif skip:
448 elif skip:
449 state['skip'] += nodes
449 state['skip'] += nodes
450 hbisect.save_state(repo, state)
450 hbisect.save_state(repo, state)
451
451
452 if not check_state(state):
452 if not check_state(state):
453 return
453 return
454
454
455 # actually bisect
455 # actually bisect
456 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
456 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
457 if extend:
457 if extend:
458 if not changesets:
458 if not changesets:
459 extendnode = extendbisectrange(nodes, good)
459 extendnode = extendbisectrange(nodes, good)
460 if extendnode is not None:
460 if extendnode is not None:
461 ui.write(_("Extending search to changeset %d:%s\n"
461 ui.write(_("Extending search to changeset %d:%s\n"
462 % (extendnode.rev(), extendnode)))
462 % (extendnode.rev(), extendnode)))
463 if noupdate:
463 if noupdate:
464 return
464 return
465 cmdutil.bail_if_changed(repo)
465 cmdutil.bail_if_changed(repo)
466 return hg.clean(repo, extendnode.node())
466 return hg.clean(repo, extendnode.node())
467 raise util.Abort(_("nothing to extend"))
467 raise util.Abort(_("nothing to extend"))
468
468
469 if changesets == 0:
469 if changesets == 0:
470 print_result(nodes, good)
470 print_result(nodes, good)
471 else:
471 else:
472 assert len(nodes) == 1 # only a single node can be tested next
472 assert len(nodes) == 1 # only a single node can be tested next
473 node = nodes[0]
473 node = nodes[0]
474 # compute the approximate number of remaining tests
474 # compute the approximate number of remaining tests
475 tests, size = 0, 2
475 tests, size = 0, 2
476 while size <= changesets:
476 while size <= changesets:
477 tests, size = tests + 1, size * 2
477 tests, size = tests + 1, size * 2
478 rev = repo.changelog.rev(node)
478 rev = repo.changelog.rev(node)
479 ui.write(_("Testing changeset %d:%s "
479 ui.write(_("Testing changeset %d:%s "
480 "(%d changesets remaining, ~%d tests)\n")
480 "(%d changesets remaining, ~%d tests)\n")
481 % (rev, short(node), changesets, tests))
481 % (rev, short(node), changesets, tests))
482 if not noupdate:
482 if not noupdate:
483 cmdutil.bail_if_changed(repo)
483 cmdutil.bail_if_changed(repo)
484 return hg.clean(repo, node)
484 return hg.clean(repo, node)
485
485
486 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
486 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
487 rename=None, inactive=False):
487 rename=None, inactive=False):
488 '''track a line of development with movable markers
488 '''track a line of development with movable markers
489
489
490 Bookmarks are pointers to certain commits that move when
490 Bookmarks are pointers to certain commits that move when
491 committing. Bookmarks are local. They can be renamed, copied and
491 committing. Bookmarks are local. They can be renamed, copied and
492 deleted. It is possible to use bookmark names in :hg:`merge` and
492 deleted. It is possible to use bookmark names in :hg:`merge` and
493 :hg:`update` to merge and update respectively to a given bookmark.
493 :hg:`update` to merge and update respectively to a given bookmark.
494
494
495 You can use :hg:`bookmark NAME` to set a bookmark on the working
495 You can use :hg:`bookmark NAME` to set a bookmark on the working
496 directory's parent revision with the given name. If you specify
496 directory's parent revision with the given name. If you specify
497 a revision using -r REV (where REV may be an existing bookmark),
497 a revision using -r REV (where REV may be an existing bookmark),
498 the bookmark is assigned to that revision.
498 the bookmark is assigned to that revision.
499
499
500 Bookmarks can be pushed and pulled between repositories (see :hg:`help
500 Bookmarks can be pushed and pulled between repositories (see :hg:`help
501 push` and :hg:`help pull`). This requires both the local and remote
501 push` and :hg:`help pull`). This requires both the local and remote
502 repositories to support bookmarks. For versions prior to 1.8, this means
502 repositories to support bookmarks. For versions prior to 1.8, this means
503 the bookmarks extension must be enabled.
503 the bookmarks extension must be enabled.
504 '''
504 '''
505 hexfn = ui.debugflag and hex or short
505 hexfn = ui.debugflag and hex or short
506 marks = repo._bookmarks
506 marks = repo._bookmarks
507 cur = repo.changectx('.').node()
507 cur = repo.changectx('.').node()
508
508
509 if rename:
509 if rename:
510 if rename not in marks:
510 if rename not in marks:
511 raise util.Abort(_("bookmark '%s' does not exist") % rename)
511 raise util.Abort(_("bookmark '%s' does not exist") % rename)
512 if mark in marks and not force:
512 if mark in marks and not force:
513 raise util.Abort(_("bookmark '%s' already exists "
513 raise util.Abort(_("bookmark '%s' already exists "
514 "(use -f to force)") % mark)
514 "(use -f to force)") % mark)
515 if mark is None:
515 if mark is None:
516 raise util.Abort(_("new bookmark name required"))
516 raise util.Abort(_("new bookmark name required"))
517 marks[mark] = marks[rename]
517 marks[mark] = marks[rename]
518 if repo._bookmarkcurrent == rename and not inactive:
518 if repo._bookmarkcurrent == rename and not inactive:
519 bookmarks.setcurrent(repo, mark)
519 bookmarks.setcurrent(repo, mark)
520 del marks[rename]
520 del marks[rename]
521 bookmarks.write(repo)
521 bookmarks.write(repo)
522 return
522 return
523
523
524 if delete:
524 if delete:
525 if mark is None:
525 if mark is None:
526 raise util.Abort(_("bookmark name required"))
526 raise util.Abort(_("bookmark name required"))
527 if mark not in marks:
527 if mark not in marks:
528 raise util.Abort(_("bookmark '%s' does not exist") % mark)
528 raise util.Abort(_("bookmark '%s' does not exist") % mark)
529 if mark == repo._bookmarkcurrent:
529 if mark == repo._bookmarkcurrent:
530 bookmarks.setcurrent(repo, None)
530 bookmarks.setcurrent(repo, None)
531 del marks[mark]
531 del marks[mark]
532 bookmarks.write(repo)
532 bookmarks.write(repo)
533 return
533 return
534
534
535 if mark is not None:
535 if mark is not None:
536 if "\n" in mark:
536 if "\n" in mark:
537 raise util.Abort(_("bookmark name cannot contain newlines"))
537 raise util.Abort(_("bookmark name cannot contain newlines"))
538 mark = mark.strip()
538 mark = mark.strip()
539 if not mark:
539 if not mark:
540 raise util.Abort(_("bookmark names cannot consist entirely of "
540 raise util.Abort(_("bookmark names cannot consist entirely of "
541 "whitespace"))
541 "whitespace"))
542 if inactive and mark == repo._bookmarkcurrent:
542 if inactive and mark == repo._bookmarkcurrent:
543 bookmarks.setcurrent(repo, None)
543 bookmarks.setcurrent(repo, None)
544 return
544 return
545 if mark in marks and not force:
545 if mark in marks and not force:
546 raise util.Abort(_("bookmark '%s' already exists "
546 raise util.Abort(_("bookmark '%s' already exists "
547 "(use -f to force)") % mark)
547 "(use -f to force)") % mark)
548 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
548 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
549 and not force):
549 and not force):
550 raise util.Abort(
550 raise util.Abort(
551 _("a bookmark cannot have the name of an existing branch"))
551 _("a bookmark cannot have the name of an existing branch"))
552 if rev:
552 if rev:
553 marks[mark] = repo.lookup(rev)
553 marks[mark] = repo.lookup(rev)
554 else:
554 else:
555 marks[mark] = repo.changectx('.').node()
555 marks[mark] = repo.changectx('.').node()
556 if not inactive and repo.changectx('.').node() == marks[mark]:
556 if not inactive and repo.changectx('.').node() == marks[mark]:
557 bookmarks.setcurrent(repo, mark)
557 bookmarks.setcurrent(repo, mark)
558 bookmarks.write(repo)
558 bookmarks.write(repo)
559 return
559 return
560
560
561 if mark is None:
561 if mark is None:
562 if rev:
562 if rev:
563 raise util.Abort(_("bookmark name required"))
563 raise util.Abort(_("bookmark name required"))
564 if len(marks) == 0:
564 if len(marks) == 0:
565 ui.status(_("no bookmarks set\n"))
565 ui.status(_("no bookmarks set\n"))
566 else:
566 else:
567 for bmark, n in sorted(marks.iteritems()):
567 for bmark, n in sorted(marks.iteritems()):
568 current = repo._bookmarkcurrent
568 current = repo._bookmarkcurrent
569 if bmark == current and n == cur:
569 if bmark == current and n == cur:
570 prefix, label = '*', 'bookmarks.current'
570 prefix, label = '*', 'bookmarks.current'
571 else:
571 else:
572 prefix, label = ' ', ''
572 prefix, label = ' ', ''
573
573
574 if ui.quiet:
574 if ui.quiet:
575 ui.write("%s\n" % bmark, label=label)
575 ui.write("%s\n" % bmark, label=label)
576 else:
576 else:
577 ui.write(" %s %-25s %d:%s\n" % (
577 ui.write(" %s %-25s %d:%s\n" % (
578 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
578 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
579 label=label)
579 label=label)
580 return
580 return
581
581
582 def branch(ui, repo, label=None, **opts):
582 def branch(ui, repo, label=None, **opts):
583 """set or show the current branch name
583 """set or show the current branch name
584
584
585 With no argument, show the current branch name. With one argument,
585 With no argument, show the current branch name. With one argument,
586 set the working directory branch name (the branch will not exist
586 set the working directory branch name (the branch will not exist
587 in the repository until the next commit). Standard practice
587 in the repository until the next commit). Standard practice
588 recommends that primary development take place on the 'default'
588 recommends that primary development take place on the 'default'
589 branch.
589 branch.
590
590
591 Unless -f/--force is specified, branch will not let you set a
591 Unless -f/--force is specified, branch will not let you set a
592 branch name that already exists, even if it's inactive.
592 branch name that already exists, even if it's inactive.
593
593
594 Use -C/--clean to reset the working directory branch to that of
594 Use -C/--clean to reset the working directory branch to that of
595 the parent of the working directory, negating a previous branch
595 the parent of the working directory, negating a previous branch
596 change.
596 change.
597
597
598 Use the command :hg:`update` to switch to an existing branch. Use
598 Use the command :hg:`update` to switch to an existing branch. Use
599 :hg:`commit --close-branch` to mark this branch as closed.
599 :hg:`commit --close-branch` to mark this branch as closed.
600
600
601 Returns 0 on success.
601 Returns 0 on success.
602 """
602 """
603
603
604 if opts.get('clean'):
604 if opts.get('clean'):
605 label = repo[None].p1().branch()
605 label = repo[None].p1().branch()
606 repo.dirstate.setbranch(label)
606 repo.dirstate.setbranch(label)
607 ui.status(_('reset working directory to branch %s\n') % label)
607 ui.status(_('reset working directory to branch %s\n') % label)
608 elif label:
608 elif label:
609 if not opts.get('force') and label in repo.branchtags():
609 if not opts.get('force') and label in repo.branchtags():
610 if label not in [p.branch() for p in repo.parents()]:
610 if label not in [p.branch() for p in repo.parents()]:
611 raise util.Abort(_('a branch of the same name already exists'),
611 raise util.Abort(_('a branch of the same name already exists'),
612 # i18n: "it" refers to an existing branch
612 # i18n: "it" refers to an existing branch
613 hint=_("use 'hg update' to switch to it"))
613 hint=_("use 'hg update' to switch to it"))
614 repo.dirstate.setbranch(label)
614 repo.dirstate.setbranch(label)
615 ui.status(_('marked working directory as branch %s\n') % label)
615 ui.status(_('marked working directory as branch %s\n') % label)
616 else:
616 else:
617 ui.write("%s\n" % repo.dirstate.branch())
617 ui.write("%s\n" % repo.dirstate.branch())
618
618
619 def branches(ui, repo, active=False, closed=False):
619 def branches(ui, repo, active=False, closed=False):
620 """list repository named branches
620 """list repository named branches
621
621
622 List the repository's named branches, indicating which ones are
622 List the repository's named branches, indicating which ones are
623 inactive. If -c/--closed is specified, also list branches which have
623 inactive. If -c/--closed is specified, also list branches which have
624 been marked closed (see :hg:`commit --close-branch`).
624 been marked closed (see :hg:`commit --close-branch`).
625
625
626 If -a/--active is specified, only show active branches. A branch
626 If -a/--active is specified, only show active branches. A branch
627 is considered active if it contains repository heads.
627 is considered active if it contains repository heads.
628
628
629 Use the command :hg:`update` to switch to an existing branch.
629 Use the command :hg:`update` to switch to an existing branch.
630
630
631 Returns 0.
631 Returns 0.
632 """
632 """
633
633
634 hexfunc = ui.debugflag and hex or short
634 hexfunc = ui.debugflag and hex or short
635 activebranches = [repo[n].branch() for n in repo.heads()]
635 activebranches = [repo[n].branch() for n in repo.heads()]
636 def testactive(tag, node):
636 def testactive(tag, node):
637 realhead = tag in activebranches
637 realhead = tag in activebranches
638 open = node in repo.branchheads(tag, closed=False)
638 open = node in repo.branchheads(tag, closed=False)
639 return realhead and open
639 return realhead and open
640 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
640 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
641 for tag, node in repo.branchtags().items()],
641 for tag, node in repo.branchtags().items()],
642 reverse=True)
642 reverse=True)
643
643
644 for isactive, node, tag in branches:
644 for isactive, node, tag in branches:
645 if (not active) or isactive:
645 if (not active) or isactive:
646 if ui.quiet:
646 if ui.quiet:
647 ui.write("%s\n" % tag)
647 ui.write("%s\n" % tag)
648 else:
648 else:
649 hn = repo.lookup(node)
649 hn = repo.lookup(node)
650 if isactive:
650 if isactive:
651 label = 'branches.active'
651 label = 'branches.active'
652 notice = ''
652 notice = ''
653 elif hn not in repo.branchheads(tag, closed=False):
653 elif hn not in repo.branchheads(tag, closed=False):
654 if not closed:
654 if not closed:
655 continue
655 continue
656 label = 'branches.closed'
656 label = 'branches.closed'
657 notice = _(' (closed)')
657 notice = _(' (closed)')
658 else:
658 else:
659 label = 'branches.inactive'
659 label = 'branches.inactive'
660 notice = _(' (inactive)')
660 notice = _(' (inactive)')
661 if tag == repo.dirstate.branch():
661 if tag == repo.dirstate.branch():
662 label = 'branches.current'
662 label = 'branches.current'
663 rev = str(node).rjust(31 - encoding.colwidth(tag))
663 rev = str(node).rjust(31 - encoding.colwidth(tag))
664 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
664 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
665 tag = ui.label(tag, label)
665 tag = ui.label(tag, label)
666 ui.write("%s %s%s\n" % (tag, rev, notice))
666 ui.write("%s %s%s\n" % (tag, rev, notice))
667
667
668 def bundle(ui, repo, fname, dest=None, **opts):
668 def bundle(ui, repo, fname, dest=None, **opts):
669 """create a changegroup file
669 """create a changegroup file
670
670
671 Generate a compressed changegroup file collecting changesets not
671 Generate a compressed changegroup file collecting changesets not
672 known to be in another repository.
672 known to be in another repository.
673
673
674 If you omit the destination repository, then hg assumes the
674 If you omit the destination repository, then hg assumes the
675 destination will have all the nodes you specify with --base
675 destination will have all the nodes you specify with --base
676 parameters. To create a bundle containing all changesets, use
676 parameters. To create a bundle containing all changesets, use
677 -a/--all (or --base null).
677 -a/--all (or --base null).
678
678
679 You can change compression method with the -t/--type option.
679 You can change compression method with the -t/--type option.
680 The available compression methods are: none, bzip2, and
680 The available compression methods are: none, bzip2, and
681 gzip (by default, bundles are compressed using bzip2).
681 gzip (by default, bundles are compressed using bzip2).
682
682
683 The bundle file can then be transferred using conventional means
683 The bundle file can then be transferred using conventional means
684 and applied to another repository with the unbundle or pull
684 and applied to another repository with the unbundle or pull
685 command. This is useful when direct push and pull are not
685 command. This is useful when direct push and pull are not
686 available or when exporting an entire repository is undesirable.
686 available or when exporting an entire repository is undesirable.
687
687
688 Applying bundles preserves all changeset contents including
688 Applying bundles preserves all changeset contents including
689 permissions, copy/rename information, and revision history.
689 permissions, copy/rename information, and revision history.
690
690
691 Returns 0 on success, 1 if no changes found.
691 Returns 0 on success, 1 if no changes found.
692 """
692 """
693 revs = None
693 revs = None
694 if 'rev' in opts:
694 if 'rev' in opts:
695 revs = cmdutil.revrange(repo, opts['rev'])
695 revs = cmdutil.revrange(repo, opts['rev'])
696
696
697 if opts.get('all'):
697 if opts.get('all'):
698 base = ['null']
698 base = ['null']
699 else:
699 else:
700 base = cmdutil.revrange(repo, opts.get('base'))
700 base = cmdutil.revrange(repo, opts.get('base'))
701 if base:
701 if base:
702 if dest:
702 if dest:
703 raise util.Abort(_("--base is incompatible with specifying "
703 raise util.Abort(_("--base is incompatible with specifying "
704 "a destination"))
704 "a destination"))
705 common = [repo.lookup(rev) for rev in base]
705 common = [repo.lookup(rev) for rev in base]
706 heads = revs and map(repo.lookup, revs) or revs
706 heads = revs and map(repo.lookup, revs) or revs
707 else:
707 else:
708 dest = ui.expandpath(dest or 'default-push', dest or 'default')
708 dest = ui.expandpath(dest or 'default-push', dest or 'default')
709 dest, branches = hg.parseurl(dest, opts.get('branch'))
709 dest, branches = hg.parseurl(dest, opts.get('branch'))
710 other = hg.repository(hg.remoteui(repo, opts), dest)
710 other = hg.repository(hg.remoteui(repo, opts), dest)
711 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
711 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
712 heads = revs and map(repo.lookup, revs) or revs
712 heads = revs and map(repo.lookup, revs) or revs
713 common, outheads = discovery.findcommonoutgoing(repo, other,
713 common, outheads = discovery.findcommonoutgoing(repo, other,
714 onlyheads=heads,
714 onlyheads=heads,
715 force=opts.get('force'))
715 force=opts.get('force'))
716
716
717 cg = repo.getbundle('bundle', common=common, heads=heads)
717 cg = repo.getbundle('bundle', common=common, heads=heads)
718 if not cg:
718 if not cg:
719 ui.status(_("no changes found\n"))
719 ui.status(_("no changes found\n"))
720 return 1
720 return 1
721
721
722 bundletype = opts.get('type', 'bzip2').lower()
722 bundletype = opts.get('type', 'bzip2').lower()
723 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
723 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
724 bundletype = btypes.get(bundletype)
724 bundletype = btypes.get(bundletype)
725 if bundletype not in changegroup.bundletypes:
725 if bundletype not in changegroup.bundletypes:
726 raise util.Abort(_('unknown bundle type specified with --type'))
726 raise util.Abort(_('unknown bundle type specified with --type'))
727
727
728 changegroup.writebundle(cg, fname, bundletype)
728 changegroup.writebundle(cg, fname, bundletype)
729
729
730 def cat(ui, repo, file1, *pats, **opts):
730 def cat(ui, repo, file1, *pats, **opts):
731 """output the current or given revision of files
731 """output the current or given revision of files
732
732
733 Print the specified files as they were at the given revision. If
733 Print the specified files as they were at the given revision. If
734 no revision is given, the parent of the working directory is used,
734 no revision is given, the parent of the working directory is used,
735 or tip if no revision is checked out.
735 or tip if no revision is checked out.
736
736
737 Output may be to a file, in which case the name of the file is
737 Output may be to a file, in which case the name of the file is
738 given using a format string. The formatting rules are the same as
738 given using a format string. The formatting rules are the same as
739 for the export command, with the following additions:
739 for the export command, with the following additions:
740
740
741 :``%s``: basename of file being printed
741 :``%s``: basename of file being printed
742 :``%d``: dirname of file being printed, or '.' if in repository root
742 :``%d``: dirname of file being printed, or '.' if in repository root
743 :``%p``: root-relative path name of file being printed
743 :``%p``: root-relative path name of file being printed
744
744
745 Returns 0 on success.
745 Returns 0 on success.
746 """
746 """
747 ctx = cmdutil.revsingle(repo, opts.get('rev'))
747 ctx = cmdutil.revsingle(repo, opts.get('rev'))
748 err = 1
748 err = 1
749 m = cmdutil.match(repo, (file1,) + pats, opts)
749 m = cmdutil.match(repo, (file1,) + pats, opts)
750 for abs in ctx.walk(m):
750 for abs in ctx.walk(m):
751 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
751 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
752 data = ctx[abs].data()
752 data = ctx[abs].data()
753 if opts.get('decode'):
753 if opts.get('decode'):
754 data = repo.wwritedata(abs, data)
754 data = repo.wwritedata(abs, data)
755 fp.write(data)
755 fp.write(data)
756 fp.close()
756 fp.close()
757 err = 0
757 err = 0
758 return err
758 return err
759
759
760 def clone(ui, source, dest=None, **opts):
760 def clone(ui, source, dest=None, **opts):
761 """make a copy of an existing repository
761 """make a copy of an existing repository
762
762
763 Create a copy of an existing repository in a new directory.
763 Create a copy of an existing repository in a new directory.
764
764
765 If no destination directory name is specified, it defaults to the
765 If no destination directory name is specified, it defaults to the
766 basename of the source.
766 basename of the source.
767
767
768 The location of the source is added to the new repository's
768 The location of the source is added to the new repository's
769 ``.hg/hgrc`` file, as the default to be used for future pulls.
769 ``.hg/hgrc`` file, as the default to be used for future pulls.
770
770
771 See :hg:`help urls` for valid source format details.
771 See :hg:`help urls` for valid source format details.
772
772
773 It is possible to specify an ``ssh://`` URL as the destination, but no
773 It is possible to specify an ``ssh://`` URL as the destination, but no
774 ``.hg/hgrc`` and working directory will be created on the remote side.
774 ``.hg/hgrc`` and working directory will be created on the remote side.
775 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
775 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
776
776
777 A set of changesets (tags, or branch names) to pull may be specified
777 A set of changesets (tags, or branch names) to pull may be specified
778 by listing each changeset (tag, or branch name) with -r/--rev.
778 by listing each changeset (tag, or branch name) with -r/--rev.
779 If -r/--rev is used, the cloned repository will contain only a subset
779 If -r/--rev is used, the cloned repository will contain only a subset
780 of the changesets of the source repository. Only the set of changesets
780 of the changesets of the source repository. Only the set of changesets
781 defined by all -r/--rev options (including all their ancestors)
781 defined by all -r/--rev options (including all their ancestors)
782 will be pulled into the destination repository.
782 will be pulled into the destination repository.
783 No subsequent changesets (including subsequent tags) will be present
783 No subsequent changesets (including subsequent tags) will be present
784 in the destination.
784 in the destination.
785
785
786 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
786 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
787 local source repositories.
787 local source repositories.
788
788
789 For efficiency, hardlinks are used for cloning whenever the source
789 For efficiency, hardlinks are used for cloning whenever the source
790 and destination are on the same filesystem (note this applies only
790 and destination are on the same filesystem (note this applies only
791 to the repository data, not to the working directory). Some
791 to the repository data, not to the working directory). Some
792 filesystems, such as AFS, implement hardlinking incorrectly, but
792 filesystems, such as AFS, implement hardlinking incorrectly, but
793 do not report errors. In these cases, use the --pull option to
793 do not report errors. In these cases, use the --pull option to
794 avoid hardlinking.
794 avoid hardlinking.
795
795
796 In some cases, you can clone repositories and the working directory
796 In some cases, you can clone repositories and the working directory
797 using full hardlinks with ::
797 using full hardlinks with ::
798
798
799 $ cp -al REPO REPOCLONE
799 $ cp -al REPO REPOCLONE
800
800
801 This is the fastest way to clone, but it is not always safe. The
801 This is the fastest way to clone, but it is not always safe. The
802 operation is not atomic (making sure REPO is not modified during
802 operation is not atomic (making sure REPO is not modified during
803 the operation is up to you) and you have to make sure your editor
803 the operation is up to you) and you have to make sure your editor
804 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
804 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
805 this is not compatible with certain extensions that place their
805 this is not compatible with certain extensions that place their
806 metadata under the .hg directory, such as mq.
806 metadata under the .hg directory, such as mq.
807
807
808 Mercurial will update the working directory to the first applicable
808 Mercurial will update the working directory to the first applicable
809 revision from this list:
809 revision from this list:
810
810
811 a) null if -U or the source repository has no changesets
811 a) null if -U or the source repository has no changesets
812 b) if -u . and the source repository is local, the first parent of
812 b) if -u . and the source repository is local, the first parent of
813 the source repository's working directory
813 the source repository's working directory
814 c) the changeset specified with -u (if a branch name, this means the
814 c) the changeset specified with -u (if a branch name, this means the
815 latest head of that branch)
815 latest head of that branch)
816 d) the changeset specified with -r
816 d) the changeset specified with -r
817 e) the tipmost head specified with -b
817 e) the tipmost head specified with -b
818 f) the tipmost head specified with the url#branch source syntax
818 f) the tipmost head specified with the url#branch source syntax
819 g) the tipmost head of the default branch
819 g) the tipmost head of the default branch
820 h) tip
820 h) tip
821
821
822 Returns 0 on success.
822 Returns 0 on success.
823 """
823 """
824 if opts.get('noupdate') and opts.get('updaterev'):
824 if opts.get('noupdate') and opts.get('updaterev'):
825 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
825 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
826
826
827 r = hg.clone(hg.remoteui(ui, opts), source, dest,
827 r = hg.clone(hg.remoteui(ui, opts), source, dest,
828 pull=opts.get('pull'),
828 pull=opts.get('pull'),
829 stream=opts.get('uncompressed'),
829 stream=opts.get('uncompressed'),
830 rev=opts.get('rev'),
830 rev=opts.get('rev'),
831 update=opts.get('updaterev') or not opts.get('noupdate'),
831 update=opts.get('updaterev') or not opts.get('noupdate'),
832 branch=opts.get('branch'))
832 branch=opts.get('branch'))
833
833
834 return r is None
834 return r is None
835
835
836 def commit(ui, repo, *pats, **opts):
836 def commit(ui, repo, *pats, **opts):
837 """commit the specified files or all outstanding changes
837 """commit the specified files or all outstanding changes
838
838
839 Commit changes to the given files into the repository. Unlike a
839 Commit changes to the given files into the repository. Unlike a
840 centralized SCM, this operation is a local operation. See
840 centralized SCM, this operation is a local operation. See
841 :hg:`push` for a way to actively distribute your changes.
841 :hg:`push` for a way to actively distribute your changes.
842
842
843 If a list of files is omitted, all changes reported by :hg:`status`
843 If a list of files is omitted, all changes reported by :hg:`status`
844 will be committed.
844 will be committed.
845
845
846 If you are committing the result of a merge, do not provide any
846 If you are committing the result of a merge, do not provide any
847 filenames or -I/-X filters.
847 filenames or -I/-X filters.
848
848
849 If no commit message is specified, Mercurial starts your
849 If no commit message is specified, Mercurial starts your
850 configured editor where you can enter a message. In case your
850 configured editor where you can enter a message. In case your
851 commit fails, you will find a backup of your message in
851 commit fails, you will find a backup of your message in
852 ``.hg/last-message.txt``.
852 ``.hg/last-message.txt``.
853
853
854 See :hg:`help dates` for a list of formats valid for -d/--date.
854 See :hg:`help dates` for a list of formats valid for -d/--date.
855
855
856 Returns 0 on success, 1 if nothing changed.
856 Returns 0 on success, 1 if nothing changed.
857 """
857 """
858 extra = {}
858 extra = {}
859 if opts.get('close_branch'):
859 if opts.get('close_branch'):
860 if repo['.'].node() not in repo.branchheads():
860 if repo['.'].node() not in repo.branchheads():
861 # The topo heads set is included in the branch heads set of the
861 # The topo heads set is included in the branch heads set of the
862 # current branch, so it's sufficient to test branchheads
862 # current branch, so it's sufficient to test branchheads
863 raise util.Abort(_('can only close branch heads'))
863 raise util.Abort(_('can only close branch heads'))
864 extra['close'] = 1
864 extra['close'] = 1
865 e = cmdutil.commiteditor
865 e = cmdutil.commiteditor
866 if opts.get('force_editor'):
866 if opts.get('force_editor'):
867 e = cmdutil.commitforceeditor
867 e = cmdutil.commitforceeditor
868
868
869 def commitfunc(ui, repo, message, match, opts):
869 def commitfunc(ui, repo, message, match, opts):
870 return repo.commit(message, opts.get('user'), opts.get('date'), match,
870 return repo.commit(message, opts.get('user'), opts.get('date'), match,
871 editor=e, extra=extra)
871 editor=e, extra=extra)
872
872
873 branch = repo[None].branch()
873 branch = repo[None].branch()
874 bheads = repo.branchheads(branch)
874 bheads = repo.branchheads(branch)
875
875
876 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
876 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
877 if not node:
877 if not node:
878 stat = repo.status(match=cmdutil.match(repo, pats, opts))
878 stat = repo.status(match=cmdutil.match(repo, pats, opts))
879 if stat[3]:
879 if stat[3]:
880 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
880 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
881 % len(stat[3]))
881 % len(stat[3]))
882 else:
882 else:
883 ui.status(_("nothing changed\n"))
883 ui.status(_("nothing changed\n"))
884 return 1
884 return 1
885
885
886 ctx = repo[node]
886 ctx = repo[node]
887 parents = ctx.parents()
887 parents = ctx.parents()
888
888
889 if bheads and not [x for x in parents
889 if bheads and not [x for x in parents
890 if x.node() in bheads and x.branch() == branch]:
890 if x.node() in bheads and x.branch() == branch]:
891 ui.status(_('created new head\n'))
891 ui.status(_('created new head\n'))
892 # The message is not printed for initial roots. For the other
892 # The message is not printed for initial roots. For the other
893 # changesets, it is printed in the following situations:
893 # changesets, it is printed in the following situations:
894 #
894 #
895 # Par column: for the 2 parents with ...
895 # Par column: for the 2 parents with ...
896 # N: null or no parent
896 # N: null or no parent
897 # B: parent is on another named branch
897 # B: parent is on another named branch
898 # C: parent is a regular non head changeset
898 # C: parent is a regular non head changeset
899 # H: parent was a branch head of the current branch
899 # H: parent was a branch head of the current branch
900 # Msg column: whether we print "created new head" message
900 # Msg column: whether we print "created new head" message
901 # In the following, it is assumed that there already exists some
901 # In the following, it is assumed that there already exists some
902 # initial branch heads of the current branch, otherwise nothing is
902 # initial branch heads of the current branch, otherwise nothing is
903 # printed anyway.
903 # printed anyway.
904 #
904 #
905 # Par Msg Comment
905 # Par Msg Comment
906 # NN y additional topo root
906 # NN y additional topo root
907 #
907 #
908 # BN y additional branch root
908 # BN y additional branch root
909 # CN y additional topo head
909 # CN y additional topo head
910 # HN n usual case
910 # HN n usual case
911 #
911 #
912 # BB y weird additional branch root
912 # BB y weird additional branch root
913 # CB y branch merge
913 # CB y branch merge
914 # HB n merge with named branch
914 # HB n merge with named branch
915 #
915 #
916 # CC y additional head from merge
916 # CC y additional head from merge
917 # CH n merge with a head
917 # CH n merge with a head
918 #
918 #
919 # HH n head merge: head count decreases
919 # HH n head merge: head count decreases
920
920
921 if not opts.get('close_branch'):
921 if not opts.get('close_branch'):
922 for r in parents:
922 for r in parents:
923 if r.extra().get('close') and r.branch() == branch:
923 if r.extra().get('close') and r.branch() == branch:
924 ui.status(_('reopening closed branch head %d\n') % r)
924 ui.status(_('reopening closed branch head %d\n') % r)
925
925
926 if ui.debugflag:
926 if ui.debugflag:
927 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
927 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
928 elif ui.verbose:
928 elif ui.verbose:
929 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
929 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
930
930
931 def copy(ui, repo, *pats, **opts):
931 def copy(ui, repo, *pats, **opts):
932 """mark files as copied for the next commit
932 """mark files as copied for the next commit
933
933
934 Mark dest as having copies of source files. If dest is a
934 Mark dest as having copies of source files. If dest is a
935 directory, copies are put in that directory. If dest is a file,
935 directory, copies are put in that directory. If dest is a file,
936 the source must be a single file.
936 the source must be a single file.
937
937
938 By default, this command copies the contents of files as they
938 By default, this command copies the contents of files as they
939 exist in the working directory. If invoked with -A/--after, the
939 exist in the working directory. If invoked with -A/--after, the
940 operation is recorded, but no copying is performed.
940 operation is recorded, but no copying is performed.
941
941
942 This command takes effect with the next commit. To undo a copy
942 This command takes effect with the next commit. To undo a copy
943 before that, see :hg:`revert`.
943 before that, see :hg:`revert`.
944
944
945 Returns 0 on success, 1 if errors are encountered.
945 Returns 0 on success, 1 if errors are encountered.
946 """
946 """
947 wlock = repo.wlock(False)
947 wlock = repo.wlock(False)
948 try:
948 try:
949 return cmdutil.copy(ui, repo, pats, opts)
949 return cmdutil.copy(ui, repo, pats, opts)
950 finally:
950 finally:
951 wlock.release()
951 wlock.release()
952
952
953 def debugancestor(ui, repo, *args):
953 def debugancestor(ui, repo, *args):
954 """find the ancestor revision of two revisions in a given index"""
954 """find the ancestor revision of two revisions in a given index"""
955 if len(args) == 3:
955 if len(args) == 3:
956 index, rev1, rev2 = args
956 index, rev1, rev2 = args
957 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
957 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
958 lookup = r.lookup
958 lookup = r.lookup
959 elif len(args) == 2:
959 elif len(args) == 2:
960 if not repo:
960 if not repo:
961 raise util.Abort(_("there is no Mercurial repository here "
961 raise util.Abort(_("there is no Mercurial repository here "
962 "(.hg not found)"))
962 "(.hg not found)"))
963 rev1, rev2 = args
963 rev1, rev2 = args
964 r = repo.changelog
964 r = repo.changelog
965 lookup = repo.lookup
965 lookup = repo.lookup
966 else:
966 else:
967 raise util.Abort(_('either two or three arguments required'))
967 raise util.Abort(_('either two or three arguments required'))
968 a = r.ancestor(lookup(rev1), lookup(rev2))
968 a = r.ancestor(lookup(rev1), lookup(rev2))
969 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
969 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
970
970
971 def debugbuilddag(ui, repo, text=None,
971 def debugbuilddag(ui, repo, text=None,
972 mergeable_file=False,
972 mergeable_file=False,
973 overwritten_file=False,
973 overwritten_file=False,
974 new_file=False):
974 new_file=False):
975 """builds a repo with a given DAG from scratch in the current empty repo
975 """builds a repo with a given DAG from scratch in the current empty repo
976
976
977 The description of the DAG is read from stdin if not given on the
977 The description of the DAG is read from stdin if not given on the
978 command line.
978 command line.
979
979
980 Elements:
980 Elements:
981
981
982 - "+n" is a linear run of n nodes based on the current default parent
982 - "+n" is a linear run of n nodes based on the current default parent
983 - "." is a single node based on the current default parent
983 - "." is a single node based on the current default parent
984 - "$" resets the default parent to null (implied at the start);
984 - "$" resets the default parent to null (implied at the start);
985 otherwise the default parent is always the last node created
985 otherwise the default parent is always the last node created
986 - "<p" sets the default parent to the backref p
986 - "<p" sets the default parent to the backref p
987 - "*p" is a fork at parent p, which is a backref
987 - "*p" is a fork at parent p, which is a backref
988 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
988 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
989 - "/p2" is a merge of the preceding node and p2
989 - "/p2" is a merge of the preceding node and p2
990 - ":tag" defines a local tag for the preceding node
990 - ":tag" defines a local tag for the preceding node
991 - "@branch" sets the named branch for subsequent nodes
991 - "@branch" sets the named branch for subsequent nodes
992 - "#...\\n" is a comment up to the end of the line
992 - "#...\\n" is a comment up to the end of the line
993
993
994 Whitespace between the above elements is ignored.
994 Whitespace between the above elements is ignored.
995
995
996 A backref is either
996 A backref is either
997
997
998 - a number n, which references the node curr-n, where curr is the current
998 - a number n, which references the node curr-n, where curr is the current
999 node, or
999 node, or
1000 - the name of a local tag you placed earlier using ":tag", or
1000 - the name of a local tag you placed earlier using ":tag", or
1001 - empty to denote the default parent.
1001 - empty to denote the default parent.
1002
1002
1003 All string valued-elements are either strictly alphanumeric, or must
1003 All string valued-elements are either strictly alphanumeric, or must
1004 be enclosed in double quotes ("..."), with "\\" as escape character.
1004 be enclosed in double quotes ("..."), with "\\" as escape character.
1005 """
1005 """
1006
1006
1007 if text is None:
1007 if text is None:
1008 ui.status(_("reading DAG from stdin\n"))
1008 ui.status(_("reading DAG from stdin\n"))
1009 text = sys.stdin.read()
1009 text = sys.stdin.read()
1010
1010
1011 cl = repo.changelog
1011 cl = repo.changelog
1012 if len(cl) > 0:
1012 if len(cl) > 0:
1013 raise util.Abort(_('repository is not empty'))
1013 raise util.Abort(_('repository is not empty'))
1014
1014
1015 # determine number of revs in DAG
1015 # determine number of revs in DAG
1016 total = 0
1016 total = 0
1017 for type, data in dagparser.parsedag(text):
1017 for type, data in dagparser.parsedag(text):
1018 if type == 'n':
1018 if type == 'n':
1019 total += 1
1019 total += 1
1020
1020
1021 if mergeable_file:
1021 if mergeable_file:
1022 linesperrev = 2
1022 linesperrev = 2
1023 # make a file with k lines per rev
1023 # make a file with k lines per rev
1024 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1024 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1025 initialmergedlines.append("")
1025 initialmergedlines.append("")
1026
1026
1027 tags = []
1027 tags = []
1028
1028
1029 tr = repo.transaction("builddag")
1029 tr = repo.transaction("builddag")
1030 try:
1030 try:
1031
1031
1032 at = -1
1032 at = -1
1033 atbranch = 'default'
1033 atbranch = 'default'
1034 nodeids = []
1034 nodeids = []
1035 ui.progress(_('building'), 0, unit=_('revisions'), total=total)
1035 ui.progress(_('building'), 0, unit=_('revisions'), total=total)
1036 for type, data in dagparser.parsedag(text):
1036 for type, data in dagparser.parsedag(text):
1037 if type == 'n':
1037 if type == 'n':
1038 ui.note('node %s\n' % str(data))
1038 ui.note('node %s\n' % str(data))
1039 id, ps = data
1039 id, ps = data
1040
1040
1041 files = []
1041 files = []
1042 fctxs = {}
1042 fctxs = {}
1043
1043
1044 p2 = None
1044 p2 = None
1045 if mergeable_file:
1045 if mergeable_file:
1046 fn = "mf"
1046 fn = "mf"
1047 p1 = repo[ps[0]]
1047 p1 = repo[ps[0]]
1048 if len(ps) > 1:
1048 if len(ps) > 1:
1049 p2 = repo[ps[1]]
1049 p2 = repo[ps[1]]
1050 pa = p1.ancestor(p2)
1050 pa = p1.ancestor(p2)
1051 base, local, other = [x[fn].data() for x in pa, p1, p2]
1051 base, local, other = [x[fn].data() for x in pa, p1, p2]
1052 m3 = simplemerge.Merge3Text(base, local, other)
1052 m3 = simplemerge.Merge3Text(base, local, other)
1053 ml = [l.strip() for l in m3.merge_lines()]
1053 ml = [l.strip() for l in m3.merge_lines()]
1054 ml.append("")
1054 ml.append("")
1055 elif at > 0:
1055 elif at > 0:
1056 ml = p1[fn].data().split("\n")
1056 ml = p1[fn].data().split("\n")
1057 else:
1057 else:
1058 ml = initialmergedlines
1058 ml = initialmergedlines
1059 ml[id * linesperrev] += " r%i" % id
1059 ml[id * linesperrev] += " r%i" % id
1060 mergedtext = "\n".join(ml)
1060 mergedtext = "\n".join(ml)
1061 files.append(fn)
1061 files.append(fn)
1062 fctxs[fn] = context.memfilectx(fn, mergedtext)
1062 fctxs[fn] = context.memfilectx(fn, mergedtext)
1063
1063
1064 if overwritten_file:
1064 if overwritten_file:
1065 fn = "of"
1065 fn = "of"
1066 files.append(fn)
1066 files.append(fn)
1067 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1067 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1068
1068
1069 if new_file:
1069 if new_file:
1070 fn = "nf%i" % id
1070 fn = "nf%i" % id
1071 files.append(fn)
1071 files.append(fn)
1072 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1072 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1073 if len(ps) > 1:
1073 if len(ps) > 1:
1074 if not p2:
1074 if not p2:
1075 p2 = repo[ps[1]]
1075 p2 = repo[ps[1]]
1076 for fn in p2:
1076 for fn in p2:
1077 if fn.startswith("nf"):
1077 if fn.startswith("nf"):
1078 files.append(fn)
1078 files.append(fn)
1079 fctxs[fn] = p2[fn]
1079 fctxs[fn] = p2[fn]
1080
1080
1081 def fctxfn(repo, cx, path):
1081 def fctxfn(repo, cx, path):
1082 return fctxs.get(path)
1082 return fctxs.get(path)
1083
1083
1084 if len(ps) == 0 or ps[0] < 0:
1084 if len(ps) == 0 or ps[0] < 0:
1085 pars = [None, None]
1085 pars = [None, None]
1086 elif len(ps) == 1:
1086 elif len(ps) == 1:
1087 pars = [nodeids[ps[0]], None]
1087 pars = [nodeids[ps[0]], None]
1088 else:
1088 else:
1089 pars = [nodeids[p] for p in ps]
1089 pars = [nodeids[p] for p in ps]
1090 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1090 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1091 date=(id, 0),
1091 date=(id, 0),
1092 user="debugbuilddag",
1092 user="debugbuilddag",
1093 extra={'branch': atbranch})
1093 extra={'branch': atbranch})
1094 nodeid = repo.commitctx(cx)
1094 nodeid = repo.commitctx(cx)
1095 nodeids.append(nodeid)
1095 nodeids.append(nodeid)
1096 at = id
1096 at = id
1097 elif type == 'l':
1097 elif type == 'l':
1098 id, name = data
1098 id, name = data
1099 ui.note('tag %s\n' % name)
1099 ui.note('tag %s\n' % name)
1100 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1100 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1101 elif type == 'a':
1101 elif type == 'a':
1102 ui.note('branch %s\n' % data)
1102 ui.note('branch %s\n' % data)
1103 atbranch = data
1103 atbranch = data
1104 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1104 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1105 tr.close()
1105 tr.close()
1106 finally:
1106 finally:
1107 ui.progress(_('building'), None)
1107 ui.progress(_('building'), None)
1108 tr.release()
1108 tr.release()
1109
1109
1110 if tags:
1110 if tags:
1111 repo.opener.write("localtags", "".join(tags))
1111 repo.opener.write("localtags", "".join(tags))
1112
1112
1113 def debugcommands(ui, cmd='', *args):
1113 def debugcommands(ui, cmd='', *args):
1114 """list all available commands and options"""
1114 """list all available commands and options"""
1115 for cmd, vals in sorted(table.iteritems()):
1115 for cmd, vals in sorted(table.iteritems()):
1116 cmd = cmd.split('|')[0].strip('^')
1116 cmd = cmd.split('|')[0].strip('^')
1117 opts = ', '.join([i[1] for i in vals[1]])
1117 opts = ', '.join([i[1] for i in vals[1]])
1118 ui.write('%s: %s\n' % (cmd, opts))
1118 ui.write('%s: %s\n' % (cmd, opts))
1119
1119
1120 def debugcomplete(ui, cmd='', **opts):
1120 def debugcomplete(ui, cmd='', **opts):
1121 """returns the completion list associated with the given command"""
1121 """returns the completion list associated with the given command"""
1122
1122
1123 if opts.get('options'):
1123 if opts.get('options'):
1124 options = []
1124 options = []
1125 otables = [globalopts]
1125 otables = [globalopts]
1126 if cmd:
1126 if cmd:
1127 aliases, entry = cmdutil.findcmd(cmd, table, False)
1127 aliases, entry = cmdutil.findcmd(cmd, table, False)
1128 otables.append(entry[1])
1128 otables.append(entry[1])
1129 for t in otables:
1129 for t in otables:
1130 for o in t:
1130 for o in t:
1131 if "(DEPRECATED)" in o[3]:
1131 if "(DEPRECATED)" in o[3]:
1132 continue
1132 continue
1133 if o[0]:
1133 if o[0]:
1134 options.append('-%s' % o[0])
1134 options.append('-%s' % o[0])
1135 options.append('--%s' % o[1])
1135 options.append('--%s' % o[1])
1136 ui.write("%s\n" % "\n".join(options))
1136 ui.write("%s\n" % "\n".join(options))
1137 return
1137 return
1138
1138
1139 cmdlist = cmdutil.findpossible(cmd, table)
1139 cmdlist = cmdutil.findpossible(cmd, table)
1140 if ui.verbose:
1140 if ui.verbose:
1141 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1141 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1142 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1142 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1143
1143
1144 def debugfsinfo(ui, path = "."):
1144 def debugfsinfo(ui, path = "."):
1145 """show information detected about current filesystem"""
1145 """show information detected about current filesystem"""
1146 util.writefile('.debugfsinfo', '')
1146 util.writefile('.debugfsinfo', '')
1147 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1147 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1148 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1148 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1149 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1149 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1150 and 'yes' or 'no'))
1150 and 'yes' or 'no'))
1151 os.unlink('.debugfsinfo')
1151 os.unlink('.debugfsinfo')
1152
1152
1153 def debugrebuildstate(ui, repo, rev="tip"):
1153 def debugrebuildstate(ui, repo, rev="tip"):
1154 """rebuild the dirstate as it would look like for the given revision"""
1154 """rebuild the dirstate as it would look like for the given revision"""
1155 ctx = cmdutil.revsingle(repo, rev)
1155 ctx = cmdutil.revsingle(repo, rev)
1156 wlock = repo.wlock()
1156 wlock = repo.wlock()
1157 try:
1157 try:
1158 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1158 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1159 finally:
1159 finally:
1160 wlock.release()
1160 wlock.release()
1161
1161
1162 def debugcheckstate(ui, repo):
1162 def debugcheckstate(ui, repo):
1163 """validate the correctness of the current dirstate"""
1163 """validate the correctness of the current dirstate"""
1164 parent1, parent2 = repo.dirstate.parents()
1164 parent1, parent2 = repo.dirstate.parents()
1165 m1 = repo[parent1].manifest()
1165 m1 = repo[parent1].manifest()
1166 m2 = repo[parent2].manifest()
1166 m2 = repo[parent2].manifest()
1167 errors = 0
1167 errors = 0
1168 for f in repo.dirstate:
1168 for f in repo.dirstate:
1169 state = repo.dirstate[f]
1169 state = repo.dirstate[f]
1170 if state in "nr" and f not in m1:
1170 if state in "nr" and f not in m1:
1171 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1171 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1172 errors += 1
1172 errors += 1
1173 if state in "a" and f in m1:
1173 if state in "a" and f in m1:
1174 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1174 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1175 errors += 1
1175 errors += 1
1176 if state in "m" and f not in m1 and f not in m2:
1176 if state in "m" and f not in m1 and f not in m2:
1177 ui.warn(_("%s in state %s, but not in either manifest\n") %
1177 ui.warn(_("%s in state %s, but not in either manifest\n") %
1178 (f, state))
1178 (f, state))
1179 errors += 1
1179 errors += 1
1180 for f in m1:
1180 for f in m1:
1181 state = repo.dirstate[f]
1181 state = repo.dirstate[f]
1182 if state not in "nrm":
1182 if state not in "nrm":
1183 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1183 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1184 errors += 1
1184 errors += 1
1185 if errors:
1185 if errors:
1186 error = _(".hg/dirstate inconsistent with current parent's manifest")
1186 error = _(".hg/dirstate inconsistent with current parent's manifest")
1187 raise util.Abort(error)
1187 raise util.Abort(error)
1188
1188
1189 def showconfig(ui, repo, *values, **opts):
1189 def showconfig(ui, repo, *values, **opts):
1190 """show combined config settings from all hgrc files
1190 """show combined config settings from all hgrc files
1191
1191
1192 With no arguments, print names and values of all config items.
1192 With no arguments, print names and values of all config items.
1193
1193
1194 With one argument of the form section.name, print just the value
1194 With one argument of the form section.name, print just the value
1195 of that config item.
1195 of that config item.
1196
1196
1197 With multiple arguments, print names and values of all config
1197 With multiple arguments, print names and values of all config
1198 items with matching section names.
1198 items with matching section names.
1199
1199
1200 With --debug, the source (filename and line number) is printed
1200 With --debug, the source (filename and line number) is printed
1201 for each config item.
1201 for each config item.
1202
1202
1203 Returns 0 on success.
1203 Returns 0 on success.
1204 """
1204 """
1205
1205
1206 for f in scmutil.rcpath():
1206 for f in scmutil.rcpath():
1207 ui.debug(_('read config from: %s\n') % f)
1207 ui.debug(_('read config from: %s\n') % f)
1208 untrusted = bool(opts.get('untrusted'))
1208 untrusted = bool(opts.get('untrusted'))
1209 if values:
1209 if values:
1210 sections = [v for v in values if '.' not in v]
1210 sections = [v for v in values if '.' not in v]
1211 items = [v for v in values if '.' in v]
1211 items = [v for v in values if '.' in v]
1212 if len(items) > 1 or items and sections:
1212 if len(items) > 1 or items and sections:
1213 raise util.Abort(_('only one config item permitted'))
1213 raise util.Abort(_('only one config item permitted'))
1214 for section, name, value in ui.walkconfig(untrusted=untrusted):
1214 for section, name, value in ui.walkconfig(untrusted=untrusted):
1215 value = str(value).replace('\n', '\\n')
1215 value = str(value).replace('\n', '\\n')
1216 sectname = section + '.' + name
1216 sectname = section + '.' + name
1217 if values:
1217 if values:
1218 for v in values:
1218 for v in values:
1219 if v == section:
1219 if v == section:
1220 ui.debug('%s: ' %
1220 ui.debug('%s: ' %
1221 ui.configsource(section, name, untrusted))
1221 ui.configsource(section, name, untrusted))
1222 ui.write('%s=%s\n' % (sectname, value))
1222 ui.write('%s=%s\n' % (sectname, value))
1223 elif v == sectname:
1223 elif v == sectname:
1224 ui.debug('%s: ' %
1224 ui.debug('%s: ' %
1225 ui.configsource(section, name, untrusted))
1225 ui.configsource(section, name, untrusted))
1226 ui.write(value, '\n')
1226 ui.write(value, '\n')
1227 else:
1227 else:
1228 ui.debug('%s: ' %
1228 ui.debug('%s: ' %
1229 ui.configsource(section, name, untrusted))
1229 ui.configsource(section, name, untrusted))
1230 ui.write('%s=%s\n' % (sectname, value))
1230 ui.write('%s=%s\n' % (sectname, value))
1231
1231
1232 def debugknown(ui, repopath, *ids, **opts):
1232 def debugknown(ui, repopath, *ids, **opts):
1233 """test whether node ids are known to a repo
1233 """test whether node ids are known to a repo
1234
1234
1235 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1235 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1236 indicating unknown/known.
1236 indicating unknown/known.
1237 """
1237 """
1238 repo = hg.repository(ui, repopath)
1238 repo = hg.repository(ui, repopath)
1239 if not repo.capable('known'):
1239 if not repo.capable('known'):
1240 raise util.Abort("known() not supported by target repository")
1240 raise util.Abort("known() not supported by target repository")
1241 flags = repo.known([bin(s) for s in ids])
1241 flags = repo.known([bin(s) for s in ids])
1242 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1242 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1243
1243
1244 def debugbundle(ui, bundlepath, all=None, **opts):
1244 def debugbundle(ui, bundlepath, all=None, **opts):
1245 """lists the contents of a bundle"""
1245 """lists the contents of a bundle"""
1246 f = url.open(ui, bundlepath)
1246 f = url.open(ui, bundlepath)
1247 try:
1247 try:
1248 gen = changegroup.readbundle(f, bundlepath)
1248 gen = changegroup.readbundle(f, bundlepath)
1249 if all:
1249 if all:
1250 ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
1250 ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
1251
1251
1252 def showchunks(named):
1252 def showchunks(named):
1253 ui.write("\n%s\n" % named)
1253 ui.write("\n%s\n" % named)
1254 chain = None
1254 chain = None
1255 while 1:
1255 while 1:
1256 chunkdata = gen.deltachunk(chain)
1256 chunkdata = gen.deltachunk(chain)
1257 if not chunkdata:
1257 if not chunkdata:
1258 break
1258 break
1259 node = chunkdata['node']
1259 node = chunkdata['node']
1260 p1 = chunkdata['p1']
1260 p1 = chunkdata['p1']
1261 p2 = chunkdata['p2']
1261 p2 = chunkdata['p2']
1262 cs = chunkdata['cs']
1262 cs = chunkdata['cs']
1263 deltabase = chunkdata['deltabase']
1263 deltabase = chunkdata['deltabase']
1264 delta = chunkdata['delta']
1264 delta = chunkdata['delta']
1265 ui.write("%s %s %s %s %s %s\n" %
1265 ui.write("%s %s %s %s %s %s\n" %
1266 (hex(node), hex(p1), hex(p2),
1266 (hex(node), hex(p1), hex(p2),
1267 hex(cs), hex(deltabase), len(delta)))
1267 hex(cs), hex(deltabase), len(delta)))
1268 chain = node
1268 chain = node
1269
1269
1270 chunkdata = gen.changelogheader()
1270 chunkdata = gen.changelogheader()
1271 showchunks("changelog")
1271 showchunks("changelog")
1272 chunkdata = gen.manifestheader()
1272 chunkdata = gen.manifestheader()
1273 showchunks("manifest")
1273 showchunks("manifest")
1274 while 1:
1274 while 1:
1275 chunkdata = gen.filelogheader()
1275 chunkdata = gen.filelogheader()
1276 if not chunkdata:
1276 if not chunkdata:
1277 break
1277 break
1278 fname = chunkdata['filename']
1278 fname = chunkdata['filename']
1279 showchunks(fname)
1279 showchunks(fname)
1280 else:
1280 else:
1281 chunkdata = gen.changelogheader()
1281 chunkdata = gen.changelogheader()
1282 chain = None
1282 chain = None
1283 while 1:
1283 while 1:
1284 chunkdata = gen.deltachunk(chain)
1284 chunkdata = gen.deltachunk(chain)
1285 if not chunkdata:
1285 if not chunkdata:
1286 break
1286 break
1287 node = chunkdata['node']
1287 node = chunkdata['node']
1288 ui.write("%s\n" % hex(node))
1288 ui.write("%s\n" % hex(node))
1289 chain = node
1289 chain = node
1290 finally:
1290 finally:
1291 f.close()
1291 f.close()
1292
1292
1293 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1293 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1294 """retrieves a bundle from a repo
1294 """retrieves a bundle from a repo
1295
1295
1296 Every ID must be a full-length hex node id string. Saves the bundle to the
1296 Every ID must be a full-length hex node id string. Saves the bundle to the
1297 given file.
1297 given file.
1298 """
1298 """
1299 repo = hg.repository(ui, repopath)
1299 repo = hg.repository(ui, repopath)
1300 if not repo.capable('getbundle'):
1300 if not repo.capable('getbundle'):
1301 raise util.Abort("getbundle() not supported by target repository")
1301 raise util.Abort("getbundle() not supported by target repository")
1302 args = {}
1302 args = {}
1303 if common:
1303 if common:
1304 args['common'] = [bin(s) for s in common]
1304 args['common'] = [bin(s) for s in common]
1305 if head:
1305 if head:
1306 args['heads'] = [bin(s) for s in head]
1306 args['heads'] = [bin(s) for s in head]
1307 bundle = repo.getbundle('debug', **args)
1307 bundle = repo.getbundle('debug', **args)
1308
1308
1309 bundletype = opts.get('type', 'bzip2').lower()
1309 bundletype = opts.get('type', 'bzip2').lower()
1310 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1310 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1311 bundletype = btypes.get(bundletype)
1311 bundletype = btypes.get(bundletype)
1312 if bundletype not in changegroup.bundletypes:
1312 if bundletype not in changegroup.bundletypes:
1313 raise util.Abort(_('unknown bundle type specified with --type'))
1313 raise util.Abort(_('unknown bundle type specified with --type'))
1314 changegroup.writebundle(bundle, bundlepath, bundletype)
1314 changegroup.writebundle(bundle, bundlepath, bundletype)
1315
1315
1316 def debugpushkey(ui, repopath, namespace, *keyinfo):
1316 def debugpushkey(ui, repopath, namespace, *keyinfo):
1317 '''access the pushkey key/value protocol
1317 '''access the pushkey key/value protocol
1318
1318
1319 With two args, list the keys in the given namespace.
1319 With two args, list the keys in the given namespace.
1320
1320
1321 With five args, set a key to new if it currently is set to old.
1321 With five args, set a key to new if it currently is set to old.
1322 Reports success or failure.
1322 Reports success or failure.
1323 '''
1323 '''
1324
1324
1325 target = hg.repository(ui, repopath)
1325 target = hg.repository(ui, repopath)
1326 if keyinfo:
1326 if keyinfo:
1327 key, old, new = keyinfo
1327 key, old, new = keyinfo
1328 r = target.pushkey(namespace, key, old, new)
1328 r = target.pushkey(namespace, key, old, new)
1329 ui.status(str(r) + '\n')
1329 ui.status(str(r) + '\n')
1330 return not r
1330 return not r
1331 else:
1331 else:
1332 for k, v in target.listkeys(namespace).iteritems():
1332 for k, v in target.listkeys(namespace).iteritems():
1333 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1333 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1334 v.encode('string-escape')))
1334 v.encode('string-escape')))
1335
1335
1336 def debugrevspec(ui, repo, expr):
1336 def debugrevspec(ui, repo, expr):
1337 '''parse and apply a revision specification'''
1337 '''parse and apply a revision specification'''
1338 if ui.verbose:
1338 if ui.verbose:
1339 tree = revset.parse(expr)[0]
1339 tree = revset.parse(expr)[0]
1340 ui.note(tree, "\n")
1340 ui.note(tree, "\n")
1341 newtree = revset.findaliases(ui, tree)
1341 newtree = revset.findaliases(ui, tree)
1342 if newtree != tree:
1342 if newtree != tree:
1343 ui.note(newtree, "\n")
1343 ui.note(newtree, "\n")
1344 func = revset.match(ui, expr)
1344 func = revset.match(ui, expr)
1345 for c in func(repo, range(len(repo))):
1345 for c in func(repo, range(len(repo))):
1346 ui.write("%s\n" % c)
1346 ui.write("%s\n" % c)
1347
1347
1348 def debugsetparents(ui, repo, rev1, rev2=None):
1348 def debugsetparents(ui, repo, rev1, rev2=None):
1349 """manually set the parents of the current working directory
1349 """manually set the parents of the current working directory
1350
1350
1351 This is useful for writing repository conversion tools, but should
1351 This is useful for writing repository conversion tools, but should
1352 be used with care.
1352 be used with care.
1353
1353
1354 Returns 0 on success.
1354 Returns 0 on success.
1355 """
1355 """
1356
1356
1357 r1 = cmdutil.revsingle(repo, rev1).node()
1357 r1 = cmdutil.revsingle(repo, rev1).node()
1358 r2 = cmdutil.revsingle(repo, rev2, 'null').node()
1358 r2 = cmdutil.revsingle(repo, rev2, 'null').node()
1359
1359
1360 wlock = repo.wlock()
1360 wlock = repo.wlock()
1361 try:
1361 try:
1362 repo.dirstate.setparents(r1, r2)
1362 repo.dirstate.setparents(r1, r2)
1363 finally:
1363 finally:
1364 wlock.release()
1364 wlock.release()
1365
1365
1366 def debugstate(ui, repo, nodates=None, datesort=None):
1366 def debugstate(ui, repo, nodates=None, datesort=None):
1367 """show the contents of the current dirstate"""
1367 """show the contents of the current dirstate"""
1368 timestr = ""
1368 timestr = ""
1369 showdate = not nodates
1369 showdate = not nodates
1370 if datesort:
1370 if datesort:
1371 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
1371 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
1372 else:
1372 else:
1373 keyfunc = None # sort by filename
1373 keyfunc = None # sort by filename
1374 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
1374 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
1375 if showdate:
1375 if showdate:
1376 if ent[3] == -1:
1376 if ent[3] == -1:
1377 # Pad or slice to locale representation
1377 # Pad or slice to locale representation
1378 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1378 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1379 time.localtime(0)))
1379 time.localtime(0)))
1380 timestr = 'unset'
1380 timestr = 'unset'
1381 timestr = (timestr[:locale_len] +
1381 timestr = (timestr[:locale_len] +
1382 ' ' * (locale_len - len(timestr)))
1382 ' ' * (locale_len - len(timestr)))
1383 else:
1383 else:
1384 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1384 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1385 time.localtime(ent[3]))
1385 time.localtime(ent[3]))
1386 if ent[1] & 020000:
1386 if ent[1] & 020000:
1387 mode = 'lnk'
1387 mode = 'lnk'
1388 else:
1388 else:
1389 mode = '%3o' % (ent[1] & 0777)
1389 mode = '%3o' % (ent[1] & 0777)
1390 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1390 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1391 for f in repo.dirstate.copies():
1391 for f in repo.dirstate.copies():
1392 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1392 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1393
1393
1394 def debugsub(ui, repo, rev=None):
1394 def debugsub(ui, repo, rev=None):
1395 ctx = cmdutil.revsingle(repo, rev, None)
1395 ctx = cmdutil.revsingle(repo, rev, None)
1396 for k, v in sorted(ctx.substate.items()):
1396 for k, v in sorted(ctx.substate.items()):
1397 ui.write('path %s\n' % k)
1397 ui.write('path %s\n' % k)
1398 ui.write(' source %s\n' % v[0])
1398 ui.write(' source %s\n' % v[0])
1399 ui.write(' revision %s\n' % v[1])
1399 ui.write(' revision %s\n' % v[1])
1400
1400
1401 def debugdag(ui, repo, file_=None, *revs, **opts):
1401 def debugdag(ui, repo, file_=None, *revs, **opts):
1402 """format the changelog or an index DAG as a concise textual description
1402 """format the changelog or an index DAG as a concise textual description
1403
1403
1404 If you pass a revlog index, the revlog's DAG is emitted. If you list
1404 If you pass a revlog index, the revlog's DAG is emitted. If you list
1405 revision numbers, they get labelled in the output as rN.
1405 revision numbers, they get labelled in the output as rN.
1406
1406
1407 Otherwise, the changelog DAG of the current repo is emitted.
1407 Otherwise, the changelog DAG of the current repo is emitted.
1408 """
1408 """
1409 spaces = opts.get('spaces')
1409 spaces = opts.get('spaces')
1410 dots = opts.get('dots')
1410 dots = opts.get('dots')
1411 if file_:
1411 if file_:
1412 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1412 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1413 revs = set((int(r) for r in revs))
1413 revs = set((int(r) for r in revs))
1414 def events():
1414 def events():
1415 for r in rlog:
1415 for r in rlog:
1416 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1416 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1417 if r in revs:
1417 if r in revs:
1418 yield 'l', (r, "r%i" % r)
1418 yield 'l', (r, "r%i" % r)
1419 elif repo:
1419 elif repo:
1420 cl = repo.changelog
1420 cl = repo.changelog
1421 tags = opts.get('tags')
1421 tags = opts.get('tags')
1422 branches = opts.get('branches')
1422 branches = opts.get('branches')
1423 if tags:
1423 if tags:
1424 labels = {}
1424 labels = {}
1425 for l, n in repo.tags().items():
1425 for l, n in repo.tags().items():
1426 labels.setdefault(cl.rev(n), []).append(l)
1426 labels.setdefault(cl.rev(n), []).append(l)
1427 def events():
1427 def events():
1428 b = "default"
1428 b = "default"
1429 for r in cl:
1429 for r in cl:
1430 if branches:
1430 if branches:
1431 newb = cl.read(cl.node(r))[5]['branch']
1431 newb = cl.read(cl.node(r))[5]['branch']
1432 if newb != b:
1432 if newb != b:
1433 yield 'a', newb
1433 yield 'a', newb
1434 b = newb
1434 b = newb
1435 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1435 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1436 if tags:
1436 if tags:
1437 ls = labels.get(r)
1437 ls = labels.get(r)
1438 if ls:
1438 if ls:
1439 for l in ls:
1439 for l in ls:
1440 yield 'l', (r, l)
1440 yield 'l', (r, l)
1441 else:
1441 else:
1442 raise util.Abort(_('need repo for changelog dag'))
1442 raise util.Abort(_('need repo for changelog dag'))
1443
1443
1444 for line in dagparser.dagtextlines(events(),
1444 for line in dagparser.dagtextlines(events(),
1445 addspaces=spaces,
1445 addspaces=spaces,
1446 wraplabels=True,
1446 wraplabels=True,
1447 wrapannotations=True,
1447 wrapannotations=True,
1448 wrapnonlinear=dots,
1448 wrapnonlinear=dots,
1449 usedots=dots,
1449 usedots=dots,
1450 maxlinewidth=70):
1450 maxlinewidth=70):
1451 ui.write(line)
1451 ui.write(line)
1452 ui.write("\n")
1452 ui.write("\n")
1453
1453
1454 def debugdata(ui, repo, file_, rev):
1454 def debugdata(ui, repo, file_, rev):
1455 """dump the contents of a data file revision"""
1455 """dump the contents of a data file revision"""
1456 r = None
1456 r = None
1457 if repo:
1457 if repo:
1458 filelog = repo.file(file_)
1458 filelog = repo.file(file_)
1459 if len(filelog):
1459 if len(filelog):
1460 r = filelog
1460 r = filelog
1461 if not r:
1461 if not r:
1462 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
1462 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
1463 file_[:-2] + ".i")
1463 file_[:-2] + ".i")
1464 try:
1464 try:
1465 ui.write(r.revision(r.lookup(rev)))
1465 ui.write(r.revision(r.lookup(rev)))
1466 except KeyError:
1466 except KeyError:
1467 raise util.Abort(_('invalid revision identifier %s') % rev)
1467 raise util.Abort(_('invalid revision identifier %s') % rev)
1468
1468
1469 def debugdate(ui, date, range=None, **opts):
1469 def debugdate(ui, date, range=None, **opts):
1470 """parse and display a date"""
1470 """parse and display a date"""
1471 if opts["extended"]:
1471 if opts["extended"]:
1472 d = util.parsedate(date, util.extendeddateformats)
1472 d = util.parsedate(date, util.extendeddateformats)
1473 else:
1473 else:
1474 d = util.parsedate(date)
1474 d = util.parsedate(date)
1475 ui.write("internal: %s %s\n" % d)
1475 ui.write("internal: %s %s\n" % d)
1476 ui.write("standard: %s\n" % util.datestr(d))
1476 ui.write("standard: %s\n" % util.datestr(d))
1477 if range:
1477 if range:
1478 m = util.matchdate(range)
1478 m = util.matchdate(range)
1479 ui.write("match: %s\n" % m(d[0]))
1479 ui.write("match: %s\n" % m(d[0]))
1480
1480
1481 def debugignore(ui, repo, *values, **opts):
1481 def debugignore(ui, repo, *values, **opts):
1482 """display the combined ignore pattern"""
1482 """display the combined ignore pattern"""
1483 ignore = repo.dirstate._ignore
1483 ignore = repo.dirstate._ignore
1484 if hasattr(ignore, 'includepat'):
1484 if hasattr(ignore, 'includepat'):
1485 ui.write("%s\n" % ignore.includepat)
1485 ui.write("%s\n" % ignore.includepat)
1486 else:
1486 else:
1487 raise util.Abort(_("no ignore patterns found"))
1487 raise util.Abort(_("no ignore patterns found"))
1488
1488
1489 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1489 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1490 """runs the changeset discovery protocol in isolation"""
1490 """runs the changeset discovery protocol in isolation"""
1491 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
1491 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
1492 remote = hg.repository(hg.remoteui(repo, opts), remoteurl)
1492 remote = hg.repository(hg.remoteui(repo, opts), remoteurl)
1493 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1493 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1494
1494
1495 # make sure tests are repeatable
1495 # make sure tests are repeatable
1496 random.seed(12323)
1496 random.seed(12323)
1497
1497
1498 def doit(localheads, remoteheads):
1498 def doit(localheads, remoteheads):
1499 if opts.get('old'):
1499 if opts.get('old'):
1500 if localheads:
1500 if localheads:
1501 raise util.Abort('cannot use localheads with old style discovery')
1501 raise util.Abort('cannot use localheads with old style discovery')
1502 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1502 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1503 force=True)
1503 force=True)
1504 common = set(common)
1504 common = set(common)
1505 if not opts.get('nonheads'):
1505 if not opts.get('nonheads'):
1506 ui.write("unpruned common: %s\n" % " ".join([short(n)
1506 ui.write("unpruned common: %s\n" % " ".join([short(n)
1507 for n in common]))
1507 for n in common]))
1508 dag = dagutil.revlogdag(repo.changelog)
1508 dag = dagutil.revlogdag(repo.changelog)
1509 all = dag.ancestorset(dag.internalizeall(common))
1509 all = dag.ancestorset(dag.internalizeall(common))
1510 common = dag.externalizeall(dag.headsetofconnecteds(all))
1510 common = dag.externalizeall(dag.headsetofconnecteds(all))
1511 else:
1511 else:
1512 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1512 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1513 common = set(common)
1513 common = set(common)
1514 rheads = set(hds)
1514 rheads = set(hds)
1515 lheads = set(repo.heads())
1515 lheads = set(repo.heads())
1516 ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
1516 ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
1517 if lheads <= common:
1517 if lheads <= common:
1518 ui.write("local is subset\n")
1518 ui.write("local is subset\n")
1519 elif rheads <= common:
1519 elif rheads <= common:
1520 ui.write("remote is subset\n")
1520 ui.write("remote is subset\n")
1521
1521
1522 serverlogs = opts.get('serverlog')
1522 serverlogs = opts.get('serverlog')
1523 if serverlogs:
1523 if serverlogs:
1524 for filename in serverlogs:
1524 for filename in serverlogs:
1525 logfile = open(filename, 'r')
1525 logfile = open(filename, 'r')
1526 try:
1526 try:
1527 line = logfile.readline()
1527 line = logfile.readline()
1528 while line:
1528 while line:
1529 parts = line.strip().split(';')
1529 parts = line.strip().split(';')
1530 op = parts[1]
1530 op = parts[1]
1531 if op == 'cg':
1531 if op == 'cg':
1532 pass
1532 pass
1533 elif op == 'cgss':
1533 elif op == 'cgss':
1534 doit(parts[2].split(' '), parts[3].split(' '))
1534 doit(parts[2].split(' '), parts[3].split(' '))
1535 elif op == 'unb':
1535 elif op == 'unb':
1536 doit(parts[3].split(' '), parts[2].split(' '))
1536 doit(parts[3].split(' '), parts[2].split(' '))
1537 line = logfile.readline()
1537 line = logfile.readline()
1538 finally:
1538 finally:
1539 logfile.close()
1539 logfile.close()
1540
1540
1541 else:
1541 else:
1542 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
1542 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
1543 opts.get('remote_head'))
1543 opts.get('remote_head'))
1544 localrevs = opts.get('local_head')
1544 localrevs = opts.get('local_head')
1545 doit(localrevs, remoterevs)
1545 doit(localrevs, remoterevs)
1546
1546
1547
1547
1548 def debugindex(ui, repo, file_, **opts):
1548 def debugindex(ui, repo, file_, **opts):
1549 """dump the contents of an index file"""
1549 """dump the contents of an index file"""
1550 r = None
1550 r = None
1551 if repo:
1551 if repo:
1552 filelog = repo.file(file_)
1552 filelog = repo.file(file_)
1553 if len(filelog):
1553 if len(filelog):
1554 r = filelog
1554 r = filelog
1555
1555
1556 format = opts.get('format', 0)
1556 format = opts.get('format', 0)
1557 if format not in (0, 1):
1557 if format not in (0, 1):
1558 raise util.Abort(_("unknown format %d") % format)
1558 raise util.Abort(_("unknown format %d") % format)
1559
1559
1560 if not r:
1560 if not r:
1561 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1561 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1562
1562
1563 generaldelta = r.version & revlog.REVLOGGENERALDELTA
1563 generaldelta = r.version & revlog.REVLOGGENERALDELTA
1564 if generaldelta:
1564 if generaldelta:
1565 basehdr = ' delta'
1565 basehdr = ' delta'
1566 else:
1566 else:
1567 basehdr = ' base'
1567 basehdr = ' base'
1568
1568
1569 if format == 0:
1569 if format == 0:
1570 ui.write(" rev offset length " + basehdr + " linkrev"
1570 ui.write(" rev offset length " + basehdr + " linkrev"
1571 " nodeid p1 p2\n")
1571 " nodeid p1 p2\n")
1572 elif format == 1:
1572 elif format == 1:
1573 ui.write(" rev flag offset length"
1573 ui.write(" rev flag offset length"
1574 " size " + basehdr + " link p1 p2 nodeid\n")
1574 " size " + basehdr + " link p1 p2 nodeid\n")
1575
1575
1576 for i in r:
1576 for i in r:
1577 node = r.node(i)
1577 node = r.node(i)
1578 if generaldelta:
1578 if generaldelta:
1579 base = r.deltaparent(i)
1579 base = r.deltaparent(i)
1580 else:
1580 else:
1581 base = r.chainbase(i)
1581 base = r.chainbase(i)
1582 if format == 0:
1582 if format == 0:
1583 try:
1583 try:
1584 pp = r.parents(node)
1584 pp = r.parents(node)
1585 except:
1585 except:
1586 pp = [nullid, nullid]
1586 pp = [nullid, nullid]
1587 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1587 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1588 i, r.start(i), r.length(i), base, r.linkrev(i),
1588 i, r.start(i), r.length(i), base, r.linkrev(i),
1589 short(node), short(pp[0]), short(pp[1])))
1589 short(node), short(pp[0]), short(pp[1])))
1590 elif format == 1:
1590 elif format == 1:
1591 pr = r.parentrevs(i)
1591 pr = r.parentrevs(i)
1592 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1592 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1593 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1593 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1594 base, r.linkrev(i), pr[0], pr[1], short(node)))
1594 base, r.linkrev(i), pr[0], pr[1], short(node)))
1595
1595
1596 def debugindexdot(ui, repo, file_):
1596 def debugindexdot(ui, repo, file_):
1597 """dump an index DAG as a graphviz dot file"""
1597 """dump an index DAG as a graphviz dot file"""
1598 r = None
1598 r = None
1599 if repo:
1599 if repo:
1600 filelog = repo.file(file_)
1600 filelog = repo.file(file_)
1601 if len(filelog):
1601 if len(filelog):
1602 r = filelog
1602 r = filelog
1603 if not r:
1603 if not r:
1604 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1604 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1605 ui.write("digraph G {\n")
1605 ui.write("digraph G {\n")
1606 for i in r:
1606 for i in r:
1607 node = r.node(i)
1607 node = r.node(i)
1608 pp = r.parents(node)
1608 pp = r.parents(node)
1609 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1609 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1610 if pp[1] != nullid:
1610 if pp[1] != nullid:
1611 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1611 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1612 ui.write("}\n")
1612 ui.write("}\n")
1613
1613
1614 def debuginstall(ui):
1614 def debuginstall(ui):
1615 '''test Mercurial installation
1615 '''test Mercurial installation
1616
1616
1617 Returns 0 on success.
1617 Returns 0 on success.
1618 '''
1618 '''
1619
1619
1620 def writetemp(contents):
1620 def writetemp(contents):
1621 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1621 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1622 f = os.fdopen(fd, "wb")
1622 f = os.fdopen(fd, "wb")
1623 f.write(contents)
1623 f.write(contents)
1624 f.close()
1624 f.close()
1625 return name
1625 return name
1626
1626
1627 problems = 0
1627 problems = 0
1628
1628
1629 # encoding
1629 # encoding
1630 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1630 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1631 try:
1631 try:
1632 encoding.fromlocal("test")
1632 encoding.fromlocal("test")
1633 except util.Abort, inst:
1633 except util.Abort, inst:
1634 ui.write(" %s\n" % inst)
1634 ui.write(" %s\n" % inst)
1635 ui.write(_(" (check that your locale is properly set)\n"))
1635 ui.write(_(" (check that your locale is properly set)\n"))
1636 problems += 1
1636 problems += 1
1637
1637
1638 # compiled modules
1638 # compiled modules
1639 ui.status(_("Checking installed modules (%s)...\n")
1639 ui.status(_("Checking installed modules (%s)...\n")
1640 % os.path.dirname(__file__))
1640 % os.path.dirname(__file__))
1641 try:
1641 try:
1642 import bdiff, mpatch, base85, osutil
1642 import bdiff, mpatch, base85, osutil
1643 except Exception, inst:
1643 except Exception, inst:
1644 ui.write(" %s\n" % inst)
1644 ui.write(" %s\n" % inst)
1645 ui.write(_(" One or more extensions could not be found"))
1645 ui.write(_(" One or more extensions could not be found"))
1646 ui.write(_(" (check that you compiled the extensions)\n"))
1646 ui.write(_(" (check that you compiled the extensions)\n"))
1647 problems += 1
1647 problems += 1
1648
1648
1649 # templates
1649 # templates
1650 ui.status(_("Checking templates...\n"))
1650 ui.status(_("Checking templates...\n"))
1651 try:
1651 try:
1652 import templater
1652 import templater
1653 templater.templater(templater.templatepath("map-cmdline.default"))
1653 templater.templater(templater.templatepath("map-cmdline.default"))
1654 except Exception, inst:
1654 except Exception, inst:
1655 ui.write(" %s\n" % inst)
1655 ui.write(" %s\n" % inst)
1656 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1656 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1657 problems += 1
1657 problems += 1
1658
1658
1659 # editor
1659 # editor
1660 ui.status(_("Checking commit editor...\n"))
1660 ui.status(_("Checking commit editor...\n"))
1661 editor = ui.geteditor()
1661 editor = ui.geteditor()
1662 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
1662 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
1663 if not cmdpath:
1663 if not cmdpath:
1664 if editor == 'vi':
1664 if editor == 'vi':
1665 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1665 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1666 ui.write(_(" (specify a commit editor in your configuration"
1666 ui.write(_(" (specify a commit editor in your configuration"
1667 " file)\n"))
1667 " file)\n"))
1668 else:
1668 else:
1669 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1669 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1670 ui.write(_(" (specify a commit editor in your configuration"
1670 ui.write(_(" (specify a commit editor in your configuration"
1671 " file)\n"))
1671 " file)\n"))
1672 problems += 1
1672 problems += 1
1673
1673
1674 # check username
1674 # check username
1675 ui.status(_("Checking username...\n"))
1675 ui.status(_("Checking username...\n"))
1676 try:
1676 try:
1677 ui.username()
1677 ui.username()
1678 except util.Abort, e:
1678 except util.Abort, e:
1679 ui.write(" %s\n" % e)
1679 ui.write(" %s\n" % e)
1680 ui.write(_(" (specify a username in your configuration file)\n"))
1680 ui.write(_(" (specify a username in your configuration file)\n"))
1681 problems += 1
1681 problems += 1
1682
1682
1683 if not problems:
1683 if not problems:
1684 ui.status(_("No problems detected\n"))
1684 ui.status(_("No problems detected\n"))
1685 else:
1685 else:
1686 ui.write(_("%s problems detected,"
1686 ui.write(_("%s problems detected,"
1687 " please check your install!\n") % problems)
1687 " please check your install!\n") % problems)
1688
1688
1689 return problems
1689 return problems
1690
1690
1691 def debugrename(ui, repo, file1, *pats, **opts):
1691 def debugrename(ui, repo, file1, *pats, **opts):
1692 """dump rename information"""
1692 """dump rename information"""
1693
1693
1694 ctx = cmdutil.revsingle(repo, opts.get('rev'))
1694 ctx = cmdutil.revsingle(repo, opts.get('rev'))
1695 m = cmdutil.match(repo, (file1,) + pats, opts)
1695 m = cmdutil.match(repo, (file1,) + pats, opts)
1696 for abs in ctx.walk(m):
1696 for abs in ctx.walk(m):
1697 fctx = ctx[abs]
1697 fctx = ctx[abs]
1698 o = fctx.filelog().renamed(fctx.filenode())
1698 o = fctx.filelog().renamed(fctx.filenode())
1699 rel = m.rel(abs)
1699 rel = m.rel(abs)
1700 if o:
1700 if o:
1701 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1701 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1702 else:
1702 else:
1703 ui.write(_("%s not renamed\n") % rel)
1703 ui.write(_("%s not renamed\n") % rel)
1704
1704
1705 def debugwalk(ui, repo, *pats, **opts):
1705 def debugwalk(ui, repo, *pats, **opts):
1706 """show how files match on given patterns"""
1706 """show how files match on given patterns"""
1707 m = cmdutil.match(repo, pats, opts)
1707 m = cmdutil.match(repo, pats, opts)
1708 items = list(repo.walk(m))
1708 items = list(repo.walk(m))
1709 if not items:
1709 if not items:
1710 return
1710 return
1711 fmt = 'f %%-%ds %%-%ds %%s' % (
1711 fmt = 'f %%-%ds %%-%ds %%s' % (
1712 max([len(abs) for abs in items]),
1712 max([len(abs) for abs in items]),
1713 max([len(m.rel(abs)) for abs in items]))
1713 max([len(m.rel(abs)) for abs in items]))
1714 for abs in items:
1714 for abs in items:
1715 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1715 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1716 ui.write("%s\n" % line.rstrip())
1716 ui.write("%s\n" % line.rstrip())
1717
1717
1718 def debugwireargs(ui, repopath, *vals, **opts):
1718 def debugwireargs(ui, repopath, *vals, **opts):
1719 repo = hg.repository(hg.remoteui(ui, opts), repopath)
1719 repo = hg.repository(hg.remoteui(ui, opts), repopath)
1720 for opt in remoteopts:
1720 for opt in remoteopts:
1721 del opts[opt[1]]
1721 del opts[opt[1]]
1722 args = {}
1722 args = {}
1723 for k, v in opts.iteritems():
1723 for k, v in opts.iteritems():
1724 if v:
1724 if v:
1725 args[k] = v
1725 args[k] = v
1726 # run twice to check that we don't mess up the stream for the next command
1726 # run twice to check that we don't mess up the stream for the next command
1727 res1 = repo.debugwireargs(*vals, **args)
1727 res1 = repo.debugwireargs(*vals, **args)
1728 res2 = repo.debugwireargs(*vals, **args)
1728 res2 = repo.debugwireargs(*vals, **args)
1729 ui.write("%s\n" % res1)
1729 ui.write("%s\n" % res1)
1730 if res1 != res2:
1730 if res1 != res2:
1731 ui.warn("%s\n" % res2)
1731 ui.warn("%s\n" % res2)
1732
1732
1733 def diff(ui, repo, *pats, **opts):
1733 def diff(ui, repo, *pats, **opts):
1734 """diff repository (or selected files)
1734 """diff repository (or selected files)
1735
1735
1736 Show differences between revisions for the specified files.
1736 Show differences between revisions for the specified files.
1737
1737
1738 Differences between files are shown using the unified diff format.
1738 Differences between files are shown using the unified diff format.
1739
1739
1740 .. note::
1740 .. note::
1741 diff may generate unexpected results for merges, as it will
1741 diff may generate unexpected results for merges, as it will
1742 default to comparing against the working directory's first
1742 default to comparing against the working directory's first
1743 parent changeset if no revisions are specified.
1743 parent changeset if no revisions are specified.
1744
1744
1745 When two revision arguments are given, then changes are shown
1745 When two revision arguments are given, then changes are shown
1746 between those revisions. If only one revision is specified then
1746 between those revisions. If only one revision is specified then
1747 that revision is compared to the working directory, and, when no
1747 that revision is compared to the working directory, and, when no
1748 revisions are specified, the working directory files are compared
1748 revisions are specified, the working directory files are compared
1749 to its parent.
1749 to its parent.
1750
1750
1751 Alternatively you can specify -c/--change with a revision to see
1751 Alternatively you can specify -c/--change with a revision to see
1752 the changes in that changeset relative to its first parent.
1752 the changes in that changeset relative to its first parent.
1753
1753
1754 Without the -a/--text option, diff will avoid generating diffs of
1754 Without the -a/--text option, diff will avoid generating diffs of
1755 files it detects as binary. With -a, diff will generate a diff
1755 files it detects as binary. With -a, diff will generate a diff
1756 anyway, probably with undesirable results.
1756 anyway, probably with undesirable results.
1757
1757
1758 Use the -g/--git option to generate diffs in the git extended diff
1758 Use the -g/--git option to generate diffs in the git extended diff
1759 format. For more information, read :hg:`help diffs`.
1759 format. For more information, read :hg:`help diffs`.
1760
1760
1761 Returns 0 on success.
1761 Returns 0 on success.
1762 """
1762 """
1763
1763
1764 revs = opts.get('rev')
1764 revs = opts.get('rev')
1765 change = opts.get('change')
1765 change = opts.get('change')
1766 stat = opts.get('stat')
1766 stat = opts.get('stat')
1767 reverse = opts.get('reverse')
1767 reverse = opts.get('reverse')
1768
1768
1769 if revs and change:
1769 if revs and change:
1770 msg = _('cannot specify --rev and --change at the same time')
1770 msg = _('cannot specify --rev and --change at the same time')
1771 raise util.Abort(msg)
1771 raise util.Abort(msg)
1772 elif change:
1772 elif change:
1773 node2 = cmdutil.revsingle(repo, change, None).node()
1773 node2 = cmdutil.revsingle(repo, change, None).node()
1774 node1 = repo[node2].p1().node()
1774 node1 = repo[node2].p1().node()
1775 else:
1775 else:
1776 node1, node2 = cmdutil.revpair(repo, revs)
1776 node1, node2 = cmdutil.revpair(repo, revs)
1777
1777
1778 if reverse:
1778 if reverse:
1779 node1, node2 = node2, node1
1779 node1, node2 = node2, node1
1780
1780
1781 diffopts = patch.diffopts(ui, opts)
1781 diffopts = patch.diffopts(ui, opts)
1782 m = cmdutil.match(repo, pats, opts)
1782 m = cmdutil.match(repo, pats, opts)
1783 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1783 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1784 listsubrepos=opts.get('subrepos'))
1784 listsubrepos=opts.get('subrepos'))
1785
1785
1786 def export(ui, repo, *changesets, **opts):
1786 def export(ui, repo, *changesets, **opts):
1787 """dump the header and diffs for one or more changesets
1787 """dump the header and diffs for one or more changesets
1788
1788
1789 Print the changeset header and diffs for one or more revisions.
1789 Print the changeset header and diffs for one or more revisions.
1790
1790
1791 The information shown in the changeset header is: author, date,
1791 The information shown in the changeset header is: author, date,
1792 branch name (if non-default), changeset hash, parent(s) and commit
1792 branch name (if non-default), changeset hash, parent(s) and commit
1793 comment.
1793 comment.
1794
1794
1795 .. note::
1795 .. note::
1796 export may generate unexpected diff output for merge
1796 export may generate unexpected diff output for merge
1797 changesets, as it will compare the merge changeset against its
1797 changesets, as it will compare the merge changeset against its
1798 first parent only.
1798 first parent only.
1799
1799
1800 Output may be to a file, in which case the name of the file is
1800 Output may be to a file, in which case the name of the file is
1801 given using a format string. The formatting rules are as follows:
1801 given using a format string. The formatting rules are as follows:
1802
1802
1803 :``%%``: literal "%" character
1803 :``%%``: literal "%" character
1804 :``%H``: changeset hash (40 hexadecimal digits)
1804 :``%H``: changeset hash (40 hexadecimal digits)
1805 :``%N``: number of patches being generated
1805 :``%N``: number of patches being generated
1806 :``%R``: changeset revision number
1806 :``%R``: changeset revision number
1807 :``%b``: basename of the exporting repository
1807 :``%b``: basename of the exporting repository
1808 :``%h``: short-form changeset hash (12 hexadecimal digits)
1808 :``%h``: short-form changeset hash (12 hexadecimal digits)
1809 :``%n``: zero-padded sequence number, starting at 1
1809 :``%n``: zero-padded sequence number, starting at 1
1810 :``%r``: zero-padded changeset revision number
1810 :``%r``: zero-padded changeset revision number
1811
1811
1812 Without the -a/--text option, export will avoid generating diffs
1812 Without the -a/--text option, export will avoid generating diffs
1813 of files it detects as binary. With -a, export will generate a
1813 of files it detects as binary. With -a, export will generate a
1814 diff anyway, probably with undesirable results.
1814 diff anyway, probably with undesirable results.
1815
1815
1816 Use the -g/--git option to generate diffs in the git extended diff
1816 Use the -g/--git option to generate diffs in the git extended diff
1817 format. See :hg:`help diffs` for more information.
1817 format. See :hg:`help diffs` for more information.
1818
1818
1819 With the --switch-parent option, the diff will be against the
1819 With the --switch-parent option, the diff will be against the
1820 second parent. It can be useful to review a merge.
1820 second parent. It can be useful to review a merge.
1821
1821
1822 Returns 0 on success.
1822 Returns 0 on success.
1823 """
1823 """
1824 changesets += tuple(opts.get('rev', []))
1824 changesets += tuple(opts.get('rev', []))
1825 if not changesets:
1825 if not changesets:
1826 raise util.Abort(_("export requires at least one changeset"))
1826 raise util.Abort(_("export requires at least one changeset"))
1827 revs = cmdutil.revrange(repo, changesets)
1827 revs = cmdutil.revrange(repo, changesets)
1828 if len(revs) > 1:
1828 if len(revs) > 1:
1829 ui.note(_('exporting patches:\n'))
1829 ui.note(_('exporting patches:\n'))
1830 else:
1830 else:
1831 ui.note(_('exporting patch:\n'))
1831 ui.note(_('exporting patch:\n'))
1832 cmdutil.export(repo, revs, template=opts.get('output'),
1832 cmdutil.export(repo, revs, template=opts.get('output'),
1833 switch_parent=opts.get('switch_parent'),
1833 switch_parent=opts.get('switch_parent'),
1834 opts=patch.diffopts(ui, opts))
1834 opts=patch.diffopts(ui, opts))
1835
1835
1836 def forget(ui, repo, *pats, **opts):
1836 def forget(ui, repo, *pats, **opts):
1837 """forget the specified files on the next commit
1837 """forget the specified files on the next commit
1838
1838
1839 Mark the specified files so they will no longer be tracked
1839 Mark the specified files so they will no longer be tracked
1840 after the next commit.
1840 after the next commit.
1841
1841
1842 This only removes files from the current branch, not from the
1842 This only removes files from the current branch, not from the
1843 entire project history, and it does not delete them from the
1843 entire project history, and it does not delete them from the
1844 working directory.
1844 working directory.
1845
1845
1846 To undo a forget before the next commit, see :hg:`add`.
1846 To undo a forget before the next commit, see :hg:`add`.
1847
1847
1848 Returns 0 on success.
1848 Returns 0 on success.
1849 """
1849 """
1850
1850
1851 if not pats:
1851 if not pats:
1852 raise util.Abort(_('no files specified'))
1852 raise util.Abort(_('no files specified'))
1853
1853
1854 m = cmdutil.match(repo, pats, opts)
1854 m = cmdutil.match(repo, pats, opts)
1855 s = repo.status(match=m, clean=True)
1855 s = repo.status(match=m, clean=True)
1856 forget = sorted(s[0] + s[1] + s[3] + s[6])
1856 forget = sorted(s[0] + s[1] + s[3] + s[6])
1857 errs = 0
1857 errs = 0
1858
1858
1859 for f in m.files():
1859 for f in m.files():
1860 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1860 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1861 ui.warn(_('not removing %s: file is already untracked\n')
1861 ui.warn(_('not removing %s: file is already untracked\n')
1862 % m.rel(f))
1862 % m.rel(f))
1863 errs = 1
1863 errs = 1
1864
1864
1865 for f in forget:
1865 for f in forget:
1866 if ui.verbose or not m.exact(f):
1866 if ui.verbose or not m.exact(f):
1867 ui.status(_('removing %s\n') % m.rel(f))
1867 ui.status(_('removing %s\n') % m.rel(f))
1868
1868
1869 repo[None].remove(forget, unlink=False)
1869 repo[None].remove(forget, unlink=False)
1870 return errs
1870 return errs
1871
1871
1872 def grep(ui, repo, pattern, *pats, **opts):
1872 def grep(ui, repo, pattern, *pats, **opts):
1873 """search for a pattern in specified files and revisions
1873 """search for a pattern in specified files and revisions
1874
1874
1875 Search revisions of files for a regular expression.
1875 Search revisions of files for a regular expression.
1876
1876
1877 This command behaves differently than Unix grep. It only accepts
1877 This command behaves differently than Unix grep. It only accepts
1878 Python/Perl regexps. It searches repository history, not the
1878 Python/Perl regexps. It searches repository history, not the
1879 working directory. It always prints the revision number in which a
1879 working directory. It always prints the revision number in which a
1880 match appears.
1880 match appears.
1881
1881
1882 By default, grep only prints output for the first revision of a
1882 By default, grep only prints output for the first revision of a
1883 file in which it finds a match. To get it to print every revision
1883 file in which it finds a match. To get it to print every revision
1884 that contains a change in match status ("-" for a match that
1884 that contains a change in match status ("-" for a match that
1885 becomes a non-match, or "+" for a non-match that becomes a match),
1885 becomes a non-match, or "+" for a non-match that becomes a match),
1886 use the --all flag.
1886 use the --all flag.
1887
1887
1888 Returns 0 if a match is found, 1 otherwise.
1888 Returns 0 if a match is found, 1 otherwise.
1889 """
1889 """
1890 reflags = 0
1890 reflags = 0
1891 if opts.get('ignore_case'):
1891 if opts.get('ignore_case'):
1892 reflags |= re.I
1892 reflags |= re.I
1893 try:
1893 try:
1894 regexp = re.compile(pattern, reflags)
1894 regexp = re.compile(pattern, reflags)
1895 except re.error, inst:
1895 except re.error, inst:
1896 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1896 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1897 return 1
1897 return 1
1898 sep, eol = ':', '\n'
1898 sep, eol = ':', '\n'
1899 if opts.get('print0'):
1899 if opts.get('print0'):
1900 sep = eol = '\0'
1900 sep = eol = '\0'
1901
1901
1902 getfile = util.lrucachefunc(repo.file)
1902 getfile = util.lrucachefunc(repo.file)
1903
1903
1904 def matchlines(body):
1904 def matchlines(body):
1905 begin = 0
1905 begin = 0
1906 linenum = 0
1906 linenum = 0
1907 while True:
1907 while True:
1908 match = regexp.search(body, begin)
1908 match = regexp.search(body, begin)
1909 if not match:
1909 if not match:
1910 break
1910 break
1911 mstart, mend = match.span()
1911 mstart, mend = match.span()
1912 linenum += body.count('\n', begin, mstart) + 1
1912 linenum += body.count('\n', begin, mstart) + 1
1913 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1913 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1914 begin = body.find('\n', mend) + 1 or len(body)
1914 begin = body.find('\n', mend) + 1 or len(body)
1915 lend = begin - 1
1915 lend = begin - 1
1916 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1916 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1917
1917
1918 class linestate(object):
1918 class linestate(object):
1919 def __init__(self, line, linenum, colstart, colend):
1919 def __init__(self, line, linenum, colstart, colend):
1920 self.line = line
1920 self.line = line
1921 self.linenum = linenum
1921 self.linenum = linenum
1922 self.colstart = colstart
1922 self.colstart = colstart
1923 self.colend = colend
1923 self.colend = colend
1924
1924
1925 def __hash__(self):
1925 def __hash__(self):
1926 return hash((self.linenum, self.line))
1926 return hash((self.linenum, self.line))
1927
1927
1928 def __eq__(self, other):
1928 def __eq__(self, other):
1929 return self.line == other.line
1929 return self.line == other.line
1930
1930
1931 matches = {}
1931 matches = {}
1932 copies = {}
1932 copies = {}
1933 def grepbody(fn, rev, body):
1933 def grepbody(fn, rev, body):
1934 matches[rev].setdefault(fn, [])
1934 matches[rev].setdefault(fn, [])
1935 m = matches[rev][fn]
1935 m = matches[rev][fn]
1936 for lnum, cstart, cend, line in matchlines(body):
1936 for lnum, cstart, cend, line in matchlines(body):
1937 s = linestate(line, lnum, cstart, cend)
1937 s = linestate(line, lnum, cstart, cend)
1938 m.append(s)
1938 m.append(s)
1939
1939
1940 def difflinestates(a, b):
1940 def difflinestates(a, b):
1941 sm = difflib.SequenceMatcher(None, a, b)
1941 sm = difflib.SequenceMatcher(None, a, b)
1942 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1942 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1943 if tag == 'insert':
1943 if tag == 'insert':
1944 for i in xrange(blo, bhi):
1944 for i in xrange(blo, bhi):
1945 yield ('+', b[i])
1945 yield ('+', b[i])
1946 elif tag == 'delete':
1946 elif tag == 'delete':
1947 for i in xrange(alo, ahi):
1947 for i in xrange(alo, ahi):
1948 yield ('-', a[i])
1948 yield ('-', a[i])
1949 elif tag == 'replace':
1949 elif tag == 'replace':
1950 for i in xrange(alo, ahi):
1950 for i in xrange(alo, ahi):
1951 yield ('-', a[i])
1951 yield ('-', a[i])
1952 for i in xrange(blo, bhi):
1952 for i in xrange(blo, bhi):
1953 yield ('+', b[i])
1953 yield ('+', b[i])
1954
1954
1955 def display(fn, ctx, pstates, states):
1955 def display(fn, ctx, pstates, states):
1956 rev = ctx.rev()
1956 rev = ctx.rev()
1957 datefunc = ui.quiet and util.shortdate or util.datestr
1957 datefunc = ui.quiet and util.shortdate or util.datestr
1958 found = False
1958 found = False
1959 filerevmatches = {}
1959 filerevmatches = {}
1960 def binary():
1960 def binary():
1961 flog = getfile(fn)
1961 flog = getfile(fn)
1962 return util.binary(flog.read(ctx.filenode(fn)))
1962 return util.binary(flog.read(ctx.filenode(fn)))
1963
1963
1964 if opts.get('all'):
1964 if opts.get('all'):
1965 iter = difflinestates(pstates, states)
1965 iter = difflinestates(pstates, states)
1966 else:
1966 else:
1967 iter = [('', l) for l in states]
1967 iter = [('', l) for l in states]
1968 for change, l in iter:
1968 for change, l in iter:
1969 cols = [fn, str(rev)]
1969 cols = [fn, str(rev)]
1970 before, match, after = None, None, None
1970 before, match, after = None, None, None
1971 if opts.get('line_number'):
1971 if opts.get('line_number'):
1972 cols.append(str(l.linenum))
1972 cols.append(str(l.linenum))
1973 if opts.get('all'):
1973 if opts.get('all'):
1974 cols.append(change)
1974 cols.append(change)
1975 if opts.get('user'):
1975 if opts.get('user'):
1976 cols.append(ui.shortuser(ctx.user()))
1976 cols.append(ui.shortuser(ctx.user()))
1977 if opts.get('date'):
1977 if opts.get('date'):
1978 cols.append(datefunc(ctx.date()))
1978 cols.append(datefunc(ctx.date()))
1979 if opts.get('files_with_matches'):
1979 if opts.get('files_with_matches'):
1980 c = (fn, rev)
1980 c = (fn, rev)
1981 if c in filerevmatches:
1981 if c in filerevmatches:
1982 continue
1982 continue
1983 filerevmatches[c] = 1
1983 filerevmatches[c] = 1
1984 else:
1984 else:
1985 before = l.line[:l.colstart]
1985 before = l.line[:l.colstart]
1986 match = l.line[l.colstart:l.colend]
1986 match = l.line[l.colstart:l.colend]
1987 after = l.line[l.colend:]
1987 after = l.line[l.colend:]
1988 ui.write(sep.join(cols))
1988 ui.write(sep.join(cols))
1989 if before is not None:
1989 if before is not None:
1990 if not opts.get('text') and binary():
1990 if not opts.get('text') and binary():
1991 ui.write(sep + " Binary file matches")
1991 ui.write(sep + " Binary file matches")
1992 else:
1992 else:
1993 ui.write(sep + before)
1993 ui.write(sep + before)
1994 ui.write(match, label='grep.match')
1994 ui.write(match, label='grep.match')
1995 ui.write(after)
1995 ui.write(after)
1996 ui.write(eol)
1996 ui.write(eol)
1997 found = True
1997 found = True
1998 return found
1998 return found
1999
1999
2000 skip = {}
2000 skip = {}
2001 revfiles = {}
2001 revfiles = {}
2002 matchfn = cmdutil.match(repo, pats, opts)
2002 matchfn = cmdutil.match(repo, pats, opts)
2003 found = False
2003 found = False
2004 follow = opts.get('follow')
2004 follow = opts.get('follow')
2005
2005
2006 def prep(ctx, fns):
2006 def prep(ctx, fns):
2007 rev = ctx.rev()
2007 rev = ctx.rev()
2008 pctx = ctx.p1()
2008 pctx = ctx.p1()
2009 parent = pctx.rev()
2009 parent = pctx.rev()
2010 matches.setdefault(rev, {})
2010 matches.setdefault(rev, {})
2011 matches.setdefault(parent, {})
2011 matches.setdefault(parent, {})
2012 files = revfiles.setdefault(rev, [])
2012 files = revfiles.setdefault(rev, [])
2013 for fn in fns:
2013 for fn in fns:
2014 flog = getfile(fn)
2014 flog = getfile(fn)
2015 try:
2015 try:
2016 fnode = ctx.filenode(fn)
2016 fnode = ctx.filenode(fn)
2017 except error.LookupError:
2017 except error.LookupError:
2018 continue
2018 continue
2019
2019
2020 copied = flog.renamed(fnode)
2020 copied = flog.renamed(fnode)
2021 copy = follow and copied and copied[0]
2021 copy = follow and copied and copied[0]
2022 if copy:
2022 if copy:
2023 copies.setdefault(rev, {})[fn] = copy
2023 copies.setdefault(rev, {})[fn] = copy
2024 if fn in skip:
2024 if fn in skip:
2025 if copy:
2025 if copy:
2026 skip[copy] = True
2026 skip[copy] = True
2027 continue
2027 continue
2028 files.append(fn)
2028 files.append(fn)
2029
2029
2030 if fn not in matches[rev]:
2030 if fn not in matches[rev]:
2031 grepbody(fn, rev, flog.read(fnode))
2031 grepbody(fn, rev, flog.read(fnode))
2032
2032
2033 pfn = copy or fn
2033 pfn = copy or fn
2034 if pfn not in matches[parent]:
2034 if pfn not in matches[parent]:
2035 try:
2035 try:
2036 fnode = pctx.filenode(pfn)
2036 fnode = pctx.filenode(pfn)
2037 grepbody(pfn, parent, flog.read(fnode))
2037 grepbody(pfn, parent, flog.read(fnode))
2038 except error.LookupError:
2038 except error.LookupError:
2039 pass
2039 pass
2040
2040
2041 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2041 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2042 rev = ctx.rev()
2042 rev = ctx.rev()
2043 parent = ctx.p1().rev()
2043 parent = ctx.p1().rev()
2044 for fn in sorted(revfiles.get(rev, [])):
2044 for fn in sorted(revfiles.get(rev, [])):
2045 states = matches[rev][fn]
2045 states = matches[rev][fn]
2046 copy = copies.get(rev, {}).get(fn)
2046 copy = copies.get(rev, {}).get(fn)
2047 if fn in skip:
2047 if fn in skip:
2048 if copy:
2048 if copy:
2049 skip[copy] = True
2049 skip[copy] = True
2050 continue
2050 continue
2051 pstates = matches.get(parent, {}).get(copy or fn, [])
2051 pstates = matches.get(parent, {}).get(copy or fn, [])
2052 if pstates or states:
2052 if pstates or states:
2053 r = display(fn, ctx, pstates, states)
2053 r = display(fn, ctx, pstates, states)
2054 found = found or r
2054 found = found or r
2055 if r and not opts.get('all'):
2055 if r and not opts.get('all'):
2056 skip[fn] = True
2056 skip[fn] = True
2057 if copy:
2057 if copy:
2058 skip[copy] = True
2058 skip[copy] = True
2059 del matches[rev]
2059 del matches[rev]
2060 del revfiles[rev]
2060 del revfiles[rev]
2061
2061
2062 return not found
2062 return not found
2063
2063
2064 def heads(ui, repo, *branchrevs, **opts):
2064 def heads(ui, repo, *branchrevs, **opts):
2065 """show current repository heads or show branch heads
2065 """show current repository heads or show branch heads
2066
2066
2067 With no arguments, show all repository branch heads.
2067 With no arguments, show all repository branch heads.
2068
2068
2069 Repository "heads" are changesets with no child changesets. They are
2069 Repository "heads" are changesets with no child changesets. They are
2070 where development generally takes place and are the usual targets
2070 where development generally takes place and are the usual targets
2071 for update and merge operations. Branch heads are changesets that have
2071 for update and merge operations. Branch heads are changesets that have
2072 no child changeset on the same branch.
2072 no child changeset on the same branch.
2073
2073
2074 If one or more REVs are given, only branch heads on the branches
2074 If one or more REVs are given, only branch heads on the branches
2075 associated with the specified changesets are shown.
2075 associated with the specified changesets are shown.
2076
2076
2077 If -c/--closed is specified, also show branch heads marked closed
2077 If -c/--closed is specified, also show branch heads marked closed
2078 (see :hg:`commit --close-branch`).
2078 (see :hg:`commit --close-branch`).
2079
2079
2080 If STARTREV is specified, only those heads that are descendants of
2080 If STARTREV is specified, only those heads that are descendants of
2081 STARTREV will be displayed.
2081 STARTREV will be displayed.
2082
2082
2083 If -t/--topo is specified, named branch mechanics will be ignored and only
2083 If -t/--topo is specified, named branch mechanics will be ignored and only
2084 changesets without children will be shown.
2084 changesets without children will be shown.
2085
2085
2086 Returns 0 if matching heads are found, 1 if not.
2086 Returns 0 if matching heads are found, 1 if not.
2087 """
2087 """
2088
2088
2089 start = None
2089 start = None
2090 if 'rev' in opts:
2090 if 'rev' in opts:
2091 start = cmdutil.revsingle(repo, opts['rev'], None).node()
2091 start = cmdutil.revsingle(repo, opts['rev'], None).node()
2092
2092
2093 if opts.get('topo'):
2093 if opts.get('topo'):
2094 heads = [repo[h] for h in repo.heads(start)]
2094 heads = [repo[h] for h in repo.heads(start)]
2095 else:
2095 else:
2096 heads = []
2096 heads = []
2097 for b, ls in repo.branchmap().iteritems():
2097 for b, ls in repo.branchmap().iteritems():
2098 if start is None:
2098 if start is None:
2099 heads += [repo[h] for h in ls]
2099 heads += [repo[h] for h in ls]
2100 continue
2100 continue
2101 startrev = repo.changelog.rev(start)
2101 startrev = repo.changelog.rev(start)
2102 descendants = set(repo.changelog.descendants(startrev))
2102 descendants = set(repo.changelog.descendants(startrev))
2103 descendants.add(startrev)
2103 descendants.add(startrev)
2104 rev = repo.changelog.rev
2104 rev = repo.changelog.rev
2105 heads += [repo[h] for h in ls if rev(h) in descendants]
2105 heads += [repo[h] for h in ls if rev(h) in descendants]
2106
2106
2107 if branchrevs:
2107 if branchrevs:
2108 branches = set(repo[br].branch() for br in branchrevs)
2108 branches = set(repo[br].branch() for br in branchrevs)
2109 heads = [h for h in heads if h.branch() in branches]
2109 heads = [h for h in heads if h.branch() in branches]
2110
2110
2111 if not opts.get('closed'):
2111 if not opts.get('closed'):
2112 heads = [h for h in heads if not h.extra().get('close')]
2112 heads = [h for h in heads if not h.extra().get('close')]
2113
2113
2114 if opts.get('active') and branchrevs:
2114 if opts.get('active') and branchrevs:
2115 dagheads = repo.heads(start)
2115 dagheads = repo.heads(start)
2116 heads = [h for h in heads if h.node() in dagheads]
2116 heads = [h for h in heads if h.node() in dagheads]
2117
2117
2118 if branchrevs:
2118 if branchrevs:
2119 haveheads = set(h.branch() for h in heads)
2119 haveheads = set(h.branch() for h in heads)
2120 if branches - haveheads:
2120 if branches - haveheads:
2121 headless = ', '.join(b for b in branches - haveheads)
2121 headless = ', '.join(b for b in branches - haveheads)
2122 msg = _('no open branch heads found on branches %s')
2122 msg = _('no open branch heads found on branches %s')
2123 if opts.get('rev'):
2123 if opts.get('rev'):
2124 msg += _(' (started at %s)' % opts['rev'])
2124 msg += _(' (started at %s)' % opts['rev'])
2125 ui.warn((msg + '\n') % headless)
2125 ui.warn((msg + '\n') % headless)
2126
2126
2127 if not heads:
2127 if not heads:
2128 return 1
2128 return 1
2129
2129
2130 heads = sorted(heads, key=lambda x: -x.rev())
2130 heads = sorted(heads, key=lambda x: -x.rev())
2131 displayer = cmdutil.show_changeset(ui, repo, opts)
2131 displayer = cmdutil.show_changeset(ui, repo, opts)
2132 for ctx in heads:
2132 for ctx in heads:
2133 displayer.show(ctx)
2133 displayer.show(ctx)
2134 displayer.close()
2134 displayer.close()
2135
2135
2136 def help_(ui, name=None, with_version=False, unknowncmd=False, full=True):
2136 def help_(ui, name=None, with_version=False, unknowncmd=False, full=True, **opts):
2137 """show help for a given topic or a help overview
2137 """show help for a given topic or a help overview
2138
2138
2139 With no arguments, print a list of commands with short help messages.
2139 With no arguments, print a list of commands with short help messages.
2140
2140
2141 Given a topic, extension, or command name, print help for that
2141 Given a topic, extension, or command name, print help for that
2142 topic.
2142 topic.
2143
2143
2144 Returns 0 if successful.
2144 Returns 0 if successful.
2145 """
2145 """
2146 option_lists = []
2146 option_lists = []
2147 textwidth = min(ui.termwidth(), 80) - 2
2147 textwidth = min(ui.termwidth(), 80) - 2
2148
2148
2149 def addglobalopts(aliases):
2149 def addglobalopts(aliases):
2150 if ui.verbose:
2150 if ui.verbose:
2151 option_lists.append((_("global options:"), globalopts))
2151 option_lists.append((_("global options:"), globalopts))
2152 if name == 'shortlist':
2152 if name == 'shortlist':
2153 option_lists.append((_('use "hg help" for the full list '
2153 option_lists.append((_('use "hg help" for the full list '
2154 'of commands'), ()))
2154 'of commands'), ()))
2155 else:
2155 else:
2156 if name == 'shortlist':
2156 if name == 'shortlist':
2157 msg = _('use "hg help" for the full list of commands '
2157 msg = _('use "hg help" for the full list of commands '
2158 'or "hg -v" for details')
2158 'or "hg -v" for details')
2159 elif name and not full:
2159 elif name and not full:
2160 msg = _('use "hg help %s" to show the full help text' % name)
2160 msg = _('use "hg help %s" to show the full help text' % name)
2161 elif aliases:
2161 elif aliases:
2162 msg = _('use "hg -v help%s" to show builtin aliases and '
2162 msg = _('use "hg -v help%s" to show builtin aliases and '
2163 'global options') % (name and " " + name or "")
2163 'global options') % (name and " " + name or "")
2164 else:
2164 else:
2165 msg = _('use "hg -v help %s" to show global options') % name
2165 msg = _('use "hg -v help %s" to show global options') % name
2166 option_lists.append((msg, ()))
2166 option_lists.append((msg, ()))
2167
2167
2168 def helpcmd(name):
2168 def helpcmd(name):
2169 if with_version:
2169 if with_version:
2170 version_(ui)
2170 version_(ui)
2171 ui.write('\n')
2171 ui.write('\n')
2172
2172
2173 try:
2173 try:
2174 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
2174 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
2175 except error.AmbiguousCommand, inst:
2175 except error.AmbiguousCommand, inst:
2176 # py3k fix: except vars can't be used outside the scope of the
2176 # py3k fix: except vars can't be used outside the scope of the
2177 # except block, nor can be used inside a lambda. python issue4617
2177 # except block, nor can be used inside a lambda. python issue4617
2178 prefix = inst.args[0]
2178 prefix = inst.args[0]
2179 select = lambda c: c.lstrip('^').startswith(prefix)
2179 select = lambda c: c.lstrip('^').startswith(prefix)
2180 helplist(_('list of commands:\n\n'), select)
2180 helplist(_('list of commands:\n\n'), select)
2181 return
2181 return
2182
2182
2183 # check if it's an invalid alias and display its error if it is
2183 # check if it's an invalid alias and display its error if it is
2184 if getattr(entry[0], 'badalias', False):
2184 if getattr(entry[0], 'badalias', False):
2185 if not unknowncmd:
2185 if not unknowncmd:
2186 entry[0](ui)
2186 entry[0](ui)
2187 return
2187 return
2188
2188
2189 # synopsis
2189 # synopsis
2190 if len(entry) > 2:
2190 if len(entry) > 2:
2191 if entry[2].startswith('hg'):
2191 if entry[2].startswith('hg'):
2192 ui.write("%s\n" % entry[2])
2192 ui.write("%s\n" % entry[2])
2193 else:
2193 else:
2194 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
2194 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
2195 else:
2195 else:
2196 ui.write('hg %s\n' % aliases[0])
2196 ui.write('hg %s\n' % aliases[0])
2197
2197
2198 # aliases
2198 # aliases
2199 if full and not ui.quiet and len(aliases) > 1:
2199 if full and not ui.quiet and len(aliases) > 1:
2200 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
2200 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
2201
2201
2202 # description
2202 # description
2203 doc = gettext(entry[0].__doc__)
2203 doc = gettext(entry[0].__doc__)
2204 if not doc:
2204 if not doc:
2205 doc = _("(no help text available)")
2205 doc = _("(no help text available)")
2206 if hasattr(entry[0], 'definition'): # aliased command
2206 if hasattr(entry[0], 'definition'): # aliased command
2207 if entry[0].definition.startswith('!'): # shell alias
2207 if entry[0].definition.startswith('!'): # shell alias
2208 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
2208 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
2209 else:
2209 else:
2210 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
2210 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
2211 if ui.quiet or not full:
2211 if ui.quiet or not full:
2212 doc = doc.splitlines()[0]
2212 doc = doc.splitlines()[0]
2213 keep = ui.verbose and ['verbose'] or []
2213 keep = ui.verbose and ['verbose'] or []
2214 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
2214 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
2215 ui.write("\n%s\n" % formatted)
2215 ui.write("\n%s\n" % formatted)
2216 if pruned:
2216 if pruned:
2217 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
2217 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
2218
2218
2219 if not ui.quiet:
2219 if not ui.quiet:
2220 # options
2220 # options
2221 if entry[1]:
2221 if entry[1]:
2222 option_lists.append((_("options:\n"), entry[1]))
2222 option_lists.append((_("options:\n"), entry[1]))
2223
2223
2224 addglobalopts(False)
2224 addglobalopts(False)
2225
2225
2226 def helplist(header, select=None):
2226 def helplist(header, select=None):
2227 h = {}
2227 h = {}
2228 cmds = {}
2228 cmds = {}
2229 for c, e in table.iteritems():
2229 for c, e in table.iteritems():
2230 f = c.split("|", 1)[0]
2230 f = c.split("|", 1)[0]
2231 if select and not select(f):
2231 if select and not select(f):
2232 continue
2232 continue
2233 if (not select and name != 'shortlist' and
2233 if (not select and name != 'shortlist' and
2234 e[0].__module__ != __name__):
2234 e[0].__module__ != __name__):
2235 continue
2235 continue
2236 if name == "shortlist" and not f.startswith("^"):
2236 if name == "shortlist" and not f.startswith("^"):
2237 continue
2237 continue
2238 f = f.lstrip("^")
2238 f = f.lstrip("^")
2239 if not ui.debugflag and f.startswith("debug"):
2239 if not ui.debugflag and f.startswith("debug"):
2240 continue
2240 continue
2241 doc = e[0].__doc__
2241 doc = e[0].__doc__
2242 if doc and 'DEPRECATED' in doc and not ui.verbose:
2242 if doc and 'DEPRECATED' in doc and not ui.verbose:
2243 continue
2243 continue
2244 doc = gettext(doc)
2244 doc = gettext(doc)
2245 if not doc:
2245 if not doc:
2246 doc = _("(no help text available)")
2246 doc = _("(no help text available)")
2247 h[f] = doc.splitlines()[0].rstrip()
2247 h[f] = doc.splitlines()[0].rstrip()
2248 cmds[f] = c.lstrip("^")
2248 cmds[f] = c.lstrip("^")
2249
2249
2250 if not h:
2250 if not h:
2251 ui.status(_('no commands defined\n'))
2251 ui.status(_('no commands defined\n'))
2252 return
2252 return
2253
2253
2254 ui.status(header)
2254 ui.status(header)
2255 fns = sorted(h)
2255 fns = sorted(h)
2256 m = max(map(len, fns))
2256 m = max(map(len, fns))
2257 for f in fns:
2257 for f in fns:
2258 if ui.verbose:
2258 if ui.verbose:
2259 commands = cmds[f].replace("|",", ")
2259 commands = cmds[f].replace("|",", ")
2260 ui.write(" %s:\n %s\n"%(commands, h[f]))
2260 ui.write(" %s:\n %s\n"%(commands, h[f]))
2261 else:
2261 else:
2262 ui.write('%s\n' % (util.wrap(h[f], textwidth,
2262 ui.write('%s\n' % (util.wrap(h[f], textwidth,
2263 initindent=' %-*s ' % (m, f),
2263 initindent=' %-*s ' % (m, f),
2264 hangindent=' ' * (m + 4))))
2264 hangindent=' ' * (m + 4))))
2265
2265
2266 if not ui.quiet:
2266 if not ui.quiet:
2267 addglobalopts(True)
2267 addglobalopts(True)
2268
2268
2269 def helptopic(name):
2269 def helptopic(name):
2270 for names, header, doc in help.helptable:
2270 for names, header, doc in help.helptable:
2271 if name in names:
2271 if name in names:
2272 break
2272 break
2273 else:
2273 else:
2274 raise error.UnknownCommand(name)
2274 raise error.UnknownCommand(name)
2275
2275
2276 # description
2276 # description
2277 if not doc:
2277 if not doc:
2278 doc = _("(no help text available)")
2278 doc = _("(no help text available)")
2279 if hasattr(doc, '__call__'):
2279 if hasattr(doc, '__call__'):
2280 doc = doc()
2280 doc = doc()
2281
2281
2282 ui.write("%s\n\n" % header)
2282 ui.write("%s\n\n" % header)
2283 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
2283 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
2284
2284
2285 def helpext(name):
2285 def helpext(name):
2286 try:
2286 try:
2287 mod = extensions.find(name)
2287 mod = extensions.find(name)
2288 doc = gettext(mod.__doc__) or _('no help text available')
2288 doc = gettext(mod.__doc__) or _('no help text available')
2289 except KeyError:
2289 except KeyError:
2290 mod = None
2290 mod = None
2291 doc = extensions.disabledext(name)
2291 doc = extensions.disabledext(name)
2292 if not doc:
2292 if not doc:
2293 raise error.UnknownCommand(name)
2293 raise error.UnknownCommand(name)
2294
2294
2295 if '\n' not in doc:
2295 if '\n' not in doc:
2296 head, tail = doc, ""
2296 head, tail = doc, ""
2297 else:
2297 else:
2298 head, tail = doc.split('\n', 1)
2298 head, tail = doc.split('\n', 1)
2299 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
2299 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
2300 if tail:
2300 if tail:
2301 ui.write(minirst.format(tail, textwidth))
2301 ui.write(minirst.format(tail, textwidth))
2302 ui.status('\n\n')
2302 ui.status('\n\n')
2303
2303
2304 if mod:
2304 if mod:
2305 try:
2305 try:
2306 ct = mod.cmdtable
2306 ct = mod.cmdtable
2307 except AttributeError:
2307 except AttributeError:
2308 ct = {}
2308 ct = {}
2309 modcmds = set([c.split('|', 1)[0] for c in ct])
2309 modcmds = set([c.split('|', 1)[0] for c in ct])
2310 helplist(_('list of commands:\n\n'), modcmds.__contains__)
2310 helplist(_('list of commands:\n\n'), modcmds.__contains__)
2311 else:
2311 else:
2312 ui.write(_('use "hg help extensions" for information on enabling '
2312 ui.write(_('use "hg help extensions" for information on enabling '
2313 'extensions\n'))
2313 'extensions\n'))
2314
2314
2315 def helpextcmd(name):
2315 def helpextcmd(name):
2316 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
2316 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
2317 doc = gettext(mod.__doc__).splitlines()[0]
2317 doc = gettext(mod.__doc__).splitlines()[0]
2318
2318
2319 msg = help.listexts(_("'%s' is provided by the following "
2319 msg = help.listexts(_("'%s' is provided by the following "
2320 "extension:") % cmd, {ext: doc}, len(ext),
2320 "extension:") % cmd, {ext: doc}, len(ext),
2321 indent=4)
2321 indent=4)
2322 ui.write(minirst.format(msg, textwidth))
2322 ui.write(minirst.format(msg, textwidth))
2323 ui.write('\n\n')
2323 ui.write('\n\n')
2324 ui.write(_('use "hg help extensions" for information on enabling '
2324 ui.write(_('use "hg help extensions" for information on enabling '
2325 'extensions\n'))
2325 'extensions\n'))
2326
2326
2327 help.addtopichook('revsets', revset.makedoc)
2327 help.addtopichook('revsets', revset.makedoc)
2328 help.addtopichook('templates', templatekw.makedoc)
2328 help.addtopichook('templates', templatekw.makedoc)
2329 help.addtopichook('templates', templatefilters.makedoc)
2329 help.addtopichook('templates', templatefilters.makedoc)
2330
2330
2331 if name and name != 'shortlist':
2331 if name and name != 'shortlist':
2332 i = None
2332 i = None
2333 if unknowncmd:
2333 if unknowncmd:
2334 queries = (helpextcmd,)
2334 queries = (helpextcmd,)
2335 elif opts.get('extension'):
2336 queries = (helpext,)
2335 else:
2337 else:
2336 queries = (helptopic, helpcmd, helpext, helpextcmd)
2338 queries = (helptopic, helpcmd, helpext, helpextcmd)
2337 for f in queries:
2339 for f in queries:
2338 try:
2340 try:
2339 f(name)
2341 f(name)
2340 i = None
2342 i = None
2341 break
2343 break
2342 except error.UnknownCommand, inst:
2344 except error.UnknownCommand, inst:
2343 i = inst
2345 i = inst
2344 if i:
2346 if i:
2345 raise i
2347 raise i
2346
2348
2347 else:
2349 else:
2348 # program name
2350 # program name
2349 if ui.verbose or with_version:
2351 if ui.verbose or with_version:
2350 version_(ui)
2352 version_(ui)
2351 else:
2353 else:
2352 ui.status(_("Mercurial Distributed SCM\n"))
2354 ui.status(_("Mercurial Distributed SCM\n"))
2353 ui.status('\n')
2355 ui.status('\n')
2354
2356
2355 # list of commands
2357 # list of commands
2356 if name == "shortlist":
2358 if name == "shortlist":
2357 header = _('basic commands:\n\n')
2359 header = _('basic commands:\n\n')
2358 else:
2360 else:
2359 header = _('list of commands:\n\n')
2361 header = _('list of commands:\n\n')
2360
2362
2361 helplist(header)
2363 helplist(header)
2362 if name != 'shortlist':
2364 if name != 'shortlist':
2363 exts, maxlength = extensions.enabled()
2365 exts, maxlength = extensions.enabled()
2364 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2366 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2365 if text:
2367 if text:
2366 ui.write("\n%s\n" % minirst.format(text, textwidth))
2368 ui.write("\n%s\n" % minirst.format(text, textwidth))
2367
2369
2368 # list all option lists
2370 # list all option lists
2369 opt_output = []
2371 opt_output = []
2370 multioccur = False
2372 multioccur = False
2371 for title, options in option_lists:
2373 for title, options in option_lists:
2372 opt_output.append(("\n%s" % title, None))
2374 opt_output.append(("\n%s" % title, None))
2373 for option in options:
2375 for option in options:
2374 if len(option) == 5:
2376 if len(option) == 5:
2375 shortopt, longopt, default, desc, optlabel = option
2377 shortopt, longopt, default, desc, optlabel = option
2376 else:
2378 else:
2377 shortopt, longopt, default, desc = option
2379 shortopt, longopt, default, desc = option
2378 optlabel = _("VALUE") # default label
2380 optlabel = _("VALUE") # default label
2379
2381
2380 if _("DEPRECATED") in desc and not ui.verbose:
2382 if _("DEPRECATED") in desc and not ui.verbose:
2381 continue
2383 continue
2382 if isinstance(default, list):
2384 if isinstance(default, list):
2383 numqualifier = " %s [+]" % optlabel
2385 numqualifier = " %s [+]" % optlabel
2384 multioccur = True
2386 multioccur = True
2385 elif (default is not None) and not isinstance(default, bool):
2387 elif (default is not None) and not isinstance(default, bool):
2386 numqualifier = " %s" % optlabel
2388 numqualifier = " %s" % optlabel
2387 else:
2389 else:
2388 numqualifier = ""
2390 numqualifier = ""
2389 opt_output.append(("%2s%s" %
2391 opt_output.append(("%2s%s" %
2390 (shortopt and "-%s" % shortopt,
2392 (shortopt and "-%s" % shortopt,
2391 longopt and " --%s%s" %
2393 longopt and " --%s%s" %
2392 (longopt, numqualifier)),
2394 (longopt, numqualifier)),
2393 "%s%s" % (desc,
2395 "%s%s" % (desc,
2394 default
2396 default
2395 and _(" (default: %s)") % default
2397 and _(" (default: %s)") % default
2396 or "")))
2398 or "")))
2397 if multioccur:
2399 if multioccur:
2398 msg = _("\n[+] marked option can be specified multiple times")
2400 msg = _("\n[+] marked option can be specified multiple times")
2399 if ui.verbose and name != 'shortlist':
2401 if ui.verbose and name != 'shortlist':
2400 opt_output.append((msg, None))
2402 opt_output.append((msg, None))
2401 else:
2403 else:
2402 opt_output.insert(-1, (msg, None))
2404 opt_output.insert(-1, (msg, None))
2403
2405
2404 if not name:
2406 if not name:
2405 ui.write(_("\nadditional help topics:\n\n"))
2407 ui.write(_("\nadditional help topics:\n\n"))
2406 topics = []
2408 topics = []
2407 for names, header, doc in help.helptable:
2409 for names, header, doc in help.helptable:
2408 topics.append((sorted(names, key=len, reverse=True)[0], header))
2410 topics.append((sorted(names, key=len, reverse=True)[0], header))
2409 topics_len = max([len(s[0]) for s in topics])
2411 topics_len = max([len(s[0]) for s in topics])
2410 for t, desc in topics:
2412 for t, desc in topics:
2411 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2413 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2412
2414
2413 if opt_output:
2415 if opt_output:
2414 colwidth = encoding.colwidth
2416 colwidth = encoding.colwidth
2415 # normalize: (opt or message, desc or None, width of opt)
2417 # normalize: (opt or message, desc or None, width of opt)
2416 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2418 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2417 for opt, desc in opt_output]
2419 for opt, desc in opt_output]
2418 hanging = max([e[2] for e in entries])
2420 hanging = max([e[2] for e in entries])
2419 for opt, desc, width in entries:
2421 for opt, desc, width in entries:
2420 if desc:
2422 if desc:
2421 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2423 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2422 hangindent = ' ' * (hanging + 3)
2424 hangindent = ' ' * (hanging + 3)
2423 ui.write('%s\n' % (util.wrap(desc, textwidth,
2425 ui.write('%s\n' % (util.wrap(desc, textwidth,
2424 initindent=initindent,
2426 initindent=initindent,
2425 hangindent=hangindent)))
2427 hangindent=hangindent)))
2426 else:
2428 else:
2427 ui.write("%s\n" % opt)
2429 ui.write("%s\n" % opt)
2428
2430
2429 def identify(ui, repo, source=None, rev=None,
2431 def identify(ui, repo, source=None, rev=None,
2430 num=None, id=None, branch=None, tags=None, bookmarks=None):
2432 num=None, id=None, branch=None, tags=None, bookmarks=None):
2431 """identify the working copy or specified revision
2433 """identify the working copy or specified revision
2432
2434
2433 Print a summary identifying the repository state at REV using one or
2435 Print a summary identifying the repository state at REV using one or
2434 two parent hash identifiers, followed by a "+" if the working
2436 two parent hash identifiers, followed by a "+" if the working
2435 directory has uncommitted changes, the branch name (if not default),
2437 directory has uncommitted changes, the branch name (if not default),
2436 a list of tags, and a list of bookmarks.
2438 a list of tags, and a list of bookmarks.
2437
2439
2438 When REV is not given, print a summary of the current state of the
2440 When REV is not given, print a summary of the current state of the
2439 repository.
2441 repository.
2440
2442
2441 Specifying a path to a repository root or Mercurial bundle will
2443 Specifying a path to a repository root or Mercurial bundle will
2442 cause lookup to operate on that repository/bundle.
2444 cause lookup to operate on that repository/bundle.
2443
2445
2444 Returns 0 if successful.
2446 Returns 0 if successful.
2445 """
2447 """
2446
2448
2447 if not repo and not source:
2449 if not repo and not source:
2448 raise util.Abort(_("there is no Mercurial repository here "
2450 raise util.Abort(_("there is no Mercurial repository here "
2449 "(.hg not found)"))
2451 "(.hg not found)"))
2450
2452
2451 hexfunc = ui.debugflag and hex or short
2453 hexfunc = ui.debugflag and hex or short
2452 default = not (num or id or branch or tags or bookmarks)
2454 default = not (num or id or branch or tags or bookmarks)
2453 output = []
2455 output = []
2454 revs = []
2456 revs = []
2455
2457
2456 if source:
2458 if source:
2457 source, branches = hg.parseurl(ui.expandpath(source))
2459 source, branches = hg.parseurl(ui.expandpath(source))
2458 repo = hg.repository(ui, source)
2460 repo = hg.repository(ui, source)
2459 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2461 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2460
2462
2461 if not repo.local():
2463 if not repo.local():
2462 if num or branch or tags:
2464 if num or branch or tags:
2463 raise util.Abort(
2465 raise util.Abort(
2464 _("can't query remote revision number, branch, or tags"))
2466 _("can't query remote revision number, branch, or tags"))
2465 if not rev and revs:
2467 if not rev and revs:
2466 rev = revs[0]
2468 rev = revs[0]
2467 if not rev:
2469 if not rev:
2468 rev = "tip"
2470 rev = "tip"
2469
2471
2470 remoterev = repo.lookup(rev)
2472 remoterev = repo.lookup(rev)
2471 if default or id:
2473 if default or id:
2472 output = [hexfunc(remoterev)]
2474 output = [hexfunc(remoterev)]
2473
2475
2474 def getbms():
2476 def getbms():
2475 bms = []
2477 bms = []
2476
2478
2477 if 'bookmarks' in repo.listkeys('namespaces'):
2479 if 'bookmarks' in repo.listkeys('namespaces'):
2478 hexremoterev = hex(remoterev)
2480 hexremoterev = hex(remoterev)
2479 bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
2481 bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
2480 if bmr == hexremoterev]
2482 if bmr == hexremoterev]
2481
2483
2482 return bms
2484 return bms
2483
2485
2484 if bookmarks:
2486 if bookmarks:
2485 output.extend(getbms())
2487 output.extend(getbms())
2486 elif default and not ui.quiet:
2488 elif default and not ui.quiet:
2487 # multiple bookmarks for a single parent separated by '/'
2489 # multiple bookmarks for a single parent separated by '/'
2488 bm = '/'.join(getbms())
2490 bm = '/'.join(getbms())
2489 if bm:
2491 if bm:
2490 output.append(bm)
2492 output.append(bm)
2491 else:
2493 else:
2492 if not rev:
2494 if not rev:
2493 ctx = repo[None]
2495 ctx = repo[None]
2494 parents = ctx.parents()
2496 parents = ctx.parents()
2495 changed = ""
2497 changed = ""
2496 if default or id or num:
2498 if default or id or num:
2497 changed = util.any(repo.status()) and "+" or ""
2499 changed = util.any(repo.status()) and "+" or ""
2498 if default or id:
2500 if default or id:
2499 output = ["%s%s" %
2501 output = ["%s%s" %
2500 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
2502 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
2501 if num:
2503 if num:
2502 output.append("%s%s" %
2504 output.append("%s%s" %
2503 ('+'.join([str(p.rev()) for p in parents]), changed))
2505 ('+'.join([str(p.rev()) for p in parents]), changed))
2504 else:
2506 else:
2505 ctx = cmdutil.revsingle(repo, rev)
2507 ctx = cmdutil.revsingle(repo, rev)
2506 if default or id:
2508 if default or id:
2507 output = [hexfunc(ctx.node())]
2509 output = [hexfunc(ctx.node())]
2508 if num:
2510 if num:
2509 output.append(str(ctx.rev()))
2511 output.append(str(ctx.rev()))
2510
2512
2511 if default and not ui.quiet:
2513 if default and not ui.quiet:
2512 b = ctx.branch()
2514 b = ctx.branch()
2513 if b != 'default':
2515 if b != 'default':
2514 output.append("(%s)" % b)
2516 output.append("(%s)" % b)
2515
2517
2516 # multiple tags for a single parent separated by '/'
2518 # multiple tags for a single parent separated by '/'
2517 t = '/'.join(ctx.tags())
2519 t = '/'.join(ctx.tags())
2518 if t:
2520 if t:
2519 output.append(t)
2521 output.append(t)
2520
2522
2521 # multiple bookmarks for a single parent separated by '/'
2523 # multiple bookmarks for a single parent separated by '/'
2522 bm = '/'.join(ctx.bookmarks())
2524 bm = '/'.join(ctx.bookmarks())
2523 if bm:
2525 if bm:
2524 output.append(bm)
2526 output.append(bm)
2525 else:
2527 else:
2526 if branch:
2528 if branch:
2527 output.append(ctx.branch())
2529 output.append(ctx.branch())
2528
2530
2529 if tags:
2531 if tags:
2530 output.extend(ctx.tags())
2532 output.extend(ctx.tags())
2531
2533
2532 if bookmarks:
2534 if bookmarks:
2533 output.extend(ctx.bookmarks())
2535 output.extend(ctx.bookmarks())
2534
2536
2535 ui.write("%s\n" % ' '.join(output))
2537 ui.write("%s\n" % ' '.join(output))
2536
2538
2537 def import_(ui, repo, patch1, *patches, **opts):
2539 def import_(ui, repo, patch1, *patches, **opts):
2538 """import an ordered set of patches
2540 """import an ordered set of patches
2539
2541
2540 Import a list of patches and commit them individually (unless
2542 Import a list of patches and commit them individually (unless
2541 --no-commit is specified).
2543 --no-commit is specified).
2542
2544
2543 If there are outstanding changes in the working directory, import
2545 If there are outstanding changes in the working directory, import
2544 will abort unless given the -f/--force flag.
2546 will abort unless given the -f/--force flag.
2545
2547
2546 You can import a patch straight from a mail message. Even patches
2548 You can import a patch straight from a mail message. Even patches
2547 as attachments work (to use the body part, it must have type
2549 as attachments work (to use the body part, it must have type
2548 text/plain or text/x-patch). From and Subject headers of email
2550 text/plain or text/x-patch). From and Subject headers of email
2549 message are used as default committer and commit message. All
2551 message are used as default committer and commit message. All
2550 text/plain body parts before first diff are added to commit
2552 text/plain body parts before first diff are added to commit
2551 message.
2553 message.
2552
2554
2553 If the imported patch was generated by :hg:`export`, user and
2555 If the imported patch was generated by :hg:`export`, user and
2554 description from patch override values from message headers and
2556 description from patch override values from message headers and
2555 body. Values given on command line with -m/--message and -u/--user
2557 body. Values given on command line with -m/--message and -u/--user
2556 override these.
2558 override these.
2557
2559
2558 If --exact is specified, import will set the working directory to
2560 If --exact is specified, import will set the working directory to
2559 the parent of each patch before applying it, and will abort if the
2561 the parent of each patch before applying it, and will abort if the
2560 resulting changeset has a different ID than the one recorded in
2562 resulting changeset has a different ID than the one recorded in
2561 the patch. This may happen due to character set problems or other
2563 the patch. This may happen due to character set problems or other
2562 deficiencies in the text patch format.
2564 deficiencies in the text patch format.
2563
2565
2564 With -s/--similarity, hg will attempt to discover renames and
2566 With -s/--similarity, hg will attempt to discover renames and
2565 copies in the patch in the same way as 'addremove'.
2567 copies in the patch in the same way as 'addremove'.
2566
2568
2567 To read a patch from standard input, use "-" as the patch name. If
2569 To read a patch from standard input, use "-" as the patch name. If
2568 a URL is specified, the patch will be downloaded from it.
2570 a URL is specified, the patch will be downloaded from it.
2569 See :hg:`help dates` for a list of formats valid for -d/--date.
2571 See :hg:`help dates` for a list of formats valid for -d/--date.
2570
2572
2571 Returns 0 on success.
2573 Returns 0 on success.
2572 """
2574 """
2573 patches = (patch1,) + patches
2575 patches = (patch1,) + patches
2574
2576
2575 date = opts.get('date')
2577 date = opts.get('date')
2576 if date:
2578 if date:
2577 opts['date'] = util.parsedate(date)
2579 opts['date'] = util.parsedate(date)
2578
2580
2579 try:
2581 try:
2580 sim = float(opts.get('similarity') or 0)
2582 sim = float(opts.get('similarity') or 0)
2581 except ValueError:
2583 except ValueError:
2582 raise util.Abort(_('similarity must be a number'))
2584 raise util.Abort(_('similarity must be a number'))
2583 if sim < 0 or sim > 100:
2585 if sim < 0 or sim > 100:
2584 raise util.Abort(_('similarity must be between 0 and 100'))
2586 raise util.Abort(_('similarity must be between 0 and 100'))
2585
2587
2586 if opts.get('exact') or not opts.get('force'):
2588 if opts.get('exact') or not opts.get('force'):
2587 cmdutil.bail_if_changed(repo)
2589 cmdutil.bail_if_changed(repo)
2588
2590
2589 d = opts["base"]
2591 d = opts["base"]
2590 strip = opts["strip"]
2592 strip = opts["strip"]
2591 wlock = lock = None
2593 wlock = lock = None
2592 msgs = []
2594 msgs = []
2593
2595
2594 def tryone(ui, hunk):
2596 def tryone(ui, hunk):
2595 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2597 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2596 patch.extract(ui, hunk)
2598 patch.extract(ui, hunk)
2597
2599
2598 if not tmpname:
2600 if not tmpname:
2599 return None
2601 return None
2600 commitid = _('to working directory')
2602 commitid = _('to working directory')
2601
2603
2602 try:
2604 try:
2603 cmdline_message = cmdutil.logmessage(opts)
2605 cmdline_message = cmdutil.logmessage(opts)
2604 if cmdline_message:
2606 if cmdline_message:
2605 # pickup the cmdline msg
2607 # pickup the cmdline msg
2606 message = cmdline_message
2608 message = cmdline_message
2607 elif message:
2609 elif message:
2608 # pickup the patch msg
2610 # pickup the patch msg
2609 message = message.strip()
2611 message = message.strip()
2610 else:
2612 else:
2611 # launch the editor
2613 # launch the editor
2612 message = None
2614 message = None
2613 ui.debug('message:\n%s\n' % message)
2615 ui.debug('message:\n%s\n' % message)
2614
2616
2615 wp = repo.parents()
2617 wp = repo.parents()
2616 if opts.get('exact'):
2618 if opts.get('exact'):
2617 if not nodeid or not p1:
2619 if not nodeid or not p1:
2618 raise util.Abort(_('not a Mercurial patch'))
2620 raise util.Abort(_('not a Mercurial patch'))
2619 p1 = repo.lookup(p1)
2621 p1 = repo.lookup(p1)
2620 p2 = repo.lookup(p2 or hex(nullid))
2622 p2 = repo.lookup(p2 or hex(nullid))
2621
2623
2622 if p1 != wp[0].node():
2624 if p1 != wp[0].node():
2623 hg.clean(repo, p1)
2625 hg.clean(repo, p1)
2624 repo.dirstate.setparents(p1, p2)
2626 repo.dirstate.setparents(p1, p2)
2625 elif p2:
2627 elif p2:
2626 try:
2628 try:
2627 p1 = repo.lookup(p1)
2629 p1 = repo.lookup(p1)
2628 p2 = repo.lookup(p2)
2630 p2 = repo.lookup(p2)
2629 if p1 == wp[0].node():
2631 if p1 == wp[0].node():
2630 repo.dirstate.setparents(p1, p2)
2632 repo.dirstate.setparents(p1, p2)
2631 except error.RepoError:
2633 except error.RepoError:
2632 pass
2634 pass
2633 if opts.get('exact') or opts.get('import_branch'):
2635 if opts.get('exact') or opts.get('import_branch'):
2634 repo.dirstate.setbranch(branch or 'default')
2636 repo.dirstate.setbranch(branch or 'default')
2635
2637
2636 files = {}
2638 files = {}
2637 patch.patch(ui, repo, tmpname, strip=strip, cwd=repo.root,
2639 patch.patch(ui, repo, tmpname, strip=strip, cwd=repo.root,
2638 files=files, eolmode=None, similarity=sim / 100.0)
2640 files=files, eolmode=None, similarity=sim / 100.0)
2639 files = list(files)
2641 files = list(files)
2640 if opts.get('no_commit'):
2642 if opts.get('no_commit'):
2641 if message:
2643 if message:
2642 msgs.append(message)
2644 msgs.append(message)
2643 else:
2645 else:
2644 if opts.get('exact'):
2646 if opts.get('exact'):
2645 m = None
2647 m = None
2646 else:
2648 else:
2647 m = cmdutil.matchfiles(repo, files or [])
2649 m = cmdutil.matchfiles(repo, files or [])
2648 n = repo.commit(message, opts.get('user') or user,
2650 n = repo.commit(message, opts.get('user') or user,
2649 opts.get('date') or date, match=m,
2651 opts.get('date') or date, match=m,
2650 editor=cmdutil.commiteditor)
2652 editor=cmdutil.commiteditor)
2651 if opts.get('exact'):
2653 if opts.get('exact'):
2652 if hex(n) != nodeid:
2654 if hex(n) != nodeid:
2653 repo.rollback()
2655 repo.rollback()
2654 raise util.Abort(_('patch is damaged'
2656 raise util.Abort(_('patch is damaged'
2655 ' or loses information'))
2657 ' or loses information'))
2656 # Force a dirstate write so that the next transaction
2658 # Force a dirstate write so that the next transaction
2657 # backups an up-do-date file.
2659 # backups an up-do-date file.
2658 repo.dirstate.write()
2660 repo.dirstate.write()
2659 if n:
2661 if n:
2660 commitid = short(n)
2662 commitid = short(n)
2661
2663
2662 return commitid
2664 return commitid
2663 finally:
2665 finally:
2664 os.unlink(tmpname)
2666 os.unlink(tmpname)
2665
2667
2666 try:
2668 try:
2667 wlock = repo.wlock()
2669 wlock = repo.wlock()
2668 lock = repo.lock()
2670 lock = repo.lock()
2669 lastcommit = None
2671 lastcommit = None
2670 for p in patches:
2672 for p in patches:
2671 pf = os.path.join(d, p)
2673 pf = os.path.join(d, p)
2672
2674
2673 if pf == '-':
2675 if pf == '-':
2674 ui.status(_("applying patch from stdin\n"))
2676 ui.status(_("applying patch from stdin\n"))
2675 pf = sys.stdin
2677 pf = sys.stdin
2676 else:
2678 else:
2677 ui.status(_("applying %s\n") % p)
2679 ui.status(_("applying %s\n") % p)
2678 pf = url.open(ui, pf)
2680 pf = url.open(ui, pf)
2679
2681
2680 haspatch = False
2682 haspatch = False
2681 for hunk in patch.split(pf):
2683 for hunk in patch.split(pf):
2682 commitid = tryone(ui, hunk)
2684 commitid = tryone(ui, hunk)
2683 if commitid:
2685 if commitid:
2684 haspatch = True
2686 haspatch = True
2685 if lastcommit:
2687 if lastcommit:
2686 ui.status(_('applied %s\n') % lastcommit)
2688 ui.status(_('applied %s\n') % lastcommit)
2687 lastcommit = commitid
2689 lastcommit = commitid
2688
2690
2689 if not haspatch:
2691 if not haspatch:
2690 raise util.Abort(_('no diffs found'))
2692 raise util.Abort(_('no diffs found'))
2691
2693
2692 if msgs:
2694 if msgs:
2693 repo.opener.write('last-message.txt', '\n* * *\n'.join(msgs))
2695 repo.opener.write('last-message.txt', '\n* * *\n'.join(msgs))
2694 finally:
2696 finally:
2695 release(lock, wlock)
2697 release(lock, wlock)
2696
2698
2697 def incoming(ui, repo, source="default", **opts):
2699 def incoming(ui, repo, source="default", **opts):
2698 """show new changesets found in source
2700 """show new changesets found in source
2699
2701
2700 Show new changesets found in the specified path/URL or the default
2702 Show new changesets found in the specified path/URL or the default
2701 pull location. These are the changesets that would have been pulled
2703 pull location. These are the changesets that would have been pulled
2702 if a pull at the time you issued this command.
2704 if a pull at the time you issued this command.
2703
2705
2704 For remote repository, using --bundle avoids downloading the
2706 For remote repository, using --bundle avoids downloading the
2705 changesets twice if the incoming is followed by a pull.
2707 changesets twice if the incoming is followed by a pull.
2706
2708
2707 See pull for valid source format details.
2709 See pull for valid source format details.
2708
2710
2709 Returns 0 if there are incoming changes, 1 otherwise.
2711 Returns 0 if there are incoming changes, 1 otherwise.
2710 """
2712 """
2711 if opts.get('bundle') and opts.get('subrepos'):
2713 if opts.get('bundle') and opts.get('subrepos'):
2712 raise util.Abort(_('cannot combine --bundle and --subrepos'))
2714 raise util.Abort(_('cannot combine --bundle and --subrepos'))
2713
2715
2714 if opts.get('bookmarks'):
2716 if opts.get('bookmarks'):
2715 source, branches = hg.parseurl(ui.expandpath(source),
2717 source, branches = hg.parseurl(ui.expandpath(source),
2716 opts.get('branch'))
2718 opts.get('branch'))
2717 other = hg.repository(hg.remoteui(repo, opts), source)
2719 other = hg.repository(hg.remoteui(repo, opts), source)
2718 if 'bookmarks' not in other.listkeys('namespaces'):
2720 if 'bookmarks' not in other.listkeys('namespaces'):
2719 ui.warn(_("remote doesn't support bookmarks\n"))
2721 ui.warn(_("remote doesn't support bookmarks\n"))
2720 return 0
2722 return 0
2721 ui.status(_('comparing with %s\n') % util.hidepassword(source))
2723 ui.status(_('comparing with %s\n') % util.hidepassword(source))
2722 return bookmarks.diff(ui, repo, other)
2724 return bookmarks.diff(ui, repo, other)
2723
2725
2724 ret = hg.incoming(ui, repo, source, opts)
2726 ret = hg.incoming(ui, repo, source, opts)
2725 return ret
2727 return ret
2726
2728
2727 def init(ui, dest=".", **opts):
2729 def init(ui, dest=".", **opts):
2728 """create a new repository in the given directory
2730 """create a new repository in the given directory
2729
2731
2730 Initialize a new repository in the given directory. If the given
2732 Initialize a new repository in the given directory. If the given
2731 directory does not exist, it will be created.
2733 directory does not exist, it will be created.
2732
2734
2733 If no directory is given, the current directory is used.
2735 If no directory is given, the current directory is used.
2734
2736
2735 It is possible to specify an ``ssh://`` URL as the destination.
2737 It is possible to specify an ``ssh://`` URL as the destination.
2736 See :hg:`help urls` for more information.
2738 See :hg:`help urls` for more information.
2737
2739
2738 Returns 0 on success.
2740 Returns 0 on success.
2739 """
2741 """
2740 hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
2742 hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
2741
2743
2742 def locate(ui, repo, *pats, **opts):
2744 def locate(ui, repo, *pats, **opts):
2743 """locate files matching specific patterns
2745 """locate files matching specific patterns
2744
2746
2745 Print files under Mercurial control in the working directory whose
2747 Print files under Mercurial control in the working directory whose
2746 names match the given patterns.
2748 names match the given patterns.
2747
2749
2748 By default, this command searches all directories in the working
2750 By default, this command searches all directories in the working
2749 directory. To search just the current directory and its
2751 directory. To search just the current directory and its
2750 subdirectories, use "--include .".
2752 subdirectories, use "--include .".
2751
2753
2752 If no patterns are given to match, this command prints the names
2754 If no patterns are given to match, this command prints the names
2753 of all files under Mercurial control in the working directory.
2755 of all files under Mercurial control in the working directory.
2754
2756
2755 If you want to feed the output of this command into the "xargs"
2757 If you want to feed the output of this command into the "xargs"
2756 command, use the -0 option to both this command and "xargs". This
2758 command, use the -0 option to both this command and "xargs". This
2757 will avoid the problem of "xargs" treating single filenames that
2759 will avoid the problem of "xargs" treating single filenames that
2758 contain whitespace as multiple filenames.
2760 contain whitespace as multiple filenames.
2759
2761
2760 Returns 0 if a match is found, 1 otherwise.
2762 Returns 0 if a match is found, 1 otherwise.
2761 """
2763 """
2762 end = opts.get('print0') and '\0' or '\n'
2764 end = opts.get('print0') and '\0' or '\n'
2763 rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
2765 rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
2764
2766
2765 ret = 1
2767 ret = 1
2766 m = cmdutil.match(repo, pats, opts, default='relglob')
2768 m = cmdutil.match(repo, pats, opts, default='relglob')
2767 m.bad = lambda x, y: False
2769 m.bad = lambda x, y: False
2768 for abs in repo[rev].walk(m):
2770 for abs in repo[rev].walk(m):
2769 if not rev and abs not in repo.dirstate:
2771 if not rev and abs not in repo.dirstate:
2770 continue
2772 continue
2771 if opts.get('fullpath'):
2773 if opts.get('fullpath'):
2772 ui.write(repo.wjoin(abs), end)
2774 ui.write(repo.wjoin(abs), end)
2773 else:
2775 else:
2774 ui.write(((pats and m.rel(abs)) or abs), end)
2776 ui.write(((pats and m.rel(abs)) or abs), end)
2775 ret = 0
2777 ret = 0
2776
2778
2777 return ret
2779 return ret
2778
2780
2779 def log(ui, repo, *pats, **opts):
2781 def log(ui, repo, *pats, **opts):
2780 """show revision history of entire repository or files
2782 """show revision history of entire repository or files
2781
2783
2782 Print the revision history of the specified files or the entire
2784 Print the revision history of the specified files or the entire
2783 project.
2785 project.
2784
2786
2785 File history is shown without following rename or copy history of
2787 File history is shown without following rename or copy history of
2786 files. Use -f/--follow with a filename to follow history across
2788 files. Use -f/--follow with a filename to follow history across
2787 renames and copies. --follow without a filename will only show
2789 renames and copies. --follow without a filename will only show
2788 ancestors or descendants of the starting revision. --follow-first
2790 ancestors or descendants of the starting revision. --follow-first
2789 only follows the first parent of merge revisions.
2791 only follows the first parent of merge revisions.
2790
2792
2791 If no revision range is specified, the default is ``tip:0`` unless
2793 If no revision range is specified, the default is ``tip:0`` unless
2792 --follow is set, in which case the working directory parent is
2794 --follow is set, in which case the working directory parent is
2793 used as the starting revision. You can specify a revision set for
2795 used as the starting revision. You can specify a revision set for
2794 log, see :hg:`help revsets` for more information.
2796 log, see :hg:`help revsets` for more information.
2795
2797
2796 See :hg:`help dates` for a list of formats valid for -d/--date.
2798 See :hg:`help dates` for a list of formats valid for -d/--date.
2797
2799
2798 By default this command prints revision number and changeset id,
2800 By default this command prints revision number and changeset id,
2799 tags, non-trivial parents, user, date and time, and a summary for
2801 tags, non-trivial parents, user, date and time, and a summary for
2800 each commit. When the -v/--verbose switch is used, the list of
2802 each commit. When the -v/--verbose switch is used, the list of
2801 changed files and full commit message are shown.
2803 changed files and full commit message are shown.
2802
2804
2803 .. note::
2805 .. note::
2804 log -p/--patch may generate unexpected diff output for merge
2806 log -p/--patch may generate unexpected diff output for merge
2805 changesets, as it will only compare the merge changeset against
2807 changesets, as it will only compare the merge changeset against
2806 its first parent. Also, only files different from BOTH parents
2808 its first parent. Also, only files different from BOTH parents
2807 will appear in files:.
2809 will appear in files:.
2808
2810
2809 Returns 0 on success.
2811 Returns 0 on success.
2810 """
2812 """
2811
2813
2812 matchfn = cmdutil.match(repo, pats, opts)
2814 matchfn = cmdutil.match(repo, pats, opts)
2813 limit = cmdutil.loglimit(opts)
2815 limit = cmdutil.loglimit(opts)
2814 count = 0
2816 count = 0
2815
2817
2816 endrev = None
2818 endrev = None
2817 if opts.get('copies') and opts.get('rev'):
2819 if opts.get('copies') and opts.get('rev'):
2818 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2820 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2819
2821
2820 df = False
2822 df = False
2821 if opts["date"]:
2823 if opts["date"]:
2822 df = util.matchdate(opts["date"])
2824 df = util.matchdate(opts["date"])
2823
2825
2824 branches = opts.get('branch', []) + opts.get('only_branch', [])
2826 branches = opts.get('branch', []) + opts.get('only_branch', [])
2825 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2827 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2826
2828
2827 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2829 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2828 def prep(ctx, fns):
2830 def prep(ctx, fns):
2829 rev = ctx.rev()
2831 rev = ctx.rev()
2830 parents = [p for p in repo.changelog.parentrevs(rev)
2832 parents = [p for p in repo.changelog.parentrevs(rev)
2831 if p != nullrev]
2833 if p != nullrev]
2832 if opts.get('no_merges') and len(parents) == 2:
2834 if opts.get('no_merges') and len(parents) == 2:
2833 return
2835 return
2834 if opts.get('only_merges') and len(parents) != 2:
2836 if opts.get('only_merges') and len(parents) != 2:
2835 return
2837 return
2836 if opts.get('branch') and ctx.branch() not in opts['branch']:
2838 if opts.get('branch') and ctx.branch() not in opts['branch']:
2837 return
2839 return
2838 if df and not df(ctx.date()[0]):
2840 if df and not df(ctx.date()[0]):
2839 return
2841 return
2840 if opts['user'] and not [k for k in opts['user']
2842 if opts['user'] and not [k for k in opts['user']
2841 if k.lower() in ctx.user().lower()]:
2843 if k.lower() in ctx.user().lower()]:
2842 return
2844 return
2843 if opts.get('keyword'):
2845 if opts.get('keyword'):
2844 for k in [kw.lower() for kw in opts['keyword']]:
2846 for k in [kw.lower() for kw in opts['keyword']]:
2845 if (k in ctx.user().lower() or
2847 if (k in ctx.user().lower() or
2846 k in ctx.description().lower() or
2848 k in ctx.description().lower() or
2847 k in " ".join(ctx.files()).lower()):
2849 k in " ".join(ctx.files()).lower()):
2848 break
2850 break
2849 else:
2851 else:
2850 return
2852 return
2851
2853
2852 copies = None
2854 copies = None
2853 if opts.get('copies') and rev:
2855 if opts.get('copies') and rev:
2854 copies = []
2856 copies = []
2855 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2857 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2856 for fn in ctx.files():
2858 for fn in ctx.files():
2857 rename = getrenamed(fn, rev)
2859 rename = getrenamed(fn, rev)
2858 if rename:
2860 if rename:
2859 copies.append((fn, rename[0]))
2861 copies.append((fn, rename[0]))
2860
2862
2861 revmatchfn = None
2863 revmatchfn = None
2862 if opts.get('patch') or opts.get('stat'):
2864 if opts.get('patch') or opts.get('stat'):
2863 if opts.get('follow') or opts.get('follow_first'):
2865 if opts.get('follow') or opts.get('follow_first'):
2864 # note: this might be wrong when following through merges
2866 # note: this might be wrong when following through merges
2865 revmatchfn = cmdutil.match(repo, fns, default='path')
2867 revmatchfn = cmdutil.match(repo, fns, default='path')
2866 else:
2868 else:
2867 revmatchfn = matchfn
2869 revmatchfn = matchfn
2868
2870
2869 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2871 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2870
2872
2871 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2873 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2872 if count == limit:
2874 if count == limit:
2873 break
2875 break
2874 if displayer.flush(ctx.rev()):
2876 if displayer.flush(ctx.rev()):
2875 count += 1
2877 count += 1
2876 displayer.close()
2878 displayer.close()
2877
2879
2878 def manifest(ui, repo, node=None, rev=None):
2880 def manifest(ui, repo, node=None, rev=None):
2879 """output the current or given revision of the project manifest
2881 """output the current or given revision of the project manifest
2880
2882
2881 Print a list of version controlled files for the given revision.
2883 Print a list of version controlled files for the given revision.
2882 If no revision is given, the first parent of the working directory
2884 If no revision is given, the first parent of the working directory
2883 is used, or the null revision if no revision is checked out.
2885 is used, or the null revision if no revision is checked out.
2884
2886
2885 With -v, print file permissions, symlink and executable bits.
2887 With -v, print file permissions, symlink and executable bits.
2886 With --debug, print file revision hashes.
2888 With --debug, print file revision hashes.
2887
2889
2888 Returns 0 on success.
2890 Returns 0 on success.
2889 """
2891 """
2890
2892
2891 if rev and node:
2893 if rev and node:
2892 raise util.Abort(_("please specify just one revision"))
2894 raise util.Abort(_("please specify just one revision"))
2893
2895
2894 if not node:
2896 if not node:
2895 node = rev
2897 node = rev
2896
2898
2897 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2899 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2898 ctx = cmdutil.revsingle(repo, node)
2900 ctx = cmdutil.revsingle(repo, node)
2899 for f in ctx:
2901 for f in ctx:
2900 if ui.debugflag:
2902 if ui.debugflag:
2901 ui.write("%40s " % hex(ctx.manifest()[f]))
2903 ui.write("%40s " % hex(ctx.manifest()[f]))
2902 if ui.verbose:
2904 if ui.verbose:
2903 ui.write(decor[ctx.flags(f)])
2905 ui.write(decor[ctx.flags(f)])
2904 ui.write("%s\n" % f)
2906 ui.write("%s\n" % f)
2905
2907
2906 def merge(ui, repo, node=None, **opts):
2908 def merge(ui, repo, node=None, **opts):
2907 """merge working directory with another revision
2909 """merge working directory with another revision
2908
2910
2909 The current working directory is updated with all changes made in
2911 The current working directory is updated with all changes made in
2910 the requested revision since the last common predecessor revision.
2912 the requested revision since the last common predecessor revision.
2911
2913
2912 Files that changed between either parent are marked as changed for
2914 Files that changed between either parent are marked as changed for
2913 the next commit and a commit must be performed before any further
2915 the next commit and a commit must be performed before any further
2914 updates to the repository are allowed. The next commit will have
2916 updates to the repository are allowed. The next commit will have
2915 two parents.
2917 two parents.
2916
2918
2917 ``--tool`` can be used to specify the merge tool used for file
2919 ``--tool`` can be used to specify the merge tool used for file
2918 merges. It overrides the HGMERGE environment variable and your
2920 merges. It overrides the HGMERGE environment variable and your
2919 configuration files. See :hg:`help merge-tools` for options.
2921 configuration files. See :hg:`help merge-tools` for options.
2920
2922
2921 If no revision is specified, the working directory's parent is a
2923 If no revision is specified, the working directory's parent is a
2922 head revision, and the current branch contains exactly one other
2924 head revision, and the current branch contains exactly one other
2923 head, the other head is merged with by default. Otherwise, an
2925 head, the other head is merged with by default. Otherwise, an
2924 explicit revision with which to merge with must be provided.
2926 explicit revision with which to merge with must be provided.
2925
2927
2926 :hg:`resolve` must be used to resolve unresolved files.
2928 :hg:`resolve` must be used to resolve unresolved files.
2927
2929
2928 To undo an uncommitted merge, use :hg:`update --clean .` which
2930 To undo an uncommitted merge, use :hg:`update --clean .` which
2929 will check out a clean copy of the original merge parent, losing
2931 will check out a clean copy of the original merge parent, losing
2930 all changes.
2932 all changes.
2931
2933
2932 Returns 0 on success, 1 if there are unresolved files.
2934 Returns 0 on success, 1 if there are unresolved files.
2933 """
2935 """
2934
2936
2935 if opts.get('rev') and node:
2937 if opts.get('rev') and node:
2936 raise util.Abort(_("please specify just one revision"))
2938 raise util.Abort(_("please specify just one revision"))
2937 if not node:
2939 if not node:
2938 node = opts.get('rev')
2940 node = opts.get('rev')
2939
2941
2940 if not node:
2942 if not node:
2941 branch = repo[None].branch()
2943 branch = repo[None].branch()
2942 bheads = repo.branchheads(branch)
2944 bheads = repo.branchheads(branch)
2943 if len(bheads) > 2:
2945 if len(bheads) > 2:
2944 raise util.Abort(_("branch '%s' has %d heads - "
2946 raise util.Abort(_("branch '%s' has %d heads - "
2945 "please merge with an explicit rev")
2947 "please merge with an explicit rev")
2946 % (branch, len(bheads)),
2948 % (branch, len(bheads)),
2947 hint=_("run 'hg heads .' to see heads"))
2949 hint=_("run 'hg heads .' to see heads"))
2948
2950
2949 parent = repo.dirstate.p1()
2951 parent = repo.dirstate.p1()
2950 if len(bheads) == 1:
2952 if len(bheads) == 1:
2951 if len(repo.heads()) > 1:
2953 if len(repo.heads()) > 1:
2952 raise util.Abort(_("branch '%s' has one head - "
2954 raise util.Abort(_("branch '%s' has one head - "
2953 "please merge with an explicit rev")
2955 "please merge with an explicit rev")
2954 % branch,
2956 % branch,
2955 hint=_("run 'hg heads' to see all heads"))
2957 hint=_("run 'hg heads' to see all heads"))
2956 msg = _('there is nothing to merge')
2958 msg = _('there is nothing to merge')
2957 if parent != repo.lookup(repo[None].branch()):
2959 if parent != repo.lookup(repo[None].branch()):
2958 msg = _('%s - use "hg update" instead') % msg
2960 msg = _('%s - use "hg update" instead') % msg
2959 raise util.Abort(msg)
2961 raise util.Abort(msg)
2960
2962
2961 if parent not in bheads:
2963 if parent not in bheads:
2962 raise util.Abort(_('working directory not at a head revision'),
2964 raise util.Abort(_('working directory not at a head revision'),
2963 hint=_("use 'hg update' or merge with an "
2965 hint=_("use 'hg update' or merge with an "
2964 "explicit revision"))
2966 "explicit revision"))
2965 node = parent == bheads[0] and bheads[-1] or bheads[0]
2967 node = parent == bheads[0] and bheads[-1] or bheads[0]
2966 else:
2968 else:
2967 node = cmdutil.revsingle(repo, node).node()
2969 node = cmdutil.revsingle(repo, node).node()
2968
2970
2969 if opts.get('preview'):
2971 if opts.get('preview'):
2970 # find nodes that are ancestors of p2 but not of p1
2972 # find nodes that are ancestors of p2 but not of p1
2971 p1 = repo.lookup('.')
2973 p1 = repo.lookup('.')
2972 p2 = repo.lookup(node)
2974 p2 = repo.lookup(node)
2973 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2975 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2974
2976
2975 displayer = cmdutil.show_changeset(ui, repo, opts)
2977 displayer = cmdutil.show_changeset(ui, repo, opts)
2976 for node in nodes:
2978 for node in nodes:
2977 displayer.show(repo[node])
2979 displayer.show(repo[node])
2978 displayer.close()
2980 displayer.close()
2979 return 0
2981 return 0
2980
2982
2981 try:
2983 try:
2982 # ui.forcemerge is an internal variable, do not document
2984 # ui.forcemerge is an internal variable, do not document
2983 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2985 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2984 return hg.merge(repo, node, force=opts.get('force'))
2986 return hg.merge(repo, node, force=opts.get('force'))
2985 finally:
2987 finally:
2986 ui.setconfig('ui', 'forcemerge', '')
2988 ui.setconfig('ui', 'forcemerge', '')
2987
2989
2988 def outgoing(ui, repo, dest=None, **opts):
2990 def outgoing(ui, repo, dest=None, **opts):
2989 """show changesets not found in the destination
2991 """show changesets not found in the destination
2990
2992
2991 Show changesets not found in the specified destination repository
2993 Show changesets not found in the specified destination repository
2992 or the default push location. These are the changesets that would
2994 or the default push location. These are the changesets that would
2993 be pushed if a push was requested.
2995 be pushed if a push was requested.
2994
2996
2995 See pull for details of valid destination formats.
2997 See pull for details of valid destination formats.
2996
2998
2997 Returns 0 if there are outgoing changes, 1 otherwise.
2999 Returns 0 if there are outgoing changes, 1 otherwise.
2998 """
3000 """
2999
3001
3000 if opts.get('bookmarks'):
3002 if opts.get('bookmarks'):
3001 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3003 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3002 dest, branches = hg.parseurl(dest, opts.get('branch'))
3004 dest, branches = hg.parseurl(dest, opts.get('branch'))
3003 other = hg.repository(hg.remoteui(repo, opts), dest)
3005 other = hg.repository(hg.remoteui(repo, opts), dest)
3004 if 'bookmarks' not in other.listkeys('namespaces'):
3006 if 'bookmarks' not in other.listkeys('namespaces'):
3005 ui.warn(_("remote doesn't support bookmarks\n"))
3007 ui.warn(_("remote doesn't support bookmarks\n"))
3006 return 0
3008 return 0
3007 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
3009 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
3008 return bookmarks.diff(ui, other, repo)
3010 return bookmarks.diff(ui, other, repo)
3009
3011
3010 ret = hg.outgoing(ui, repo, dest, opts)
3012 ret = hg.outgoing(ui, repo, dest, opts)
3011 return ret
3013 return ret
3012
3014
3013 def parents(ui, repo, file_=None, **opts):
3015 def parents(ui, repo, file_=None, **opts):
3014 """show the parents of the working directory or revision
3016 """show the parents of the working directory or revision
3015
3017
3016 Print the working directory's parent revisions. If a revision is
3018 Print the working directory's parent revisions. If a revision is
3017 given via -r/--rev, the parent of that revision will be printed.
3019 given via -r/--rev, the parent of that revision will be printed.
3018 If a file argument is given, the revision in which the file was
3020 If a file argument is given, the revision in which the file was
3019 last changed (before the working directory revision or the
3021 last changed (before the working directory revision or the
3020 argument to --rev if given) is printed.
3022 argument to --rev if given) is printed.
3021
3023
3022 Returns 0 on success.
3024 Returns 0 on success.
3023 """
3025 """
3024
3026
3025 ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
3027 ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
3026
3028
3027 if file_:
3029 if file_:
3028 m = cmdutil.match(repo, (file_,), opts)
3030 m = cmdutil.match(repo, (file_,), opts)
3029 if m.anypats() or len(m.files()) != 1:
3031 if m.anypats() or len(m.files()) != 1:
3030 raise util.Abort(_('can only specify an explicit filename'))
3032 raise util.Abort(_('can only specify an explicit filename'))
3031 file_ = m.files()[0]
3033 file_ = m.files()[0]
3032 filenodes = []
3034 filenodes = []
3033 for cp in ctx.parents():
3035 for cp in ctx.parents():
3034 if not cp:
3036 if not cp:
3035 continue
3037 continue
3036 try:
3038 try:
3037 filenodes.append(cp.filenode(file_))
3039 filenodes.append(cp.filenode(file_))
3038 except error.LookupError:
3040 except error.LookupError:
3039 pass
3041 pass
3040 if not filenodes:
3042 if not filenodes:
3041 raise util.Abort(_("'%s' not found in manifest!") % file_)
3043 raise util.Abort(_("'%s' not found in manifest!") % file_)
3042 fl = repo.file(file_)
3044 fl = repo.file(file_)
3043 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
3045 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
3044 else:
3046 else:
3045 p = [cp.node() for cp in ctx.parents()]
3047 p = [cp.node() for cp in ctx.parents()]
3046
3048
3047 displayer = cmdutil.show_changeset(ui, repo, opts)
3049 displayer = cmdutil.show_changeset(ui, repo, opts)
3048 for n in p:
3050 for n in p:
3049 if n != nullid:
3051 if n != nullid:
3050 displayer.show(repo[n])
3052 displayer.show(repo[n])
3051 displayer.close()
3053 displayer.close()
3052
3054
3053 def paths(ui, repo, search=None):
3055 def paths(ui, repo, search=None):
3054 """show aliases for remote repositories
3056 """show aliases for remote repositories
3055
3057
3056 Show definition of symbolic path name NAME. If no name is given,
3058 Show definition of symbolic path name NAME. If no name is given,
3057 show definition of all available names.
3059 show definition of all available names.
3058
3060
3059 Path names are defined in the [paths] section of your
3061 Path names are defined in the [paths] section of your
3060 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
3062 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
3061 repository, ``.hg/hgrc`` is used, too.
3063 repository, ``.hg/hgrc`` is used, too.
3062
3064
3063 The path names ``default`` and ``default-push`` have a special
3065 The path names ``default`` and ``default-push`` have a special
3064 meaning. When performing a push or pull operation, they are used
3066 meaning. When performing a push or pull operation, they are used
3065 as fallbacks if no location is specified on the command-line.
3067 as fallbacks if no location is specified on the command-line.
3066 When ``default-push`` is set, it will be used for push and
3068 When ``default-push`` is set, it will be used for push and
3067 ``default`` will be used for pull; otherwise ``default`` is used
3069 ``default`` will be used for pull; otherwise ``default`` is used
3068 as the fallback for both. When cloning a repository, the clone
3070 as the fallback for both. When cloning a repository, the clone
3069 source is written as ``default`` in ``.hg/hgrc``. Note that
3071 source is written as ``default`` in ``.hg/hgrc``. Note that
3070 ``default`` and ``default-push`` apply to all inbound (e.g.
3072 ``default`` and ``default-push`` apply to all inbound (e.g.
3071 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
3073 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
3072 :hg:`bundle`) operations.
3074 :hg:`bundle`) operations.
3073
3075
3074 See :hg:`help urls` for more information.
3076 See :hg:`help urls` for more information.
3075
3077
3076 Returns 0 on success.
3078 Returns 0 on success.
3077 """
3079 """
3078 if search:
3080 if search:
3079 for name, path in ui.configitems("paths"):
3081 for name, path in ui.configitems("paths"):
3080 if name == search:
3082 if name == search:
3081 ui.write("%s\n" % util.hidepassword(path))
3083 ui.write("%s\n" % util.hidepassword(path))
3082 return
3084 return
3083 ui.warn(_("not found!\n"))
3085 ui.warn(_("not found!\n"))
3084 return 1
3086 return 1
3085 else:
3087 else:
3086 for name, path in ui.configitems("paths"):
3088 for name, path in ui.configitems("paths"):
3087 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
3089 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
3088
3090
3089 def postincoming(ui, repo, modheads, optupdate, checkout):
3091 def postincoming(ui, repo, modheads, optupdate, checkout):
3090 if modheads == 0:
3092 if modheads == 0:
3091 return
3093 return
3092 if optupdate:
3094 if optupdate:
3093 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
3095 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
3094 return hg.update(repo, checkout)
3096 return hg.update(repo, checkout)
3095 else:
3097 else:
3096 ui.status(_("not updating, since new heads added\n"))
3098 ui.status(_("not updating, since new heads added\n"))
3097 if modheads > 1:
3099 if modheads > 1:
3098 currentbranchheads = len(repo.branchheads())
3100 currentbranchheads = len(repo.branchheads())
3099 if currentbranchheads == modheads:
3101 if currentbranchheads == modheads:
3100 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
3102 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
3101 elif currentbranchheads > 1:
3103 elif currentbranchheads > 1:
3102 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
3104 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
3103 else:
3105 else:
3104 ui.status(_("(run 'hg heads' to see heads)\n"))
3106 ui.status(_("(run 'hg heads' to see heads)\n"))
3105 else:
3107 else:
3106 ui.status(_("(run 'hg update' to get a working copy)\n"))
3108 ui.status(_("(run 'hg update' to get a working copy)\n"))
3107
3109
3108 def pull(ui, repo, source="default", **opts):
3110 def pull(ui, repo, source="default", **opts):
3109 """pull changes from the specified source
3111 """pull changes from the specified source
3110
3112
3111 Pull changes from a remote repository to a local one.
3113 Pull changes from a remote repository to a local one.
3112
3114
3113 This finds all changes from the repository at the specified path
3115 This finds all changes from the repository at the specified path
3114 or URL and adds them to a local repository (the current one unless
3116 or URL and adds them to a local repository (the current one unless
3115 -R is specified). By default, this does not update the copy of the
3117 -R is specified). By default, this does not update the copy of the
3116 project in the working directory.
3118 project in the working directory.
3117
3119
3118 Use :hg:`incoming` if you want to see what would have been added
3120 Use :hg:`incoming` if you want to see what would have been added
3119 by a pull at the time you issued this command. If you then decide
3121 by a pull at the time you issued this command. If you then decide
3120 to add those changes to the repository, you should use :hg:`pull
3122 to add those changes to the repository, you should use :hg:`pull
3121 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
3123 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
3122
3124
3123 If SOURCE is omitted, the 'default' path will be used.
3125 If SOURCE is omitted, the 'default' path will be used.
3124 See :hg:`help urls` for more information.
3126 See :hg:`help urls` for more information.
3125
3127
3126 Returns 0 on success, 1 if an update had unresolved files.
3128 Returns 0 on success, 1 if an update had unresolved files.
3127 """
3129 """
3128 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
3130 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
3129 other = hg.repository(hg.remoteui(repo, opts), source)
3131 other = hg.repository(hg.remoteui(repo, opts), source)
3130 ui.status(_('pulling from %s\n') % util.hidepassword(source))
3132 ui.status(_('pulling from %s\n') % util.hidepassword(source))
3131 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3133 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3132
3134
3133 if opts.get('bookmark'):
3135 if opts.get('bookmark'):
3134 if not revs:
3136 if not revs:
3135 revs = []
3137 revs = []
3136 rb = other.listkeys('bookmarks')
3138 rb = other.listkeys('bookmarks')
3137 for b in opts['bookmark']:
3139 for b in opts['bookmark']:
3138 if b not in rb:
3140 if b not in rb:
3139 raise util.Abort(_('remote bookmark %s not found!') % b)
3141 raise util.Abort(_('remote bookmark %s not found!') % b)
3140 revs.append(rb[b])
3142 revs.append(rb[b])
3141
3143
3142 if revs:
3144 if revs:
3143 try:
3145 try:
3144 revs = [other.lookup(rev) for rev in revs]
3146 revs = [other.lookup(rev) for rev in revs]
3145 except error.CapabilityError:
3147 except error.CapabilityError:
3146 err = _("other repository doesn't support revision lookup, "
3148 err = _("other repository doesn't support revision lookup, "
3147 "so a rev cannot be specified.")
3149 "so a rev cannot be specified.")
3148 raise util.Abort(err)
3150 raise util.Abort(err)
3149
3151
3150 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
3152 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
3151 bookmarks.updatefromremote(ui, repo, other)
3153 bookmarks.updatefromremote(ui, repo, other)
3152 if checkout:
3154 if checkout:
3153 checkout = str(repo.changelog.rev(other.lookup(checkout)))
3155 checkout = str(repo.changelog.rev(other.lookup(checkout)))
3154 repo._subtoppath = source
3156 repo._subtoppath = source
3155 try:
3157 try:
3156 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
3158 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
3157
3159
3158 finally:
3160 finally:
3159 del repo._subtoppath
3161 del repo._subtoppath
3160
3162
3161 # update specified bookmarks
3163 # update specified bookmarks
3162 if opts.get('bookmark'):
3164 if opts.get('bookmark'):
3163 for b in opts['bookmark']:
3165 for b in opts['bookmark']:
3164 # explicit pull overrides local bookmark if any
3166 # explicit pull overrides local bookmark if any
3165 ui.status(_("importing bookmark %s\n") % b)
3167 ui.status(_("importing bookmark %s\n") % b)
3166 repo._bookmarks[b] = repo[rb[b]].node()
3168 repo._bookmarks[b] = repo[rb[b]].node()
3167 bookmarks.write(repo)
3169 bookmarks.write(repo)
3168
3170
3169 return ret
3171 return ret
3170
3172
3171 def push(ui, repo, dest=None, **opts):
3173 def push(ui, repo, dest=None, **opts):
3172 """push changes to the specified destination
3174 """push changes to the specified destination
3173
3175
3174 Push changesets from the local repository to the specified
3176 Push changesets from the local repository to the specified
3175 destination.
3177 destination.
3176
3178
3177 This operation is symmetrical to pull: it is identical to a pull
3179 This operation is symmetrical to pull: it is identical to a pull
3178 in the destination repository from the current one.
3180 in the destination repository from the current one.
3179
3181
3180 By default, push will not allow creation of new heads at the
3182 By default, push will not allow creation of new heads at the
3181 destination, since multiple heads would make it unclear which head
3183 destination, since multiple heads would make it unclear which head
3182 to use. In this situation, it is recommended to pull and merge
3184 to use. In this situation, it is recommended to pull and merge
3183 before pushing.
3185 before pushing.
3184
3186
3185 Use --new-branch if you want to allow push to create a new named
3187 Use --new-branch if you want to allow push to create a new named
3186 branch that is not present at the destination. This allows you to
3188 branch that is not present at the destination. This allows you to
3187 only create a new branch without forcing other changes.
3189 only create a new branch without forcing other changes.
3188
3190
3189 Use -f/--force to override the default behavior and push all
3191 Use -f/--force to override the default behavior and push all
3190 changesets on all branches.
3192 changesets on all branches.
3191
3193
3192 If -r/--rev is used, the specified revision and all its ancestors
3194 If -r/--rev is used, the specified revision and all its ancestors
3193 will be pushed to the remote repository.
3195 will be pushed to the remote repository.
3194
3196
3195 Please see :hg:`help urls` for important details about ``ssh://``
3197 Please see :hg:`help urls` for important details about ``ssh://``
3196 URLs. If DESTINATION is omitted, a default path will be used.
3198 URLs. If DESTINATION is omitted, a default path will be used.
3197
3199
3198 Returns 0 if push was successful, 1 if nothing to push.
3200 Returns 0 if push was successful, 1 if nothing to push.
3199 """
3201 """
3200
3202
3201 if opts.get('bookmark'):
3203 if opts.get('bookmark'):
3202 for b in opts['bookmark']:
3204 for b in opts['bookmark']:
3203 # translate -B options to -r so changesets get pushed
3205 # translate -B options to -r so changesets get pushed
3204 if b in repo._bookmarks:
3206 if b in repo._bookmarks:
3205 opts.setdefault('rev', []).append(b)
3207 opts.setdefault('rev', []).append(b)
3206 else:
3208 else:
3207 # if we try to push a deleted bookmark, translate it to null
3209 # if we try to push a deleted bookmark, translate it to null
3208 # this lets simultaneous -r, -b options continue working
3210 # this lets simultaneous -r, -b options continue working
3209 opts.setdefault('rev', []).append("null")
3211 opts.setdefault('rev', []).append("null")
3210
3212
3211 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3213 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3212 dest, branches = hg.parseurl(dest, opts.get('branch'))
3214 dest, branches = hg.parseurl(dest, opts.get('branch'))
3213 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
3215 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
3214 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
3216 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
3215 other = hg.repository(hg.remoteui(repo, opts), dest)
3217 other = hg.repository(hg.remoteui(repo, opts), dest)
3216 if revs:
3218 if revs:
3217 revs = [repo.lookup(rev) for rev in revs]
3219 revs = [repo.lookup(rev) for rev in revs]
3218
3220
3219 repo._subtoppath = dest
3221 repo._subtoppath = dest
3220 try:
3222 try:
3221 # push subrepos depth-first for coherent ordering
3223 # push subrepos depth-first for coherent ordering
3222 c = repo['']
3224 c = repo['']
3223 subs = c.substate # only repos that are committed
3225 subs = c.substate # only repos that are committed
3224 for s in sorted(subs):
3226 for s in sorted(subs):
3225 if not c.sub(s).push(opts.get('force')):
3227 if not c.sub(s).push(opts.get('force')):
3226 return False
3228 return False
3227 finally:
3229 finally:
3228 del repo._subtoppath
3230 del repo._subtoppath
3229 result = repo.push(other, opts.get('force'), revs=revs,
3231 result = repo.push(other, opts.get('force'), revs=revs,
3230 newbranch=opts.get('new_branch'))
3232 newbranch=opts.get('new_branch'))
3231
3233
3232 result = (result == 0)
3234 result = (result == 0)
3233
3235
3234 if opts.get('bookmark'):
3236 if opts.get('bookmark'):
3235 rb = other.listkeys('bookmarks')
3237 rb = other.listkeys('bookmarks')
3236 for b in opts['bookmark']:
3238 for b in opts['bookmark']:
3237 # explicit push overrides remote bookmark if any
3239 # explicit push overrides remote bookmark if any
3238 if b in repo._bookmarks:
3240 if b in repo._bookmarks:
3239 ui.status(_("exporting bookmark %s\n") % b)
3241 ui.status(_("exporting bookmark %s\n") % b)
3240 new = repo[b].hex()
3242 new = repo[b].hex()
3241 elif b in rb:
3243 elif b in rb:
3242 ui.status(_("deleting remote bookmark %s\n") % b)
3244 ui.status(_("deleting remote bookmark %s\n") % b)
3243 new = '' # delete
3245 new = '' # delete
3244 else:
3246 else:
3245 ui.warn(_('bookmark %s does not exist on the local '
3247 ui.warn(_('bookmark %s does not exist on the local '
3246 'or remote repository!\n') % b)
3248 'or remote repository!\n') % b)
3247 return 2
3249 return 2
3248 old = rb.get(b, '')
3250 old = rb.get(b, '')
3249 r = other.pushkey('bookmarks', b, old, new)
3251 r = other.pushkey('bookmarks', b, old, new)
3250 if not r:
3252 if not r:
3251 ui.warn(_('updating bookmark %s failed!\n') % b)
3253 ui.warn(_('updating bookmark %s failed!\n') % b)
3252 if not result:
3254 if not result:
3253 result = 2
3255 result = 2
3254
3256
3255 return result
3257 return result
3256
3258
3257 def recover(ui, repo):
3259 def recover(ui, repo):
3258 """roll back an interrupted transaction
3260 """roll back an interrupted transaction
3259
3261
3260 Recover from an interrupted commit or pull.
3262 Recover from an interrupted commit or pull.
3261
3263
3262 This command tries to fix the repository status after an
3264 This command tries to fix the repository status after an
3263 interrupted operation. It should only be necessary when Mercurial
3265 interrupted operation. It should only be necessary when Mercurial
3264 suggests it.
3266 suggests it.
3265
3267
3266 Returns 0 if successful, 1 if nothing to recover or verify fails.
3268 Returns 0 if successful, 1 if nothing to recover or verify fails.
3267 """
3269 """
3268 if repo.recover():
3270 if repo.recover():
3269 return hg.verify(repo)
3271 return hg.verify(repo)
3270 return 1
3272 return 1
3271
3273
3272 def remove(ui, repo, *pats, **opts):
3274 def remove(ui, repo, *pats, **opts):
3273 """remove the specified files on the next commit
3275 """remove the specified files on the next commit
3274
3276
3275 Schedule the indicated files for removal from the repository.
3277 Schedule the indicated files for removal from the repository.
3276
3278
3277 This only removes files from the current branch, not from the
3279 This only removes files from the current branch, not from the
3278 entire project history. -A/--after can be used to remove only
3280 entire project history. -A/--after can be used to remove only
3279 files that have already been deleted, -f/--force can be used to
3281 files that have already been deleted, -f/--force can be used to
3280 force deletion, and -Af can be used to remove files from the next
3282 force deletion, and -Af can be used to remove files from the next
3281 revision without deleting them from the working directory.
3283 revision without deleting them from the working directory.
3282
3284
3283 The following table details the behavior of remove for different
3285 The following table details the behavior of remove for different
3284 file states (columns) and option combinations (rows). The file
3286 file states (columns) and option combinations (rows). The file
3285 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
3287 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
3286 reported by :hg:`status`). The actions are Warn, Remove (from
3288 reported by :hg:`status`). The actions are Warn, Remove (from
3287 branch) and Delete (from disk)::
3289 branch) and Delete (from disk)::
3288
3290
3289 A C M !
3291 A C M !
3290 none W RD W R
3292 none W RD W R
3291 -f R RD RD R
3293 -f R RD RD R
3292 -A W W W R
3294 -A W W W R
3293 -Af R R R R
3295 -Af R R R R
3294
3296
3295 This command schedules the files to be removed at the next commit.
3297 This command schedules the files to be removed at the next commit.
3296 To undo a remove before that, see :hg:`revert`.
3298 To undo a remove before that, see :hg:`revert`.
3297
3299
3298 Returns 0 on success, 1 if any warnings encountered.
3300 Returns 0 on success, 1 if any warnings encountered.
3299 """
3301 """
3300
3302
3301 ret = 0
3303 ret = 0
3302 after, force = opts.get('after'), opts.get('force')
3304 after, force = opts.get('after'), opts.get('force')
3303 if not pats and not after:
3305 if not pats and not after:
3304 raise util.Abort(_('no files specified'))
3306 raise util.Abort(_('no files specified'))
3305
3307
3306 m = cmdutil.match(repo, pats, opts)
3308 m = cmdutil.match(repo, pats, opts)
3307 s = repo.status(match=m, clean=True)
3309 s = repo.status(match=m, clean=True)
3308 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
3310 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
3309
3311
3310 for f in m.files():
3312 for f in m.files():
3311 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
3313 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
3312 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
3314 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
3313 ret = 1
3315 ret = 1
3314
3316
3315 if force:
3317 if force:
3316 remove, forget = modified + deleted + clean, added
3318 remove, forget = modified + deleted + clean, added
3317 elif after:
3319 elif after:
3318 remove, forget = deleted, []
3320 remove, forget = deleted, []
3319 for f in modified + added + clean:
3321 for f in modified + added + clean:
3320 ui.warn(_('not removing %s: file still exists (use -f'
3322 ui.warn(_('not removing %s: file still exists (use -f'
3321 ' to force removal)\n') % m.rel(f))
3323 ' to force removal)\n') % m.rel(f))
3322 ret = 1
3324 ret = 1
3323 else:
3325 else:
3324 remove, forget = deleted + clean, []
3326 remove, forget = deleted + clean, []
3325 for f in modified:
3327 for f in modified:
3326 ui.warn(_('not removing %s: file is modified (use -f'
3328 ui.warn(_('not removing %s: file is modified (use -f'
3327 ' to force removal)\n') % m.rel(f))
3329 ' to force removal)\n') % m.rel(f))
3328 ret = 1
3330 ret = 1
3329 for f in added:
3331 for f in added:
3330 ui.warn(_('not removing %s: file has been marked for add (use -f'
3332 ui.warn(_('not removing %s: file has been marked for add (use -f'
3331 ' to force removal)\n') % m.rel(f))
3333 ' to force removal)\n') % m.rel(f))
3332 ret = 1
3334 ret = 1
3333
3335
3334 for f in sorted(remove + forget):
3336 for f in sorted(remove + forget):
3335 if ui.verbose or not m.exact(f):
3337 if ui.verbose or not m.exact(f):
3336 ui.status(_('removing %s\n') % m.rel(f))
3338 ui.status(_('removing %s\n') % m.rel(f))
3337
3339
3338 repo[None].forget(forget)
3340 repo[None].forget(forget)
3339 repo[None].remove(remove, unlink=not after)
3341 repo[None].remove(remove, unlink=not after)
3340 return ret
3342 return ret
3341
3343
3342 def rename(ui, repo, *pats, **opts):
3344 def rename(ui, repo, *pats, **opts):
3343 """rename files; equivalent of copy + remove
3345 """rename files; equivalent of copy + remove
3344
3346
3345 Mark dest as copies of sources; mark sources for deletion. If dest
3347 Mark dest as copies of sources; mark sources for deletion. If dest
3346 is a directory, copies are put in that directory. If dest is a
3348 is a directory, copies are put in that directory. If dest is a
3347 file, there can only be one source.
3349 file, there can only be one source.
3348
3350
3349 By default, this command copies the contents of files as they
3351 By default, this command copies the contents of files as they
3350 exist in the working directory. If invoked with -A/--after, the
3352 exist in the working directory. If invoked with -A/--after, the
3351 operation is recorded, but no copying is performed.
3353 operation is recorded, but no copying is performed.
3352
3354
3353 This command takes effect at the next commit. To undo a rename
3355 This command takes effect at the next commit. To undo a rename
3354 before that, see :hg:`revert`.
3356 before that, see :hg:`revert`.
3355
3357
3356 Returns 0 on success, 1 if errors are encountered.
3358 Returns 0 on success, 1 if errors are encountered.
3357 """
3359 """
3358 wlock = repo.wlock(False)
3360 wlock = repo.wlock(False)
3359 try:
3361 try:
3360 return cmdutil.copy(ui, repo, pats, opts, rename=True)
3362 return cmdutil.copy(ui, repo, pats, opts, rename=True)
3361 finally:
3363 finally:
3362 wlock.release()
3364 wlock.release()
3363
3365
3364 def resolve(ui, repo, *pats, **opts):
3366 def resolve(ui, repo, *pats, **opts):
3365 """redo merges or set/view the merge status of files
3367 """redo merges or set/view the merge status of files
3366
3368
3367 Merges with unresolved conflicts are often the result of
3369 Merges with unresolved conflicts are often the result of
3368 non-interactive merging using the ``internal:merge`` configuration
3370 non-interactive merging using the ``internal:merge`` configuration
3369 setting, or a command-line merge tool like ``diff3``. The resolve
3371 setting, or a command-line merge tool like ``diff3``. The resolve
3370 command is used to manage the files involved in a merge, after
3372 command is used to manage the files involved in a merge, after
3371 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
3373 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
3372 working directory must have two parents).
3374 working directory must have two parents).
3373
3375
3374 The resolve command can be used in the following ways:
3376 The resolve command can be used in the following ways:
3375
3377
3376 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
3378 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
3377 files, discarding any previous merge attempts. Re-merging is not
3379 files, discarding any previous merge attempts. Re-merging is not
3378 performed for files already marked as resolved. Use ``--all/-a``
3380 performed for files already marked as resolved. Use ``--all/-a``
3379 to selects all unresolved files. ``--tool`` can be used to specify
3381 to selects all unresolved files. ``--tool`` can be used to specify
3380 the merge tool used for the given files. It overrides the HGMERGE
3382 the merge tool used for the given files. It overrides the HGMERGE
3381 environment variable and your configuration files.
3383 environment variable and your configuration files.
3382
3384
3383 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
3385 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
3384 (e.g. after having manually fixed-up the files). The default is
3386 (e.g. after having manually fixed-up the files). The default is
3385 to mark all unresolved files.
3387 to mark all unresolved files.
3386
3388
3387 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
3389 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
3388 default is to mark all resolved files.
3390 default is to mark all resolved files.
3389
3391
3390 - :hg:`resolve -l`: list files which had or still have conflicts.
3392 - :hg:`resolve -l`: list files which had or still have conflicts.
3391 In the printed list, ``U`` = unresolved and ``R`` = resolved.
3393 In the printed list, ``U`` = unresolved and ``R`` = resolved.
3392
3394
3393 Note that Mercurial will not let you commit files with unresolved
3395 Note that Mercurial will not let you commit files with unresolved
3394 merge conflicts. You must use :hg:`resolve -m ...` before you can
3396 merge conflicts. You must use :hg:`resolve -m ...` before you can
3395 commit after a conflicting merge.
3397 commit after a conflicting merge.
3396
3398
3397 Returns 0 on success, 1 if any files fail a resolve attempt.
3399 Returns 0 on success, 1 if any files fail a resolve attempt.
3398 """
3400 """
3399
3401
3400 all, mark, unmark, show, nostatus = \
3402 all, mark, unmark, show, nostatus = \
3401 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
3403 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
3402
3404
3403 if (show and (mark or unmark)) or (mark and unmark):
3405 if (show and (mark or unmark)) or (mark and unmark):
3404 raise util.Abort(_("too many options specified"))
3406 raise util.Abort(_("too many options specified"))
3405 if pats and all:
3407 if pats and all:
3406 raise util.Abort(_("can't specify --all and patterns"))
3408 raise util.Abort(_("can't specify --all and patterns"))
3407 if not (all or pats or show or mark or unmark):
3409 if not (all or pats or show or mark or unmark):
3408 raise util.Abort(_('no files or directories specified; '
3410 raise util.Abort(_('no files or directories specified; '
3409 'use --all to remerge all files'))
3411 'use --all to remerge all files'))
3410
3412
3411 ms = mergemod.mergestate(repo)
3413 ms = mergemod.mergestate(repo)
3412 m = cmdutil.match(repo, pats, opts)
3414 m = cmdutil.match(repo, pats, opts)
3413 ret = 0
3415 ret = 0
3414
3416
3415 for f in ms:
3417 for f in ms:
3416 if m(f):
3418 if m(f):
3417 if show:
3419 if show:
3418 if nostatus:
3420 if nostatus:
3419 ui.write("%s\n" % f)
3421 ui.write("%s\n" % f)
3420 else:
3422 else:
3421 ui.write("%s %s\n" % (ms[f].upper(), f),
3423 ui.write("%s %s\n" % (ms[f].upper(), f),
3422 label='resolve.' +
3424 label='resolve.' +
3423 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3425 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3424 elif mark:
3426 elif mark:
3425 ms.mark(f, "r")
3427 ms.mark(f, "r")
3426 elif unmark:
3428 elif unmark:
3427 ms.mark(f, "u")
3429 ms.mark(f, "u")
3428 else:
3430 else:
3429 wctx = repo[None]
3431 wctx = repo[None]
3430 mctx = wctx.parents()[-1]
3432 mctx = wctx.parents()[-1]
3431
3433
3432 # backup pre-resolve (merge uses .orig for its own purposes)
3434 # backup pre-resolve (merge uses .orig for its own purposes)
3433 a = repo.wjoin(f)
3435 a = repo.wjoin(f)
3434 util.copyfile(a, a + ".resolve")
3436 util.copyfile(a, a + ".resolve")
3435
3437
3436 try:
3438 try:
3437 # resolve file
3439 # resolve file
3438 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3440 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3439 if ms.resolve(f, wctx, mctx):
3441 if ms.resolve(f, wctx, mctx):
3440 ret = 1
3442 ret = 1
3441 finally:
3443 finally:
3442 ui.setconfig('ui', 'forcemerge', '')
3444 ui.setconfig('ui', 'forcemerge', '')
3443
3445
3444 # replace filemerge's .orig file with our resolve file
3446 # replace filemerge's .orig file with our resolve file
3445 util.rename(a + ".resolve", a + ".orig")
3447 util.rename(a + ".resolve", a + ".orig")
3446
3448
3447 ms.commit()
3449 ms.commit()
3448 return ret
3450 return ret
3449
3451
3450 def revert(ui, repo, *pats, **opts):
3452 def revert(ui, repo, *pats, **opts):
3451 """restore individual files or directories to an earlier state
3453 """restore individual files or directories to an earlier state
3452
3454
3453 .. note::
3455 .. note::
3454 This command is most likely not what you are looking for.
3456 This command is most likely not what you are looking for.
3455 Revert will partially overwrite content in the working
3457 Revert will partially overwrite content in the working
3456 directory without changing the working directory parents. Use
3458 directory without changing the working directory parents. Use
3457 :hg:`update -r rev` to check out earlier revisions, or
3459 :hg:`update -r rev` to check out earlier revisions, or
3458 :hg:`update --clean .` to undo a merge which has added another
3460 :hg:`update --clean .` to undo a merge which has added another
3459 parent.
3461 parent.
3460
3462
3461 With no revision specified, revert the named files or directories
3463 With no revision specified, revert the named files or directories
3462 to the contents they had in the parent of the working directory.
3464 to the contents they had in the parent of the working directory.
3463 This restores the contents of the affected files to an unmodified
3465 This restores the contents of the affected files to an unmodified
3464 state and unschedules adds, removes, copies, and renames. If the
3466 state and unschedules adds, removes, copies, and renames. If the
3465 working directory has two parents, you must explicitly specify a
3467 working directory has two parents, you must explicitly specify a
3466 revision.
3468 revision.
3467
3469
3468 Using the -r/--rev option, revert the given files or directories
3470 Using the -r/--rev option, revert the given files or directories
3469 to their contents as of a specific revision. This can be helpful
3471 to their contents as of a specific revision. This can be helpful
3470 to "roll back" some or all of an earlier change. See :hg:`help
3472 to "roll back" some or all of an earlier change. See :hg:`help
3471 dates` for a list of formats valid for -d/--date.
3473 dates` for a list of formats valid for -d/--date.
3472
3474
3473 Revert modifies the working directory. It does not commit any
3475 Revert modifies the working directory. It does not commit any
3474 changes, or change the parent of the working directory. If you
3476 changes, or change the parent of the working directory. If you
3475 revert to a revision other than the parent of the working
3477 revert to a revision other than the parent of the working
3476 directory, the reverted files will thus appear modified
3478 directory, the reverted files will thus appear modified
3477 afterwards.
3479 afterwards.
3478
3480
3479 If a file has been deleted, it is restored. Files scheduled for
3481 If a file has been deleted, it is restored. Files scheduled for
3480 addition are just unscheduled and left as they are. If the
3482 addition are just unscheduled and left as they are. If the
3481 executable mode of a file was changed, it is reset.
3483 executable mode of a file was changed, it is reset.
3482
3484
3483 If names are given, all files matching the names are reverted.
3485 If names are given, all files matching the names are reverted.
3484 If no arguments are given, no files are reverted.
3486 If no arguments are given, no files are reverted.
3485
3487
3486 Modified files are saved with a .orig suffix before reverting.
3488 Modified files are saved with a .orig suffix before reverting.
3487 To disable these backups, use --no-backup.
3489 To disable these backups, use --no-backup.
3488
3490
3489 Returns 0 on success.
3491 Returns 0 on success.
3490 """
3492 """
3491
3493
3492 if opts.get("date"):
3494 if opts.get("date"):
3493 if opts.get("rev"):
3495 if opts.get("rev"):
3494 raise util.Abort(_("you can't specify a revision and a date"))
3496 raise util.Abort(_("you can't specify a revision and a date"))
3495 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3497 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3496
3498
3497 parent, p2 = repo.dirstate.parents()
3499 parent, p2 = repo.dirstate.parents()
3498 if not opts.get('rev') and p2 != nullid:
3500 if not opts.get('rev') and p2 != nullid:
3499 raise util.Abort(_('uncommitted merge - '
3501 raise util.Abort(_('uncommitted merge - '
3500 'use "hg update", see "hg help revert"'))
3502 'use "hg update", see "hg help revert"'))
3501
3503
3502 if not pats and not opts.get('all'):
3504 if not pats and not opts.get('all'):
3503 raise util.Abort(_('no files or directories specified; '
3505 raise util.Abort(_('no files or directories specified; '
3504 'use --all to revert the whole repo'))
3506 'use --all to revert the whole repo'))
3505
3507
3506 ctx = cmdutil.revsingle(repo, opts.get('rev'))
3508 ctx = cmdutil.revsingle(repo, opts.get('rev'))
3507 node = ctx.node()
3509 node = ctx.node()
3508 mf = ctx.manifest()
3510 mf = ctx.manifest()
3509 if node == parent:
3511 if node == parent:
3510 pmf = mf
3512 pmf = mf
3511 else:
3513 else:
3512 pmf = None
3514 pmf = None
3513
3515
3514 # need all matching names in dirstate and manifest of target rev,
3516 # need all matching names in dirstate and manifest of target rev,
3515 # so have to walk both. do not print errors if files exist in one
3517 # so have to walk both. do not print errors if files exist in one
3516 # but not other.
3518 # but not other.
3517
3519
3518 names = {}
3520 names = {}
3519
3521
3520 wlock = repo.wlock()
3522 wlock = repo.wlock()
3521 try:
3523 try:
3522 # walk dirstate.
3524 # walk dirstate.
3523
3525
3524 m = cmdutil.match(repo, pats, opts)
3526 m = cmdutil.match(repo, pats, opts)
3525 m.bad = lambda x, y: False
3527 m.bad = lambda x, y: False
3526 for abs in repo.walk(m):
3528 for abs in repo.walk(m):
3527 names[abs] = m.rel(abs), m.exact(abs)
3529 names[abs] = m.rel(abs), m.exact(abs)
3528
3530
3529 # walk target manifest.
3531 # walk target manifest.
3530
3532
3531 def badfn(path, msg):
3533 def badfn(path, msg):
3532 if path in names:
3534 if path in names:
3533 return
3535 return
3534 path_ = path + '/'
3536 path_ = path + '/'
3535 for f in names:
3537 for f in names:
3536 if f.startswith(path_):
3538 if f.startswith(path_):
3537 return
3539 return
3538 ui.warn("%s: %s\n" % (m.rel(path), msg))
3540 ui.warn("%s: %s\n" % (m.rel(path), msg))
3539
3541
3540 m = cmdutil.match(repo, pats, opts)
3542 m = cmdutil.match(repo, pats, opts)
3541 m.bad = badfn
3543 m.bad = badfn
3542 for abs in repo[node].walk(m):
3544 for abs in repo[node].walk(m):
3543 if abs not in names:
3545 if abs not in names:
3544 names[abs] = m.rel(abs), m.exact(abs)
3546 names[abs] = m.rel(abs), m.exact(abs)
3545
3547
3546 m = cmdutil.matchfiles(repo, names)
3548 m = cmdutil.matchfiles(repo, names)
3547 changes = repo.status(match=m)[:4]
3549 changes = repo.status(match=m)[:4]
3548 modified, added, removed, deleted = map(set, changes)
3550 modified, added, removed, deleted = map(set, changes)
3549
3551
3550 # if f is a rename, also revert the source
3552 # if f is a rename, also revert the source
3551 cwd = repo.getcwd()
3553 cwd = repo.getcwd()
3552 for f in added:
3554 for f in added:
3553 src = repo.dirstate.copied(f)
3555 src = repo.dirstate.copied(f)
3554 if src and src not in names and repo.dirstate[src] == 'r':
3556 if src and src not in names and repo.dirstate[src] == 'r':
3555 removed.add(src)
3557 removed.add(src)
3556 names[src] = (repo.pathto(src, cwd), True)
3558 names[src] = (repo.pathto(src, cwd), True)
3557
3559
3558 def removeforget(abs):
3560 def removeforget(abs):
3559 if repo.dirstate[abs] == 'a':
3561 if repo.dirstate[abs] == 'a':
3560 return _('forgetting %s\n')
3562 return _('forgetting %s\n')
3561 return _('removing %s\n')
3563 return _('removing %s\n')
3562
3564
3563 revert = ([], _('reverting %s\n'))
3565 revert = ([], _('reverting %s\n'))
3564 add = ([], _('adding %s\n'))
3566 add = ([], _('adding %s\n'))
3565 remove = ([], removeforget)
3567 remove = ([], removeforget)
3566 undelete = ([], _('undeleting %s\n'))
3568 undelete = ([], _('undeleting %s\n'))
3567
3569
3568 disptable = (
3570 disptable = (
3569 # dispatch table:
3571 # dispatch table:
3570 # file state
3572 # file state
3571 # action if in target manifest
3573 # action if in target manifest
3572 # action if not in target manifest
3574 # action if not in target manifest
3573 # make backup if in target manifest
3575 # make backup if in target manifest
3574 # make backup if not in target manifest
3576 # make backup if not in target manifest
3575 (modified, revert, remove, True, True),
3577 (modified, revert, remove, True, True),
3576 (added, revert, remove, True, False),
3578 (added, revert, remove, True, False),
3577 (removed, undelete, None, False, False),
3579 (removed, undelete, None, False, False),
3578 (deleted, revert, remove, False, False),
3580 (deleted, revert, remove, False, False),
3579 )
3581 )
3580
3582
3581 for abs, (rel, exact) in sorted(names.items()):
3583 for abs, (rel, exact) in sorted(names.items()):
3582 mfentry = mf.get(abs)
3584 mfentry = mf.get(abs)
3583 target = repo.wjoin(abs)
3585 target = repo.wjoin(abs)
3584 def handle(xlist, dobackup):
3586 def handle(xlist, dobackup):
3585 xlist[0].append(abs)
3587 xlist[0].append(abs)
3586 if (dobackup and not opts.get('no_backup') and
3588 if (dobackup and not opts.get('no_backup') and
3587 os.path.lexists(target)):
3589 os.path.lexists(target)):
3588 bakname = "%s.orig" % rel
3590 bakname = "%s.orig" % rel
3589 ui.note(_('saving current version of %s as %s\n') %
3591 ui.note(_('saving current version of %s as %s\n') %
3590 (rel, bakname))
3592 (rel, bakname))
3591 if not opts.get('dry_run'):
3593 if not opts.get('dry_run'):
3592 util.rename(target, bakname)
3594 util.rename(target, bakname)
3593 if ui.verbose or not exact:
3595 if ui.verbose or not exact:
3594 msg = xlist[1]
3596 msg = xlist[1]
3595 if not isinstance(msg, basestring):
3597 if not isinstance(msg, basestring):
3596 msg = msg(abs)
3598 msg = msg(abs)
3597 ui.status(msg % rel)
3599 ui.status(msg % rel)
3598 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3600 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3599 if abs not in table:
3601 if abs not in table:
3600 continue
3602 continue
3601 # file has changed in dirstate
3603 # file has changed in dirstate
3602 if mfentry:
3604 if mfentry:
3603 handle(hitlist, backuphit)
3605 handle(hitlist, backuphit)
3604 elif misslist is not None:
3606 elif misslist is not None:
3605 handle(misslist, backupmiss)
3607 handle(misslist, backupmiss)
3606 break
3608 break
3607 else:
3609 else:
3608 if abs not in repo.dirstate:
3610 if abs not in repo.dirstate:
3609 if mfentry:
3611 if mfentry:
3610 handle(add, True)
3612 handle(add, True)
3611 elif exact:
3613 elif exact:
3612 ui.warn(_('file not managed: %s\n') % rel)
3614 ui.warn(_('file not managed: %s\n') % rel)
3613 continue
3615 continue
3614 # file has not changed in dirstate
3616 # file has not changed in dirstate
3615 if node == parent:
3617 if node == parent:
3616 if exact:
3618 if exact:
3617 ui.warn(_('no changes needed to %s\n') % rel)
3619 ui.warn(_('no changes needed to %s\n') % rel)
3618 continue
3620 continue
3619 if pmf is None:
3621 if pmf is None:
3620 # only need parent manifest in this unlikely case,
3622 # only need parent manifest in this unlikely case,
3621 # so do not read by default
3623 # so do not read by default
3622 pmf = repo[parent].manifest()
3624 pmf = repo[parent].manifest()
3623 if abs in pmf:
3625 if abs in pmf:
3624 if mfentry:
3626 if mfentry:
3625 # if version of file is same in parent and target
3627 # if version of file is same in parent and target
3626 # manifests, do nothing
3628 # manifests, do nothing
3627 if (pmf[abs] != mfentry or
3629 if (pmf[abs] != mfentry or
3628 pmf.flags(abs) != mf.flags(abs)):
3630 pmf.flags(abs) != mf.flags(abs)):
3629 handle(revert, False)
3631 handle(revert, False)
3630 else:
3632 else:
3631 handle(remove, False)
3633 handle(remove, False)
3632
3634
3633 if not opts.get('dry_run'):
3635 if not opts.get('dry_run'):
3634 def checkout(f):
3636 def checkout(f):
3635 fc = ctx[f]
3637 fc = ctx[f]
3636 repo.wwrite(f, fc.data(), fc.flags())
3638 repo.wwrite(f, fc.data(), fc.flags())
3637
3639
3638 audit_path = scmutil.pathauditor(repo.root)
3640 audit_path = scmutil.pathauditor(repo.root)
3639 for f in remove[0]:
3641 for f in remove[0]:
3640 if repo.dirstate[f] == 'a':
3642 if repo.dirstate[f] == 'a':
3641 repo.dirstate.forget(f)
3643 repo.dirstate.forget(f)
3642 continue
3644 continue
3643 audit_path(f)
3645 audit_path(f)
3644 try:
3646 try:
3645 util.unlinkpath(repo.wjoin(f))
3647 util.unlinkpath(repo.wjoin(f))
3646 except OSError:
3648 except OSError:
3647 pass
3649 pass
3648 repo.dirstate.remove(f)
3650 repo.dirstate.remove(f)
3649
3651
3650 normal = None
3652 normal = None
3651 if node == parent:
3653 if node == parent:
3652 # We're reverting to our parent. If possible, we'd like status
3654 # We're reverting to our parent. If possible, we'd like status
3653 # to report the file as clean. We have to use normallookup for
3655 # to report the file as clean. We have to use normallookup for
3654 # merges to avoid losing information about merged/dirty files.
3656 # merges to avoid losing information about merged/dirty files.
3655 if p2 != nullid:
3657 if p2 != nullid:
3656 normal = repo.dirstate.normallookup
3658 normal = repo.dirstate.normallookup
3657 else:
3659 else:
3658 normal = repo.dirstate.normal
3660 normal = repo.dirstate.normal
3659 for f in revert[0]:
3661 for f in revert[0]:
3660 checkout(f)
3662 checkout(f)
3661 if normal:
3663 if normal:
3662 normal(f)
3664 normal(f)
3663
3665
3664 for f in add[0]:
3666 for f in add[0]:
3665 checkout(f)
3667 checkout(f)
3666 repo.dirstate.add(f)
3668 repo.dirstate.add(f)
3667
3669
3668 normal = repo.dirstate.normallookup
3670 normal = repo.dirstate.normallookup
3669 if node == parent and p2 == nullid:
3671 if node == parent and p2 == nullid:
3670 normal = repo.dirstate.normal
3672 normal = repo.dirstate.normal
3671 for f in undelete[0]:
3673 for f in undelete[0]:
3672 checkout(f)
3674 checkout(f)
3673 normal(f)
3675 normal(f)
3674
3676
3675 finally:
3677 finally:
3676 wlock.release()
3678 wlock.release()
3677
3679
3678 def rollback(ui, repo, **opts):
3680 def rollback(ui, repo, **opts):
3679 """roll back the last transaction (dangerous)
3681 """roll back the last transaction (dangerous)
3680
3682
3681 This command should be used with care. There is only one level of
3683 This command should be used with care. There is only one level of
3682 rollback, and there is no way to undo a rollback. It will also
3684 rollback, and there is no way to undo a rollback. It will also
3683 restore the dirstate at the time of the last transaction, losing
3685 restore the dirstate at the time of the last transaction, losing
3684 any dirstate changes since that time. This command does not alter
3686 any dirstate changes since that time. This command does not alter
3685 the working directory.
3687 the working directory.
3686
3688
3687 Transactions are used to encapsulate the effects of all commands
3689 Transactions are used to encapsulate the effects of all commands
3688 that create new changesets or propagate existing changesets into a
3690 that create new changesets or propagate existing changesets into a
3689 repository. For example, the following commands are transactional,
3691 repository. For example, the following commands are transactional,
3690 and their effects can be rolled back:
3692 and their effects can be rolled back:
3691
3693
3692 - commit
3694 - commit
3693 - import
3695 - import
3694 - pull
3696 - pull
3695 - push (with this repository as the destination)
3697 - push (with this repository as the destination)
3696 - unbundle
3698 - unbundle
3697
3699
3698 This command is not intended for use on public repositories. Once
3700 This command is not intended for use on public repositories. Once
3699 changes are visible for pull by other users, rolling a transaction
3701 changes are visible for pull by other users, rolling a transaction
3700 back locally is ineffective (someone else may already have pulled
3702 back locally is ineffective (someone else may already have pulled
3701 the changes). Furthermore, a race is possible with readers of the
3703 the changes). Furthermore, a race is possible with readers of the
3702 repository; for example an in-progress pull from the repository
3704 repository; for example an in-progress pull from the repository
3703 may fail if a rollback is performed.
3705 may fail if a rollback is performed.
3704
3706
3705 Returns 0 on success, 1 if no rollback data is available.
3707 Returns 0 on success, 1 if no rollback data is available.
3706 """
3708 """
3707 return repo.rollback(opts.get('dry_run'))
3709 return repo.rollback(opts.get('dry_run'))
3708
3710
3709 def root(ui, repo):
3711 def root(ui, repo):
3710 """print the root (top) of the current working directory
3712 """print the root (top) of the current working directory
3711
3713
3712 Print the root directory of the current repository.
3714 Print the root directory of the current repository.
3713
3715
3714 Returns 0 on success.
3716 Returns 0 on success.
3715 """
3717 """
3716 ui.write(repo.root + "\n")
3718 ui.write(repo.root + "\n")
3717
3719
3718 def serve(ui, repo, **opts):
3720 def serve(ui, repo, **opts):
3719 """start stand-alone webserver
3721 """start stand-alone webserver
3720
3722
3721 Start a local HTTP repository browser and pull server. You can use
3723 Start a local HTTP repository browser and pull server. You can use
3722 this for ad-hoc sharing and browsing of repositories. It is
3724 this for ad-hoc sharing and browsing of repositories. It is
3723 recommended to use a real web server to serve a repository for
3725 recommended to use a real web server to serve a repository for
3724 longer periods of time.
3726 longer periods of time.
3725
3727
3726 Please note that the server does not implement access control.
3728 Please note that the server does not implement access control.
3727 This means that, by default, anybody can read from the server and
3729 This means that, by default, anybody can read from the server and
3728 nobody can write to it by default. Set the ``web.allow_push``
3730 nobody can write to it by default. Set the ``web.allow_push``
3729 option to ``*`` to allow everybody to push to the server. You
3731 option to ``*`` to allow everybody to push to the server. You
3730 should use a real web server if you need to authenticate users.
3732 should use a real web server if you need to authenticate users.
3731
3733
3732 By default, the server logs accesses to stdout and errors to
3734 By default, the server logs accesses to stdout and errors to
3733 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3735 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3734 files.
3736 files.
3735
3737
3736 To have the server choose a free port number to listen on, specify
3738 To have the server choose a free port number to listen on, specify
3737 a port number of 0; in this case, the server will print the port
3739 a port number of 0; in this case, the server will print the port
3738 number it uses.
3740 number it uses.
3739
3741
3740 Returns 0 on success.
3742 Returns 0 on success.
3741 """
3743 """
3742
3744
3743 if opts["stdio"]:
3745 if opts["stdio"]:
3744 if repo is None:
3746 if repo is None:
3745 raise error.RepoError(_("There is no Mercurial repository here"
3747 raise error.RepoError(_("There is no Mercurial repository here"
3746 " (.hg not found)"))
3748 " (.hg not found)"))
3747 s = sshserver.sshserver(ui, repo)
3749 s = sshserver.sshserver(ui, repo)
3748 s.serve_forever()
3750 s.serve_forever()
3749
3751
3750 # this way we can check if something was given in the command-line
3752 # this way we can check if something was given in the command-line
3751 if opts.get('port'):
3753 if opts.get('port'):
3752 opts['port'] = util.getport(opts.get('port'))
3754 opts['port'] = util.getport(opts.get('port'))
3753
3755
3754 baseui = repo and repo.baseui or ui
3756 baseui = repo and repo.baseui or ui
3755 optlist = ("name templates style address port prefix ipv6"
3757 optlist = ("name templates style address port prefix ipv6"
3756 " accesslog errorlog certificate encoding")
3758 " accesslog errorlog certificate encoding")
3757 for o in optlist.split():
3759 for o in optlist.split():
3758 val = opts.get(o, '')
3760 val = opts.get(o, '')
3759 if val in (None, ''): # should check against default options instead
3761 if val in (None, ''): # should check against default options instead
3760 continue
3762 continue
3761 baseui.setconfig("web", o, val)
3763 baseui.setconfig("web", o, val)
3762 if repo and repo.ui != baseui:
3764 if repo and repo.ui != baseui:
3763 repo.ui.setconfig("web", o, val)
3765 repo.ui.setconfig("web", o, val)
3764
3766
3765 o = opts.get('web_conf') or opts.get('webdir_conf')
3767 o = opts.get('web_conf') or opts.get('webdir_conf')
3766 if not o:
3768 if not o:
3767 if not repo:
3769 if not repo:
3768 raise error.RepoError(_("There is no Mercurial repository"
3770 raise error.RepoError(_("There is no Mercurial repository"
3769 " here (.hg not found)"))
3771 " here (.hg not found)"))
3770 o = repo.root
3772 o = repo.root
3771
3773
3772 app = hgweb.hgweb(o, baseui=ui)
3774 app = hgweb.hgweb(o, baseui=ui)
3773
3775
3774 class service(object):
3776 class service(object):
3775 def init(self):
3777 def init(self):
3776 util.setsignalhandler()
3778 util.setsignalhandler()
3777 self.httpd = hgweb.server.create_server(ui, app)
3779 self.httpd = hgweb.server.create_server(ui, app)
3778
3780
3779 if opts['port'] and not ui.verbose:
3781 if opts['port'] and not ui.verbose:
3780 return
3782 return
3781
3783
3782 if self.httpd.prefix:
3784 if self.httpd.prefix:
3783 prefix = self.httpd.prefix.strip('/') + '/'
3785 prefix = self.httpd.prefix.strip('/') + '/'
3784 else:
3786 else:
3785 prefix = ''
3787 prefix = ''
3786
3788
3787 port = ':%d' % self.httpd.port
3789 port = ':%d' % self.httpd.port
3788 if port == ':80':
3790 if port == ':80':
3789 port = ''
3791 port = ''
3790
3792
3791 bindaddr = self.httpd.addr
3793 bindaddr = self.httpd.addr
3792 if bindaddr == '0.0.0.0':
3794 if bindaddr == '0.0.0.0':
3793 bindaddr = '*'
3795 bindaddr = '*'
3794 elif ':' in bindaddr: # IPv6
3796 elif ':' in bindaddr: # IPv6
3795 bindaddr = '[%s]' % bindaddr
3797 bindaddr = '[%s]' % bindaddr
3796
3798
3797 fqaddr = self.httpd.fqaddr
3799 fqaddr = self.httpd.fqaddr
3798 if ':' in fqaddr:
3800 if ':' in fqaddr:
3799 fqaddr = '[%s]' % fqaddr
3801 fqaddr = '[%s]' % fqaddr
3800 if opts['port']:
3802 if opts['port']:
3801 write = ui.status
3803 write = ui.status
3802 else:
3804 else:
3803 write = ui.write
3805 write = ui.write
3804 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3806 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3805 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3807 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3806
3808
3807 def run(self):
3809 def run(self):
3808 self.httpd.serve_forever()
3810 self.httpd.serve_forever()
3809
3811
3810 service = service()
3812 service = service()
3811
3813
3812 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3814 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3813
3815
3814 def status(ui, repo, *pats, **opts):
3816 def status(ui, repo, *pats, **opts):
3815 """show changed files in the working directory
3817 """show changed files in the working directory
3816
3818
3817 Show status of files in the repository. If names are given, only
3819 Show status of files in the repository. If names are given, only
3818 files that match are shown. Files that are clean or ignored or
3820 files that match are shown. Files that are clean or ignored or
3819 the source of a copy/move operation, are not listed unless
3821 the source of a copy/move operation, are not listed unless
3820 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3822 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3821 Unless options described with "show only ..." are given, the
3823 Unless options described with "show only ..." are given, the
3822 options -mardu are used.
3824 options -mardu are used.
3823
3825
3824 Option -q/--quiet hides untracked (unknown and ignored) files
3826 Option -q/--quiet hides untracked (unknown and ignored) files
3825 unless explicitly requested with -u/--unknown or -i/--ignored.
3827 unless explicitly requested with -u/--unknown or -i/--ignored.
3826
3828
3827 .. note::
3829 .. note::
3828 status may appear to disagree with diff if permissions have
3830 status may appear to disagree with diff if permissions have
3829 changed or a merge has occurred. The standard diff format does
3831 changed or a merge has occurred. The standard diff format does
3830 not report permission changes and diff only reports changes
3832 not report permission changes and diff only reports changes
3831 relative to one merge parent.
3833 relative to one merge parent.
3832
3834
3833 If one revision is given, it is used as the base revision.
3835 If one revision is given, it is used as the base revision.
3834 If two revisions are given, the differences between them are
3836 If two revisions are given, the differences between them are
3835 shown. The --change option can also be used as a shortcut to list
3837 shown. The --change option can also be used as a shortcut to list
3836 the changed files of a revision from its first parent.
3838 the changed files of a revision from its first parent.
3837
3839
3838 The codes used to show the status of files are::
3840 The codes used to show the status of files are::
3839
3841
3840 M = modified
3842 M = modified
3841 A = added
3843 A = added
3842 R = removed
3844 R = removed
3843 C = clean
3845 C = clean
3844 ! = missing (deleted by non-hg command, but still tracked)
3846 ! = missing (deleted by non-hg command, but still tracked)
3845 ? = not tracked
3847 ? = not tracked
3846 I = ignored
3848 I = ignored
3847 = origin of the previous file listed as A (added)
3849 = origin of the previous file listed as A (added)
3848
3850
3849 Returns 0 on success.
3851 Returns 0 on success.
3850 """
3852 """
3851
3853
3852 revs = opts.get('rev')
3854 revs = opts.get('rev')
3853 change = opts.get('change')
3855 change = opts.get('change')
3854
3856
3855 if revs and change:
3857 if revs and change:
3856 msg = _('cannot specify --rev and --change at the same time')
3858 msg = _('cannot specify --rev and --change at the same time')
3857 raise util.Abort(msg)
3859 raise util.Abort(msg)
3858 elif change:
3860 elif change:
3859 node2 = repo.lookup(change)
3861 node2 = repo.lookup(change)
3860 node1 = repo[node2].p1().node()
3862 node1 = repo[node2].p1().node()
3861 else:
3863 else:
3862 node1, node2 = cmdutil.revpair(repo, revs)
3864 node1, node2 = cmdutil.revpair(repo, revs)
3863
3865
3864 cwd = (pats and repo.getcwd()) or ''
3866 cwd = (pats and repo.getcwd()) or ''
3865 end = opts.get('print0') and '\0' or '\n'
3867 end = opts.get('print0') and '\0' or '\n'
3866 copy = {}
3868 copy = {}
3867 states = 'modified added removed deleted unknown ignored clean'.split()
3869 states = 'modified added removed deleted unknown ignored clean'.split()
3868 show = [k for k in states if opts.get(k)]
3870 show = [k for k in states if opts.get(k)]
3869 if opts.get('all'):
3871 if opts.get('all'):
3870 show += ui.quiet and (states[:4] + ['clean']) or states
3872 show += ui.quiet and (states[:4] + ['clean']) or states
3871 if not show:
3873 if not show:
3872 show = ui.quiet and states[:4] or states[:5]
3874 show = ui.quiet and states[:4] or states[:5]
3873
3875
3874 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3876 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3875 'ignored' in show, 'clean' in show, 'unknown' in show,
3877 'ignored' in show, 'clean' in show, 'unknown' in show,
3876 opts.get('subrepos'))
3878 opts.get('subrepos'))
3877 changestates = zip(states, 'MAR!?IC', stat)
3879 changestates = zip(states, 'MAR!?IC', stat)
3878
3880
3879 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3881 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3880 ctxn = repo[nullid]
3882 ctxn = repo[nullid]
3881 ctx1 = repo[node1]
3883 ctx1 = repo[node1]
3882 ctx2 = repo[node2]
3884 ctx2 = repo[node2]
3883 added = stat[1]
3885 added = stat[1]
3884 if node2 is None:
3886 if node2 is None:
3885 added = stat[0] + stat[1] # merged?
3887 added = stat[0] + stat[1] # merged?
3886
3888
3887 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3889 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3888 if k in added:
3890 if k in added:
3889 copy[k] = v
3891 copy[k] = v
3890 elif v in added:
3892 elif v in added:
3891 copy[v] = k
3893 copy[v] = k
3892
3894
3893 for state, char, files in changestates:
3895 for state, char, files in changestates:
3894 if state in show:
3896 if state in show:
3895 format = "%s %%s%s" % (char, end)
3897 format = "%s %%s%s" % (char, end)
3896 if opts.get('no_status'):
3898 if opts.get('no_status'):
3897 format = "%%s%s" % end
3899 format = "%%s%s" % end
3898
3900
3899 for f in files:
3901 for f in files:
3900 ui.write(format % repo.pathto(f, cwd),
3902 ui.write(format % repo.pathto(f, cwd),
3901 label='status.' + state)
3903 label='status.' + state)
3902 if f in copy:
3904 if f in copy:
3903 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3905 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3904 label='status.copied')
3906 label='status.copied')
3905
3907
3906 def summary(ui, repo, **opts):
3908 def summary(ui, repo, **opts):
3907 """summarize working directory state
3909 """summarize working directory state
3908
3910
3909 This generates a brief summary of the working directory state,
3911 This generates a brief summary of the working directory state,
3910 including parents, branch, commit status, and available updates.
3912 including parents, branch, commit status, and available updates.
3911
3913
3912 With the --remote option, this will check the default paths for
3914 With the --remote option, this will check the default paths for
3913 incoming and outgoing changes. This can be time-consuming.
3915 incoming and outgoing changes. This can be time-consuming.
3914
3916
3915 Returns 0 on success.
3917 Returns 0 on success.
3916 """
3918 """
3917
3919
3918 ctx = repo[None]
3920 ctx = repo[None]
3919 parents = ctx.parents()
3921 parents = ctx.parents()
3920 pnode = parents[0].node()
3922 pnode = parents[0].node()
3921
3923
3922 for p in parents:
3924 for p in parents:
3923 # label with log.changeset (instead of log.parent) since this
3925 # label with log.changeset (instead of log.parent) since this
3924 # shows a working directory parent *changeset*:
3926 # shows a working directory parent *changeset*:
3925 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3927 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3926 label='log.changeset')
3928 label='log.changeset')
3927 ui.write(' '.join(p.tags()), label='log.tag')
3929 ui.write(' '.join(p.tags()), label='log.tag')
3928 if p.bookmarks():
3930 if p.bookmarks():
3929 ui.write(' ' + ' '.join(p.bookmarks()), label='log.bookmark')
3931 ui.write(' ' + ' '.join(p.bookmarks()), label='log.bookmark')
3930 if p.rev() == -1:
3932 if p.rev() == -1:
3931 if not len(repo):
3933 if not len(repo):
3932 ui.write(_(' (empty repository)'))
3934 ui.write(_(' (empty repository)'))
3933 else:
3935 else:
3934 ui.write(_(' (no revision checked out)'))
3936 ui.write(_(' (no revision checked out)'))
3935 ui.write('\n')
3937 ui.write('\n')
3936 if p.description():
3938 if p.description():
3937 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3939 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3938 label='log.summary')
3940 label='log.summary')
3939
3941
3940 branch = ctx.branch()
3942 branch = ctx.branch()
3941 bheads = repo.branchheads(branch)
3943 bheads = repo.branchheads(branch)
3942 m = _('branch: %s\n') % branch
3944 m = _('branch: %s\n') % branch
3943 if branch != 'default':
3945 if branch != 'default':
3944 ui.write(m, label='log.branch')
3946 ui.write(m, label='log.branch')
3945 else:
3947 else:
3946 ui.status(m, label='log.branch')
3948 ui.status(m, label='log.branch')
3947
3949
3948 st = list(repo.status(unknown=True))[:6]
3950 st = list(repo.status(unknown=True))[:6]
3949
3951
3950 c = repo.dirstate.copies()
3952 c = repo.dirstate.copies()
3951 copied, renamed = [], []
3953 copied, renamed = [], []
3952 for d, s in c.iteritems():
3954 for d, s in c.iteritems():
3953 if s in st[2]:
3955 if s in st[2]:
3954 st[2].remove(s)
3956 st[2].remove(s)
3955 renamed.append(d)
3957 renamed.append(d)
3956 else:
3958 else:
3957 copied.append(d)
3959 copied.append(d)
3958 if d in st[1]:
3960 if d in st[1]:
3959 st[1].remove(d)
3961 st[1].remove(d)
3960 st.insert(3, renamed)
3962 st.insert(3, renamed)
3961 st.insert(4, copied)
3963 st.insert(4, copied)
3962
3964
3963 ms = mergemod.mergestate(repo)
3965 ms = mergemod.mergestate(repo)
3964 st.append([f for f in ms if ms[f] == 'u'])
3966 st.append([f for f in ms if ms[f] == 'u'])
3965
3967
3966 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3968 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3967 st.append(subs)
3969 st.append(subs)
3968
3970
3969 labels = [ui.label(_('%d modified'), 'status.modified'),
3971 labels = [ui.label(_('%d modified'), 'status.modified'),
3970 ui.label(_('%d added'), 'status.added'),
3972 ui.label(_('%d added'), 'status.added'),
3971 ui.label(_('%d removed'), 'status.removed'),
3973 ui.label(_('%d removed'), 'status.removed'),
3972 ui.label(_('%d renamed'), 'status.copied'),
3974 ui.label(_('%d renamed'), 'status.copied'),
3973 ui.label(_('%d copied'), 'status.copied'),
3975 ui.label(_('%d copied'), 'status.copied'),
3974 ui.label(_('%d deleted'), 'status.deleted'),
3976 ui.label(_('%d deleted'), 'status.deleted'),
3975 ui.label(_('%d unknown'), 'status.unknown'),
3977 ui.label(_('%d unknown'), 'status.unknown'),
3976 ui.label(_('%d ignored'), 'status.ignored'),
3978 ui.label(_('%d ignored'), 'status.ignored'),
3977 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3979 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3978 ui.label(_('%d subrepos'), 'status.modified')]
3980 ui.label(_('%d subrepos'), 'status.modified')]
3979 t = []
3981 t = []
3980 for s, l in zip(st, labels):
3982 for s, l in zip(st, labels):
3981 if s:
3983 if s:
3982 t.append(l % len(s))
3984 t.append(l % len(s))
3983
3985
3984 t = ', '.join(t)
3986 t = ', '.join(t)
3985 cleanworkdir = False
3987 cleanworkdir = False
3986
3988
3987 if len(parents) > 1:
3989 if len(parents) > 1:
3988 t += _(' (merge)')
3990 t += _(' (merge)')
3989 elif branch != parents[0].branch():
3991 elif branch != parents[0].branch():
3990 t += _(' (new branch)')
3992 t += _(' (new branch)')
3991 elif (parents[0].extra().get('close') and
3993 elif (parents[0].extra().get('close') and
3992 pnode in repo.branchheads(branch, closed=True)):
3994 pnode in repo.branchheads(branch, closed=True)):
3993 t += _(' (head closed)')
3995 t += _(' (head closed)')
3994 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3996 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3995 t += _(' (clean)')
3997 t += _(' (clean)')
3996 cleanworkdir = True
3998 cleanworkdir = True
3997 elif pnode not in bheads:
3999 elif pnode not in bheads:
3998 t += _(' (new branch head)')
4000 t += _(' (new branch head)')
3999
4001
4000 if cleanworkdir:
4002 if cleanworkdir:
4001 ui.status(_('commit: %s\n') % t.strip())
4003 ui.status(_('commit: %s\n') % t.strip())
4002 else:
4004 else:
4003 ui.write(_('commit: %s\n') % t.strip())
4005 ui.write(_('commit: %s\n') % t.strip())
4004
4006
4005 # all ancestors of branch heads - all ancestors of parent = new csets
4007 # all ancestors of branch heads - all ancestors of parent = new csets
4006 new = [0] * len(repo)
4008 new = [0] * len(repo)
4007 cl = repo.changelog
4009 cl = repo.changelog
4008 for a in [cl.rev(n) for n in bheads]:
4010 for a in [cl.rev(n) for n in bheads]:
4009 new[a] = 1
4011 new[a] = 1
4010 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
4012 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
4011 new[a] = 1
4013 new[a] = 1
4012 for a in [p.rev() for p in parents]:
4014 for a in [p.rev() for p in parents]:
4013 if a >= 0:
4015 if a >= 0:
4014 new[a] = 0
4016 new[a] = 0
4015 for a in cl.ancestors(*[p.rev() for p in parents]):
4017 for a in cl.ancestors(*[p.rev() for p in parents]):
4016 new[a] = 0
4018 new[a] = 0
4017 new = sum(new)
4019 new = sum(new)
4018
4020
4019 if new == 0:
4021 if new == 0:
4020 ui.status(_('update: (current)\n'))
4022 ui.status(_('update: (current)\n'))
4021 elif pnode not in bheads:
4023 elif pnode not in bheads:
4022 ui.write(_('update: %d new changesets (update)\n') % new)
4024 ui.write(_('update: %d new changesets (update)\n') % new)
4023 else:
4025 else:
4024 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
4026 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
4025 (new, len(bheads)))
4027 (new, len(bheads)))
4026
4028
4027 if opts.get('remote'):
4029 if opts.get('remote'):
4028 t = []
4030 t = []
4029 source, branches = hg.parseurl(ui.expandpath('default'))
4031 source, branches = hg.parseurl(ui.expandpath('default'))
4030 other = hg.repository(hg.remoteui(repo, {}), source)
4032 other = hg.repository(hg.remoteui(repo, {}), source)
4031 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
4033 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
4032 ui.debug('comparing with %s\n' % util.hidepassword(source))
4034 ui.debug('comparing with %s\n' % util.hidepassword(source))
4033 repo.ui.pushbuffer()
4035 repo.ui.pushbuffer()
4034 commoninc = discovery.findcommonincoming(repo, other)
4036 commoninc = discovery.findcommonincoming(repo, other)
4035 _common, incoming, _rheads = commoninc
4037 _common, incoming, _rheads = commoninc
4036 repo.ui.popbuffer()
4038 repo.ui.popbuffer()
4037 if incoming:
4039 if incoming:
4038 t.append(_('1 or more incoming'))
4040 t.append(_('1 or more incoming'))
4039
4041
4040 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
4042 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
4041 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
4043 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
4042 if source != dest:
4044 if source != dest:
4043 other = hg.repository(hg.remoteui(repo, {}), dest)
4045 other = hg.repository(hg.remoteui(repo, {}), dest)
4044 commoninc = None
4046 commoninc = None
4045 ui.debug('comparing with %s\n' % util.hidepassword(dest))
4047 ui.debug('comparing with %s\n' % util.hidepassword(dest))
4046 repo.ui.pushbuffer()
4048 repo.ui.pushbuffer()
4047 common, outheads = discovery.findcommonoutgoing(repo, other,
4049 common, outheads = discovery.findcommonoutgoing(repo, other,
4048 commoninc=commoninc)
4050 commoninc=commoninc)
4049 repo.ui.popbuffer()
4051 repo.ui.popbuffer()
4050 o = repo.changelog.findmissing(common=common, heads=outheads)
4052 o = repo.changelog.findmissing(common=common, heads=outheads)
4051 if o:
4053 if o:
4052 t.append(_('%d outgoing') % len(o))
4054 t.append(_('%d outgoing') % len(o))
4053 if 'bookmarks' in other.listkeys('namespaces'):
4055 if 'bookmarks' in other.listkeys('namespaces'):
4054 lmarks = repo.listkeys('bookmarks')
4056 lmarks = repo.listkeys('bookmarks')
4055 rmarks = other.listkeys('bookmarks')
4057 rmarks = other.listkeys('bookmarks')
4056 diff = set(rmarks) - set(lmarks)
4058 diff = set(rmarks) - set(lmarks)
4057 if len(diff) > 0:
4059 if len(diff) > 0:
4058 t.append(_('%d incoming bookmarks') % len(diff))
4060 t.append(_('%d incoming bookmarks') % len(diff))
4059 diff = set(lmarks) - set(rmarks)
4061 diff = set(lmarks) - set(rmarks)
4060 if len(diff) > 0:
4062 if len(diff) > 0:
4061 t.append(_('%d outgoing bookmarks') % len(diff))
4063 t.append(_('%d outgoing bookmarks') % len(diff))
4062
4064
4063 if t:
4065 if t:
4064 ui.write(_('remote: %s\n') % (', '.join(t)))
4066 ui.write(_('remote: %s\n') % (', '.join(t)))
4065 else:
4067 else:
4066 ui.status(_('remote: (synced)\n'))
4068 ui.status(_('remote: (synced)\n'))
4067
4069
4068 def tag(ui, repo, name1, *names, **opts):
4070 def tag(ui, repo, name1, *names, **opts):
4069 """add one or more tags for the current or given revision
4071 """add one or more tags for the current or given revision
4070
4072
4071 Name a particular revision using <name>.
4073 Name a particular revision using <name>.
4072
4074
4073 Tags are used to name particular revisions of the repository and are
4075 Tags are used to name particular revisions of the repository and are
4074 very useful to compare different revisions, to go back to significant
4076 very useful to compare different revisions, to go back to significant
4075 earlier versions or to mark branch points as releases, etc. Changing
4077 earlier versions or to mark branch points as releases, etc. Changing
4076 an existing tag is normally disallowed; use -f/--force to override.
4078 an existing tag is normally disallowed; use -f/--force to override.
4077
4079
4078 If no revision is given, the parent of the working directory is
4080 If no revision is given, the parent of the working directory is
4079 used, or tip if no revision is checked out.
4081 used, or tip if no revision is checked out.
4080
4082
4081 To facilitate version control, distribution, and merging of tags,
4083 To facilitate version control, distribution, and merging of tags,
4082 they are stored as a file named ".hgtags" which is managed similarly
4084 they are stored as a file named ".hgtags" which is managed similarly
4083 to other project files and can be hand-edited if necessary. This
4085 to other project files and can be hand-edited if necessary. This
4084 also means that tagging creates a new commit. The file
4086 also means that tagging creates a new commit. The file
4085 ".hg/localtags" is used for local tags (not shared among
4087 ".hg/localtags" is used for local tags (not shared among
4086 repositories).
4088 repositories).
4087
4089
4088 Tag commits are usually made at the head of a branch. If the parent
4090 Tag commits are usually made at the head of a branch. If the parent
4089 of the working directory is not a branch head, :hg:`tag` aborts; use
4091 of the working directory is not a branch head, :hg:`tag` aborts; use
4090 -f/--force to force the tag commit to be based on a non-head
4092 -f/--force to force the tag commit to be based on a non-head
4091 changeset.
4093 changeset.
4092
4094
4093 See :hg:`help dates` for a list of formats valid for -d/--date.
4095 See :hg:`help dates` for a list of formats valid for -d/--date.
4094
4096
4095 Since tag names have priority over branch names during revision
4097 Since tag names have priority over branch names during revision
4096 lookup, using an existing branch name as a tag name is discouraged.
4098 lookup, using an existing branch name as a tag name is discouraged.
4097
4099
4098 Returns 0 on success.
4100 Returns 0 on success.
4099 """
4101 """
4100
4102
4101 rev_ = "."
4103 rev_ = "."
4102 names = [t.strip() for t in (name1,) + names]
4104 names = [t.strip() for t in (name1,) + names]
4103 if len(names) != len(set(names)):
4105 if len(names) != len(set(names)):
4104 raise util.Abort(_('tag names must be unique'))
4106 raise util.Abort(_('tag names must be unique'))
4105 for n in names:
4107 for n in names:
4106 if n in ['tip', '.', 'null']:
4108 if n in ['tip', '.', 'null']:
4107 raise util.Abort(_("the name '%s' is reserved") % n)
4109 raise util.Abort(_("the name '%s' is reserved") % n)
4108 if not n:
4110 if not n:
4109 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
4111 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
4110 if opts.get('rev') and opts.get('remove'):
4112 if opts.get('rev') and opts.get('remove'):
4111 raise util.Abort(_("--rev and --remove are incompatible"))
4113 raise util.Abort(_("--rev and --remove are incompatible"))
4112 if opts.get('rev'):
4114 if opts.get('rev'):
4113 rev_ = opts['rev']
4115 rev_ = opts['rev']
4114 message = opts.get('message')
4116 message = opts.get('message')
4115 if opts.get('remove'):
4117 if opts.get('remove'):
4116 expectedtype = opts.get('local') and 'local' or 'global'
4118 expectedtype = opts.get('local') and 'local' or 'global'
4117 for n in names:
4119 for n in names:
4118 if not repo.tagtype(n):
4120 if not repo.tagtype(n):
4119 raise util.Abort(_("tag '%s' does not exist") % n)
4121 raise util.Abort(_("tag '%s' does not exist") % n)
4120 if repo.tagtype(n) != expectedtype:
4122 if repo.tagtype(n) != expectedtype:
4121 if expectedtype == 'global':
4123 if expectedtype == 'global':
4122 raise util.Abort(_("tag '%s' is not a global tag") % n)
4124 raise util.Abort(_("tag '%s' is not a global tag") % n)
4123 else:
4125 else:
4124 raise util.Abort(_("tag '%s' is not a local tag") % n)
4126 raise util.Abort(_("tag '%s' is not a local tag") % n)
4125 rev_ = nullid
4127 rev_ = nullid
4126 if not message:
4128 if not message:
4127 # we don't translate commit messages
4129 # we don't translate commit messages
4128 message = 'Removed tag %s' % ', '.join(names)
4130 message = 'Removed tag %s' % ', '.join(names)
4129 elif not opts.get('force'):
4131 elif not opts.get('force'):
4130 for n in names:
4132 for n in names:
4131 if n in repo.tags():
4133 if n in repo.tags():
4132 raise util.Abort(_("tag '%s' already exists "
4134 raise util.Abort(_("tag '%s' already exists "
4133 "(use -f to force)") % n)
4135 "(use -f to force)") % n)
4134 if not opts.get('local'):
4136 if not opts.get('local'):
4135 p1, p2 = repo.dirstate.parents()
4137 p1, p2 = repo.dirstate.parents()
4136 if p2 != nullid:
4138 if p2 != nullid:
4137 raise util.Abort(_('uncommitted merge'))
4139 raise util.Abort(_('uncommitted merge'))
4138 bheads = repo.branchheads()
4140 bheads = repo.branchheads()
4139 if not opts.get('force') and bheads and p1 not in bheads:
4141 if not opts.get('force') and bheads and p1 not in bheads:
4140 raise util.Abort(_('not at a branch head (use -f to force)'))
4142 raise util.Abort(_('not at a branch head (use -f to force)'))
4141 r = cmdutil.revsingle(repo, rev_).node()
4143 r = cmdutil.revsingle(repo, rev_).node()
4142
4144
4143 if not message:
4145 if not message:
4144 # we don't translate commit messages
4146 # we don't translate commit messages
4145 message = ('Added tag %s for changeset %s' %
4147 message = ('Added tag %s for changeset %s' %
4146 (', '.join(names), short(r)))
4148 (', '.join(names), short(r)))
4147
4149
4148 date = opts.get('date')
4150 date = opts.get('date')
4149 if date:
4151 if date:
4150 date = util.parsedate(date)
4152 date = util.parsedate(date)
4151
4153
4152 if opts.get('edit'):
4154 if opts.get('edit'):
4153 message = ui.edit(message, ui.username())
4155 message = ui.edit(message, ui.username())
4154
4156
4155 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
4157 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
4156
4158
4157 def tags(ui, repo):
4159 def tags(ui, repo):
4158 """list repository tags
4160 """list repository tags
4159
4161
4160 This lists both regular and local tags. When the -v/--verbose
4162 This lists both regular and local tags. When the -v/--verbose
4161 switch is used, a third column "local" is printed for local tags.
4163 switch is used, a third column "local" is printed for local tags.
4162
4164
4163 Returns 0 on success.
4165 Returns 0 on success.
4164 """
4166 """
4165
4167
4166 hexfunc = ui.debugflag and hex or short
4168 hexfunc = ui.debugflag and hex or short
4167 tagtype = ""
4169 tagtype = ""
4168
4170
4169 for t, n in reversed(repo.tagslist()):
4171 for t, n in reversed(repo.tagslist()):
4170 if ui.quiet:
4172 if ui.quiet:
4171 ui.write("%s\n" % t)
4173 ui.write("%s\n" % t)
4172 continue
4174 continue
4173
4175
4174 hn = hexfunc(n)
4176 hn = hexfunc(n)
4175 r = "%5d:%s" % (repo.changelog.rev(n), hn)
4177 r = "%5d:%s" % (repo.changelog.rev(n), hn)
4176 spaces = " " * (30 - encoding.colwidth(t))
4178 spaces = " " * (30 - encoding.colwidth(t))
4177
4179
4178 if ui.verbose:
4180 if ui.verbose:
4179 if repo.tagtype(t) == 'local':
4181 if repo.tagtype(t) == 'local':
4180 tagtype = " local"
4182 tagtype = " local"
4181 else:
4183 else:
4182 tagtype = ""
4184 tagtype = ""
4183 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
4185 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
4184
4186
4185 def tip(ui, repo, **opts):
4187 def tip(ui, repo, **opts):
4186 """show the tip revision
4188 """show the tip revision
4187
4189
4188 The tip revision (usually just called the tip) is the changeset
4190 The tip revision (usually just called the tip) is the changeset
4189 most recently added to the repository (and therefore the most
4191 most recently added to the repository (and therefore the most
4190 recently changed head).
4192 recently changed head).
4191
4193
4192 If you have just made a commit, that commit will be the tip. If
4194 If you have just made a commit, that commit will be the tip. If
4193 you have just pulled changes from another repository, the tip of
4195 you have just pulled changes from another repository, the tip of
4194 that repository becomes the current tip. The "tip" tag is special
4196 that repository becomes the current tip. The "tip" tag is special
4195 and cannot be renamed or assigned to a different changeset.
4197 and cannot be renamed or assigned to a different changeset.
4196
4198
4197 Returns 0 on success.
4199 Returns 0 on success.
4198 """
4200 """
4199 displayer = cmdutil.show_changeset(ui, repo, opts)
4201 displayer = cmdutil.show_changeset(ui, repo, opts)
4200 displayer.show(repo[len(repo) - 1])
4202 displayer.show(repo[len(repo) - 1])
4201 displayer.close()
4203 displayer.close()
4202
4204
4203 def unbundle(ui, repo, fname1, *fnames, **opts):
4205 def unbundle(ui, repo, fname1, *fnames, **opts):
4204 """apply one or more changegroup files
4206 """apply one or more changegroup files
4205
4207
4206 Apply one or more compressed changegroup files generated by the
4208 Apply one or more compressed changegroup files generated by the
4207 bundle command.
4209 bundle command.
4208
4210
4209 Returns 0 on success, 1 if an update has unresolved files.
4211 Returns 0 on success, 1 if an update has unresolved files.
4210 """
4212 """
4211 fnames = (fname1,) + fnames
4213 fnames = (fname1,) + fnames
4212
4214
4213 lock = repo.lock()
4215 lock = repo.lock()
4214 wc = repo['.']
4216 wc = repo['.']
4215 try:
4217 try:
4216 for fname in fnames:
4218 for fname in fnames:
4217 f = url.open(ui, fname)
4219 f = url.open(ui, fname)
4218 gen = changegroup.readbundle(f, fname)
4220 gen = changegroup.readbundle(f, fname)
4219 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
4221 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
4220 lock=lock)
4222 lock=lock)
4221 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
4223 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
4222 finally:
4224 finally:
4223 lock.release()
4225 lock.release()
4224 return postincoming(ui, repo, modheads, opts.get('update'), None)
4226 return postincoming(ui, repo, modheads, opts.get('update'), None)
4225
4227
4226 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
4228 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
4227 """update working directory (or switch revisions)
4229 """update working directory (or switch revisions)
4228
4230
4229 Update the repository's working directory to the specified
4231 Update the repository's working directory to the specified
4230 changeset. If no changeset is specified, update to the tip of the
4232 changeset. If no changeset is specified, update to the tip of the
4231 current named branch.
4233 current named branch.
4232
4234
4233 If the changeset is not a descendant of the working directory's
4235 If the changeset is not a descendant of the working directory's
4234 parent, the update is aborted. With the -c/--check option, the
4236 parent, the update is aborted. With the -c/--check option, the
4235 working directory is checked for uncommitted changes; if none are
4237 working directory is checked for uncommitted changes; if none are
4236 found, the working directory is updated to the specified
4238 found, the working directory is updated to the specified
4237 changeset.
4239 changeset.
4238
4240
4239 The following rules apply when the working directory contains
4241 The following rules apply when the working directory contains
4240 uncommitted changes:
4242 uncommitted changes:
4241
4243
4242 1. If neither -c/--check nor -C/--clean is specified, and if
4244 1. If neither -c/--check nor -C/--clean is specified, and if
4243 the requested changeset is an ancestor or descendant of
4245 the requested changeset is an ancestor or descendant of
4244 the working directory's parent, the uncommitted changes
4246 the working directory's parent, the uncommitted changes
4245 are merged into the requested changeset and the merged
4247 are merged into the requested changeset and the merged
4246 result is left uncommitted. If the requested changeset is
4248 result is left uncommitted. If the requested changeset is
4247 not an ancestor or descendant (that is, it is on another
4249 not an ancestor or descendant (that is, it is on another
4248 branch), the update is aborted and the uncommitted changes
4250 branch), the update is aborted and the uncommitted changes
4249 are preserved.
4251 are preserved.
4250
4252
4251 2. With the -c/--check option, the update is aborted and the
4253 2. With the -c/--check option, the update is aborted and the
4252 uncommitted changes are preserved.
4254 uncommitted changes are preserved.
4253
4255
4254 3. With the -C/--clean option, uncommitted changes are discarded and
4256 3. With the -C/--clean option, uncommitted changes are discarded and
4255 the working directory is updated to the requested changeset.
4257 the working directory is updated to the requested changeset.
4256
4258
4257 Use null as the changeset to remove the working directory (like
4259 Use null as the changeset to remove the working directory (like
4258 :hg:`clone -U`).
4260 :hg:`clone -U`).
4259
4261
4260 If you want to update just one file to an older changeset, use
4262 If you want to update just one file to an older changeset, use
4261 :hg:`revert`.
4263 :hg:`revert`.
4262
4264
4263 See :hg:`help dates` for a list of formats valid for -d/--date.
4265 See :hg:`help dates` for a list of formats valid for -d/--date.
4264
4266
4265 Returns 0 on success, 1 if there are unresolved files.
4267 Returns 0 on success, 1 if there are unresolved files.
4266 """
4268 """
4267 if rev and node:
4269 if rev and node:
4268 raise util.Abort(_("please specify just one revision"))
4270 raise util.Abort(_("please specify just one revision"))
4269
4271
4270 if rev is None or rev == '':
4272 if rev is None or rev == '':
4271 rev = node
4273 rev = node
4272
4274
4273 # if we defined a bookmark, we have to remember the original bookmark name
4275 # if we defined a bookmark, we have to remember the original bookmark name
4274 brev = rev
4276 brev = rev
4275 rev = cmdutil.revsingle(repo, rev, rev).rev()
4277 rev = cmdutil.revsingle(repo, rev, rev).rev()
4276
4278
4277 if check and clean:
4279 if check and clean:
4278 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
4280 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
4279
4281
4280 if check:
4282 if check:
4281 # we could use dirty() but we can ignore merge and branch trivia
4283 # we could use dirty() but we can ignore merge and branch trivia
4282 c = repo[None]
4284 c = repo[None]
4283 if c.modified() or c.added() or c.removed():
4285 if c.modified() or c.added() or c.removed():
4284 raise util.Abort(_("uncommitted local changes"))
4286 raise util.Abort(_("uncommitted local changes"))
4285
4287
4286 if date:
4288 if date:
4287 if rev is not None:
4289 if rev is not None:
4288 raise util.Abort(_("you can't specify a revision and a date"))
4290 raise util.Abort(_("you can't specify a revision and a date"))
4289 rev = cmdutil.finddate(ui, repo, date)
4291 rev = cmdutil.finddate(ui, repo, date)
4290
4292
4291 if clean or check:
4293 if clean or check:
4292 ret = hg.clean(repo, rev)
4294 ret = hg.clean(repo, rev)
4293 else:
4295 else:
4294 ret = hg.update(repo, rev)
4296 ret = hg.update(repo, rev)
4295
4297
4296 if brev in repo._bookmarks:
4298 if brev in repo._bookmarks:
4297 bookmarks.setcurrent(repo, brev)
4299 bookmarks.setcurrent(repo, brev)
4298
4300
4299 return ret
4301 return ret
4300
4302
4301 def verify(ui, repo):
4303 def verify(ui, repo):
4302 """verify the integrity of the repository
4304 """verify the integrity of the repository
4303
4305
4304 Verify the integrity of the current repository.
4306 Verify the integrity of the current repository.
4305
4307
4306 This will perform an extensive check of the repository's
4308 This will perform an extensive check of the repository's
4307 integrity, validating the hashes and checksums of each entry in
4309 integrity, validating the hashes and checksums of each entry in
4308 the changelog, manifest, and tracked files, as well as the
4310 the changelog, manifest, and tracked files, as well as the
4309 integrity of their crosslinks and indices.
4311 integrity of their crosslinks and indices.
4310
4312
4311 Returns 0 on success, 1 if errors are encountered.
4313 Returns 0 on success, 1 if errors are encountered.
4312 """
4314 """
4313 return hg.verify(repo)
4315 return hg.verify(repo)
4314
4316
4315 def version_(ui):
4317 def version_(ui):
4316 """output version and copyright information"""
4318 """output version and copyright information"""
4317 ui.write(_("Mercurial Distributed SCM (version %s)\n")
4319 ui.write(_("Mercurial Distributed SCM (version %s)\n")
4318 % util.version())
4320 % util.version())
4319 ui.status(_(
4321 ui.status(_(
4320 "(see http://mercurial.selenic.com for more information)\n"
4322 "(see http://mercurial.selenic.com for more information)\n"
4321 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
4323 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
4322 "This is free software; see the source for copying conditions. "
4324 "This is free software; see the source for copying conditions. "
4323 "There is NO\nwarranty; "
4325 "There is NO\nwarranty; "
4324 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
4326 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
4325 ))
4327 ))
4326
4328
4327 # Command options and aliases are listed here, alphabetically
4329 # Command options and aliases are listed here, alphabetically
4328
4330
4329 globalopts = [
4331 globalopts = [
4330 ('R', 'repository', '',
4332 ('R', 'repository', '',
4331 _('repository root directory or name of overlay bundle file'),
4333 _('repository root directory or name of overlay bundle file'),
4332 _('REPO')),
4334 _('REPO')),
4333 ('', 'cwd', '',
4335 ('', 'cwd', '',
4334 _('change working directory'), _('DIR')),
4336 _('change working directory'), _('DIR')),
4335 ('y', 'noninteractive', None,
4337 ('y', 'noninteractive', None,
4336 _('do not prompt, assume \'yes\' for any required answers')),
4338 _('do not prompt, assume \'yes\' for any required answers')),
4337 ('q', 'quiet', None, _('suppress output')),
4339 ('q', 'quiet', None, _('suppress output')),
4338 ('v', 'verbose', None, _('enable additional output')),
4340 ('v', 'verbose', None, _('enable additional output')),
4339 ('', 'config', [],
4341 ('', 'config', [],
4340 _('set/override config option (use \'section.name=value\')'),
4342 _('set/override config option (use \'section.name=value\')'),
4341 _('CONFIG')),
4343 _('CONFIG')),
4342 ('', 'debug', None, _('enable debugging output')),
4344 ('', 'debug', None, _('enable debugging output')),
4343 ('', 'debugger', None, _('start debugger')),
4345 ('', 'debugger', None, _('start debugger')),
4344 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
4346 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
4345 _('ENCODE')),
4347 _('ENCODE')),
4346 ('', 'encodingmode', encoding.encodingmode,
4348 ('', 'encodingmode', encoding.encodingmode,
4347 _('set the charset encoding mode'), _('MODE')),
4349 _('set the charset encoding mode'), _('MODE')),
4348 ('', 'traceback', None, _('always print a traceback on exception')),
4350 ('', 'traceback', None, _('always print a traceback on exception')),
4349 ('', 'time', None, _('time how long the command takes')),
4351 ('', 'time', None, _('time how long the command takes')),
4350 ('', 'profile', None, _('print command execution profile')),
4352 ('', 'profile', None, _('print command execution profile')),
4351 ('', 'version', None, _('output version information and exit')),
4353 ('', 'version', None, _('output version information and exit')),
4352 ('h', 'help', None, _('display help and exit')),
4354 ('h', 'help', None, _('display help and exit')),
4353 ]
4355 ]
4354
4356
4355 dryrunopts = [('n', 'dry-run', None,
4357 dryrunopts = [('n', 'dry-run', None,
4356 _('do not perform actions, just print output'))]
4358 _('do not perform actions, just print output'))]
4357
4359
4358 remoteopts = [
4360 remoteopts = [
4359 ('e', 'ssh', '',
4361 ('e', 'ssh', '',
4360 _('specify ssh command to use'), _('CMD')),
4362 _('specify ssh command to use'), _('CMD')),
4361 ('', 'remotecmd', '',
4363 ('', 'remotecmd', '',
4362 _('specify hg command to run on the remote side'), _('CMD')),
4364 _('specify hg command to run on the remote side'), _('CMD')),
4363 ('', 'insecure', None,
4365 ('', 'insecure', None,
4364 _('do not verify server certificate (ignoring web.cacerts config)')),
4366 _('do not verify server certificate (ignoring web.cacerts config)')),
4365 ]
4367 ]
4366
4368
4367 walkopts = [
4369 walkopts = [
4368 ('I', 'include', [],
4370 ('I', 'include', [],
4369 _('include names matching the given patterns'), _('PATTERN')),
4371 _('include names matching the given patterns'), _('PATTERN')),
4370 ('X', 'exclude', [],
4372 ('X', 'exclude', [],
4371 _('exclude names matching the given patterns'), _('PATTERN')),
4373 _('exclude names matching the given patterns'), _('PATTERN')),
4372 ]
4374 ]
4373
4375
4374 commitopts = [
4376 commitopts = [
4375 ('m', 'message', '',
4377 ('m', 'message', '',
4376 _('use text as commit message'), _('TEXT')),
4378 _('use text as commit message'), _('TEXT')),
4377 ('l', 'logfile', '',
4379 ('l', 'logfile', '',
4378 _('read commit message from file'), _('FILE')),
4380 _('read commit message from file'), _('FILE')),
4379 ]
4381 ]
4380
4382
4381 commitopts2 = [
4383 commitopts2 = [
4382 ('d', 'date', '',
4384 ('d', 'date', '',
4383 _('record the specified date as commit date'), _('DATE')),
4385 _('record the specified date as commit date'), _('DATE')),
4384 ('u', 'user', '',
4386 ('u', 'user', '',
4385 _('record the specified user as committer'), _('USER')),
4387 _('record the specified user as committer'), _('USER')),
4386 ]
4388 ]
4387
4389
4388 templateopts = [
4390 templateopts = [
4389 ('', 'style', '',
4391 ('', 'style', '',
4390 _('display using template map file'), _('STYLE')),
4392 _('display using template map file'), _('STYLE')),
4391 ('', 'template', '',
4393 ('', 'template', '',
4392 _('display with template'), _('TEMPLATE')),
4394 _('display with template'), _('TEMPLATE')),
4393 ]
4395 ]
4394
4396
4395 logopts = [
4397 logopts = [
4396 ('p', 'patch', None, _('show patch')),
4398 ('p', 'patch', None, _('show patch')),
4397 ('g', 'git', None, _('use git extended diff format')),
4399 ('g', 'git', None, _('use git extended diff format')),
4398 ('l', 'limit', '',
4400 ('l', 'limit', '',
4399 _('limit number of changes displayed'), _('NUM')),
4401 _('limit number of changes displayed'), _('NUM')),
4400 ('M', 'no-merges', None, _('do not show merges')),
4402 ('M', 'no-merges', None, _('do not show merges')),
4401 ('', 'stat', None, _('output diffstat-style summary of changes')),
4403 ('', 'stat', None, _('output diffstat-style summary of changes')),
4402 ] + templateopts
4404 ] + templateopts
4403
4405
4404 diffopts = [
4406 diffopts = [
4405 ('a', 'text', None, _('treat all files as text')),
4407 ('a', 'text', None, _('treat all files as text')),
4406 ('g', 'git', None, _('use git extended diff format')),
4408 ('g', 'git', None, _('use git extended diff format')),
4407 ('', 'nodates', None, _('omit dates from diff headers'))
4409 ('', 'nodates', None, _('omit dates from diff headers'))
4408 ]
4410 ]
4409
4411
4410 diffopts2 = [
4412 diffopts2 = [
4411 ('p', 'show-function', None, _('show which function each change is in')),
4413 ('p', 'show-function', None, _('show which function each change is in')),
4412 ('', 'reverse', None, _('produce a diff that undoes the changes')),
4414 ('', 'reverse', None, _('produce a diff that undoes the changes')),
4413 ('w', 'ignore-all-space', None,
4415 ('w', 'ignore-all-space', None,
4414 _('ignore white space when comparing lines')),
4416 _('ignore white space when comparing lines')),
4415 ('b', 'ignore-space-change', None,
4417 ('b', 'ignore-space-change', None,
4416 _('ignore changes in the amount of white space')),
4418 _('ignore changes in the amount of white space')),
4417 ('B', 'ignore-blank-lines', None,
4419 ('B', 'ignore-blank-lines', None,
4418 _('ignore changes whose lines are all blank')),
4420 _('ignore changes whose lines are all blank')),
4419 ('U', 'unified', '',
4421 ('U', 'unified', '',
4420 _('number of lines of context to show'), _('NUM')),
4422 _('number of lines of context to show'), _('NUM')),
4421 ('', 'stat', None, _('output diffstat-style summary of changes')),
4423 ('', 'stat', None, _('output diffstat-style summary of changes')),
4422 ]
4424 ]
4423
4425
4424 similarityopts = [
4426 similarityopts = [
4425 ('s', 'similarity', '',
4427 ('s', 'similarity', '',
4426 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
4428 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
4427 ]
4429 ]
4428
4430
4429 subrepoopts = [
4431 subrepoopts = [
4430 ('S', 'subrepos', None,
4432 ('S', 'subrepos', None,
4431 _('recurse into subrepositories'))
4433 _('recurse into subrepositories'))
4432 ]
4434 ]
4433
4435
4434 table = {
4436 table = {
4435 "^add": (add, walkopts + subrepoopts + dryrunopts,
4437 "^add": (add, walkopts + subrepoopts + dryrunopts,
4436 _('[OPTION]... [FILE]...')),
4438 _('[OPTION]... [FILE]...')),
4437 "addremove":
4439 "addremove":
4438 (addremove, similarityopts + walkopts + dryrunopts,
4440 (addremove, similarityopts + walkopts + dryrunopts,
4439 _('[OPTION]... [FILE]...')),
4441 _('[OPTION]... [FILE]...')),
4440 "^annotate|blame":
4442 "^annotate|blame":
4441 (annotate,
4443 (annotate,
4442 [('r', 'rev', '',
4444 [('r', 'rev', '',
4443 _('annotate the specified revision'), _('REV')),
4445 _('annotate the specified revision'), _('REV')),
4444 ('', 'follow', None,
4446 ('', 'follow', None,
4445 _('follow copies/renames and list the filename (DEPRECATED)')),
4447 _('follow copies/renames and list the filename (DEPRECATED)')),
4446 ('', 'no-follow', None, _("don't follow copies and renames")),
4448 ('', 'no-follow', None, _("don't follow copies and renames")),
4447 ('a', 'text', None, _('treat all files as text')),
4449 ('a', 'text', None, _('treat all files as text')),
4448 ('u', 'user', None, _('list the author (long with -v)')),
4450 ('u', 'user', None, _('list the author (long with -v)')),
4449 ('f', 'file', None, _('list the filename')),
4451 ('f', 'file', None, _('list the filename')),
4450 ('d', 'date', None, _('list the date (short with -q)')),
4452 ('d', 'date', None, _('list the date (short with -q)')),
4451 ('n', 'number', None, _('list the revision number (default)')),
4453 ('n', 'number', None, _('list the revision number (default)')),
4452 ('c', 'changeset', None, _('list the changeset')),
4454 ('c', 'changeset', None, _('list the changeset')),
4453 ('l', 'line-number', None,
4455 ('l', 'line-number', None,
4454 _('show line number at the first appearance'))
4456 _('show line number at the first appearance'))
4455 ] + walkopts,
4457 ] + walkopts,
4456 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
4458 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
4457 "archive":
4459 "archive":
4458 (archive,
4460 (archive,
4459 [('', 'no-decode', None, _('do not pass files through decoders')),
4461 [('', 'no-decode', None, _('do not pass files through decoders')),
4460 ('p', 'prefix', '',
4462 ('p', 'prefix', '',
4461 _('directory prefix for files in archive'), _('PREFIX')),
4463 _('directory prefix for files in archive'), _('PREFIX')),
4462 ('r', 'rev', '',
4464 ('r', 'rev', '',
4463 _('revision to distribute'), _('REV')),
4465 _('revision to distribute'), _('REV')),
4464 ('t', 'type', '',
4466 ('t', 'type', '',
4465 _('type of distribution to create'), _('TYPE')),
4467 _('type of distribution to create'), _('TYPE')),
4466 ] + subrepoopts + walkopts,
4468 ] + subrepoopts + walkopts,
4467 _('[OPTION]... DEST')),
4469 _('[OPTION]... DEST')),
4468 "backout":
4470 "backout":
4469 (backout,
4471 (backout,
4470 [('', 'merge', None,
4472 [('', 'merge', None,
4471 _('merge with old dirstate parent after backout')),
4473 _('merge with old dirstate parent after backout')),
4472 ('', 'parent', '',
4474 ('', 'parent', '',
4473 _('parent to choose when backing out merge'), _('REV')),
4475 _('parent to choose when backing out merge'), _('REV')),
4474 ('t', 'tool', '',
4476 ('t', 'tool', '',
4475 _('specify merge tool')),
4477 _('specify merge tool')),
4476 ('r', 'rev', '',
4478 ('r', 'rev', '',
4477 _('revision to backout'), _('REV')),
4479 _('revision to backout'), _('REV')),
4478 ] + walkopts + commitopts + commitopts2,
4480 ] + walkopts + commitopts + commitopts2,
4479 _('[OPTION]... [-r] REV')),
4481 _('[OPTION]... [-r] REV')),
4480 "bisect":
4482 "bisect":
4481 (bisect,
4483 (bisect,
4482 [('r', 'reset', False, _('reset bisect state')),
4484 [('r', 'reset', False, _('reset bisect state')),
4483 ('g', 'good', False, _('mark changeset good')),
4485 ('g', 'good', False, _('mark changeset good')),
4484 ('b', 'bad', False, _('mark changeset bad')),
4486 ('b', 'bad', False, _('mark changeset bad')),
4485 ('s', 'skip', False, _('skip testing changeset')),
4487 ('s', 'skip', False, _('skip testing changeset')),
4486 ('e', 'extend', False, _('extend the bisect range')),
4488 ('e', 'extend', False, _('extend the bisect range')),
4487 ('c', 'command', '',
4489 ('c', 'command', '',
4488 _('use command to check changeset state'), _('CMD')),
4490 _('use command to check changeset state'), _('CMD')),
4489 ('U', 'noupdate', False, _('do not update to target'))],
4491 ('U', 'noupdate', False, _('do not update to target'))],
4490 _("[-gbsr] [-U] [-c CMD] [REV]")),
4492 _("[-gbsr] [-U] [-c CMD] [REV]")),
4491 "bookmarks":
4493 "bookmarks":
4492 (bookmark,
4494 (bookmark,
4493 [('f', 'force', False, _('force')),
4495 [('f', 'force', False, _('force')),
4494 ('r', 'rev', '', _('revision'), _('REV')),
4496 ('r', 'rev', '', _('revision'), _('REV')),
4495 ('d', 'delete', False, _('delete a given bookmark')),
4497 ('d', 'delete', False, _('delete a given bookmark')),
4496 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
4498 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
4497 ('i', 'inactive', False, _('do not mark a new bookmark active'))],
4499 ('i', 'inactive', False, _('do not mark a new bookmark active'))],
4498 _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]')),
4500 _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]')),
4499 "branch":
4501 "branch":
4500 (branch,
4502 (branch,
4501 [('f', 'force', None,
4503 [('f', 'force', None,
4502 _('set branch name even if it shadows an existing branch')),
4504 _('set branch name even if it shadows an existing branch')),
4503 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4505 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4504 _('[-fC] [NAME]')),
4506 _('[-fC] [NAME]')),
4505 "branches":
4507 "branches":
4506 (branches,
4508 (branches,
4507 [('a', 'active', False,
4509 [('a', 'active', False,
4508 _('show only branches that have unmerged heads')),
4510 _('show only branches that have unmerged heads')),
4509 ('c', 'closed', False,
4511 ('c', 'closed', False,
4510 _('show normal and closed branches'))],
4512 _('show normal and closed branches'))],
4511 _('[-ac]')),
4513 _('[-ac]')),
4512 "bundle":
4514 "bundle":
4513 (bundle,
4515 (bundle,
4514 [('f', 'force', None,
4516 [('f', 'force', None,
4515 _('run even when the destination is unrelated')),
4517 _('run even when the destination is unrelated')),
4516 ('r', 'rev', [],
4518 ('r', 'rev', [],
4517 _('a changeset intended to be added to the destination'),
4519 _('a changeset intended to be added to the destination'),
4518 _('REV')),
4520 _('REV')),
4519 ('b', 'branch', [],
4521 ('b', 'branch', [],
4520 _('a specific branch you would like to bundle'),
4522 _('a specific branch you would like to bundle'),
4521 _('BRANCH')),
4523 _('BRANCH')),
4522 ('', 'base', [],
4524 ('', 'base', [],
4523 _('a base changeset assumed to be available at the destination'),
4525 _('a base changeset assumed to be available at the destination'),
4524 _('REV')),
4526 _('REV')),
4525 ('a', 'all', None, _('bundle all changesets in the repository')),
4527 ('a', 'all', None, _('bundle all changesets in the repository')),
4526 ('t', 'type', 'bzip2',
4528 ('t', 'type', 'bzip2',
4527 _('bundle compression type to use'), _('TYPE')),
4529 _('bundle compression type to use'), _('TYPE')),
4528 ] + remoteopts,
4530 ] + remoteopts,
4529 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4531 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4530 "cat":
4532 "cat":
4531 (cat,
4533 (cat,
4532 [('o', 'output', '',
4534 [('o', 'output', '',
4533 _('print output to file with formatted name'), _('FORMAT')),
4535 _('print output to file with formatted name'), _('FORMAT')),
4534 ('r', 'rev', '',
4536 ('r', 'rev', '',
4535 _('print the given revision'), _('REV')),
4537 _('print the given revision'), _('REV')),
4536 ('', 'decode', None, _('apply any matching decode filter')),
4538 ('', 'decode', None, _('apply any matching decode filter')),
4537 ] + walkopts,
4539 ] + walkopts,
4538 _('[OPTION]... FILE...')),
4540 _('[OPTION]... FILE...')),
4539 "^clone":
4541 "^clone":
4540 (clone,
4542 (clone,
4541 [('U', 'noupdate', None,
4543 [('U', 'noupdate', None,
4542 _('the clone will include an empty working copy (only a repository)')),
4544 _('the clone will include an empty working copy (only a repository)')),
4543 ('u', 'updaterev', '',
4545 ('u', 'updaterev', '',
4544 _('revision, tag or branch to check out'), _('REV')),
4546 _('revision, tag or branch to check out'), _('REV')),
4545 ('r', 'rev', [],
4547 ('r', 'rev', [],
4546 _('include the specified changeset'), _('REV')),
4548 _('include the specified changeset'), _('REV')),
4547 ('b', 'branch', [],
4549 ('b', 'branch', [],
4548 _('clone only the specified branch'), _('BRANCH')),
4550 _('clone only the specified branch'), _('BRANCH')),
4549 ('', 'pull', None, _('use pull protocol to copy metadata')),
4551 ('', 'pull', None, _('use pull protocol to copy metadata')),
4550 ('', 'uncompressed', None,
4552 ('', 'uncompressed', None,
4551 _('use uncompressed transfer (fast over LAN)')),
4553 _('use uncompressed transfer (fast over LAN)')),
4552 ] + remoteopts,
4554 ] + remoteopts,
4553 _('[OPTION]... SOURCE [DEST]')),
4555 _('[OPTION]... SOURCE [DEST]')),
4554 "^commit|ci":
4556 "^commit|ci":
4555 (commit,
4557 (commit,
4556 [('A', 'addremove', None,
4558 [('A', 'addremove', None,
4557 _('mark new/missing files as added/removed before committing')),
4559 _('mark new/missing files as added/removed before committing')),
4558 ('', 'close-branch', None,
4560 ('', 'close-branch', None,
4559 _('mark a branch as closed, hiding it from the branch list')),
4561 _('mark a branch as closed, hiding it from the branch list')),
4560 ] + walkopts + commitopts + commitopts2,
4562 ] + walkopts + commitopts + commitopts2,
4561 _('[OPTION]... [FILE]...')),
4563 _('[OPTION]... [FILE]...')),
4562 "copy|cp":
4564 "copy|cp":
4563 (copy,
4565 (copy,
4564 [('A', 'after', None, _('record a copy that has already occurred')),
4566 [('A', 'after', None, _('record a copy that has already occurred')),
4565 ('f', 'force', None,
4567 ('f', 'force', None,
4566 _('forcibly copy over an existing managed file')),
4568 _('forcibly copy over an existing managed file')),
4567 ] + walkopts + dryrunopts,
4569 ] + walkopts + dryrunopts,
4568 _('[OPTION]... [SOURCE]... DEST')),
4570 _('[OPTION]... [SOURCE]... DEST')),
4569 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4571 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4570 "debugbuilddag":
4572 "debugbuilddag":
4571 (debugbuilddag,
4573 (debugbuilddag,
4572 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4574 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4573 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4575 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4574 ('n', 'new-file', None, _('add new file at each rev')),
4576 ('n', 'new-file', None, _('add new file at each rev')),
4575 ],
4577 ],
4576 _('[OPTION]... [TEXT]')),
4578 _('[OPTION]... [TEXT]')),
4577 "debugbundle":
4579 "debugbundle":
4578 (debugbundle,
4580 (debugbundle,
4579 [('a', 'all', None, _('show all details')),
4581 [('a', 'all', None, _('show all details')),
4580 ],
4582 ],
4581 _('FILE')),
4583 _('FILE')),
4582 "debugcheckstate": (debugcheckstate, [], ''),
4584 "debugcheckstate": (debugcheckstate, [], ''),
4583 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4585 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4584 "debugcomplete":
4586 "debugcomplete":
4585 (debugcomplete,
4587 (debugcomplete,
4586 [('o', 'options', None, _('show the command options'))],
4588 [('o', 'options', None, _('show the command options'))],
4587 _('[-o] CMD')),
4589 _('[-o] CMD')),
4588 "debugdag":
4590 "debugdag":
4589 (debugdag,
4591 (debugdag,
4590 [('t', 'tags', None, _('use tags as labels')),
4592 [('t', 'tags', None, _('use tags as labels')),
4591 ('b', 'branches', None, _('annotate with branch names')),
4593 ('b', 'branches', None, _('annotate with branch names')),
4592 ('', 'dots', None, _('use dots for runs')),
4594 ('', 'dots', None, _('use dots for runs')),
4593 ('s', 'spaces', None, _('separate elements by spaces')),
4595 ('s', 'spaces', None, _('separate elements by spaces')),
4594 ],
4596 ],
4595 _('[OPTION]... [FILE [REV]...]')),
4597 _('[OPTION]... [FILE [REV]...]')),
4596 "debugdate":
4598 "debugdate":
4597 (debugdate,
4599 (debugdate,
4598 [('e', 'extended', None, _('try extended date formats'))],
4600 [('e', 'extended', None, _('try extended date formats'))],
4599 _('[-e] DATE [RANGE]')),
4601 _('[-e] DATE [RANGE]')),
4600 "debugdata": (debugdata, [], _('FILE REV')),
4602 "debugdata": (debugdata, [], _('FILE REV')),
4601 "debugdiscovery": (debugdiscovery,
4603 "debugdiscovery": (debugdiscovery,
4602 [('', 'old', None,
4604 [('', 'old', None,
4603 _('use old-style discovery')),
4605 _('use old-style discovery')),
4604 ('', 'nonheads', None,
4606 ('', 'nonheads', None,
4605 _('use old-style discovery with non-heads included')),
4607 _('use old-style discovery with non-heads included')),
4606 ] + remoteopts,
4608 ] + remoteopts,
4607 _('[-l REV] [-r REV] [-b BRANCH]...'
4609 _('[-l REV] [-r REV] [-b BRANCH]...'
4608 ' [OTHER]')),
4610 ' [OTHER]')),
4609 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4611 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4610 "debuggetbundle":
4612 "debuggetbundle":
4611 (debuggetbundle,
4613 (debuggetbundle,
4612 [('H', 'head', [], _('id of head node'), _('ID')),
4614 [('H', 'head', [], _('id of head node'), _('ID')),
4613 ('C', 'common', [], _('id of common node'), _('ID')),
4615 ('C', 'common', [], _('id of common node'), _('ID')),
4614 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
4616 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
4615 ],
4617 ],
4616 _('REPO FILE [-H|-C ID]...')),
4618 _('REPO FILE [-H|-C ID]...')),
4617 "debugignore": (debugignore, [], ''),
4619 "debugignore": (debugignore, [], ''),
4618 "debugindex": (debugindex,
4620 "debugindex": (debugindex,
4619 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
4621 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
4620 _('FILE')),
4622 _('FILE')),
4621 "debugindexdot": (debugindexdot, [], _('FILE')),
4623 "debugindexdot": (debugindexdot, [], _('FILE')),
4622 "debuginstall": (debuginstall, [], ''),
4624 "debuginstall": (debuginstall, [], ''),
4623 "debugknown": (debugknown, [], _('REPO ID...')),
4625 "debugknown": (debugknown, [], _('REPO ID...')),
4624 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4626 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4625 "debugrebuildstate":
4627 "debugrebuildstate":
4626 (debugrebuildstate,
4628 (debugrebuildstate,
4627 [('r', 'rev', '',
4629 [('r', 'rev', '',
4628 _('revision to rebuild to'), _('REV'))],
4630 _('revision to rebuild to'), _('REV'))],
4629 _('[-r REV] [REV]')),
4631 _('[-r REV] [REV]')),
4630 "debugrename":
4632 "debugrename":
4631 (debugrename,
4633 (debugrename,
4632 [('r', 'rev', '',
4634 [('r', 'rev', '',
4633 _('revision to debug'), _('REV'))],
4635 _('revision to debug'), _('REV'))],
4634 _('[-r REV] FILE')),
4636 _('[-r REV] FILE')),
4635 "debugrevspec":
4637 "debugrevspec":
4636 (debugrevspec, [], ('REVSPEC')),
4638 (debugrevspec, [], ('REVSPEC')),
4637 "debugsetparents":
4639 "debugsetparents":
4638 (debugsetparents, [], _('REV1 [REV2]')),
4640 (debugsetparents, [], _('REV1 [REV2]')),
4639 "debugstate":
4641 "debugstate":
4640 (debugstate,
4642 (debugstate,
4641 [('', 'nodates', None, _('do not display the saved mtime')),
4643 [('', 'nodates', None, _('do not display the saved mtime')),
4642 ('', 'datesort', None, _('sort by saved mtime'))],
4644 ('', 'datesort', None, _('sort by saved mtime'))],
4643 _('[OPTION]...')),
4645 _('[OPTION]...')),
4644 "debugsub":
4646 "debugsub":
4645 (debugsub,
4647 (debugsub,
4646 [('r', 'rev', '',
4648 [('r', 'rev', '',
4647 _('revision to check'), _('REV'))],
4649 _('revision to check'), _('REV'))],
4648 _('[-r REV] [REV]')),
4650 _('[-r REV] [REV]')),
4649 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4651 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4650 "debugwireargs":
4652 "debugwireargs":
4651 (debugwireargs,
4653 (debugwireargs,
4652 [('', 'three', '', 'three'),
4654 [('', 'three', '', 'three'),
4653 ('', 'four', '', 'four'),
4655 ('', 'four', '', 'four'),
4654 ('', 'five', '', 'five'),
4656 ('', 'five', '', 'five'),
4655 ] + remoteopts,
4657 ] + remoteopts,
4656 _('REPO [OPTIONS]... [ONE [TWO]]')),
4658 _('REPO [OPTIONS]... [ONE [TWO]]')),
4657 "^diff":
4659 "^diff":
4658 (diff,
4660 (diff,
4659 [('r', 'rev', [],
4661 [('r', 'rev', [],
4660 _('revision'), _('REV')),
4662 _('revision'), _('REV')),
4661 ('c', 'change', '',
4663 ('c', 'change', '',
4662 _('change made by revision'), _('REV'))
4664 _('change made by revision'), _('REV'))
4663 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4665 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4664 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4666 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4665 "^export":
4667 "^export":
4666 (export,
4668 (export,
4667 [('o', 'output', '',
4669 [('o', 'output', '',
4668 _('print output to file with formatted name'), _('FORMAT')),
4670 _('print output to file with formatted name'), _('FORMAT')),
4669 ('', 'switch-parent', None, _('diff against the second parent')),
4671 ('', 'switch-parent', None, _('diff against the second parent')),
4670 ('r', 'rev', [],
4672 ('r', 'rev', [],
4671 _('revisions to export'), _('REV')),
4673 _('revisions to export'), _('REV')),
4672 ] + diffopts,
4674 ] + diffopts,
4673 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4675 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4674 "^forget":
4676 "^forget":
4675 (forget,
4677 (forget,
4676 [] + walkopts,
4678 [] + walkopts,
4677 _('[OPTION]... FILE...')),
4679 _('[OPTION]... FILE...')),
4678 "grep":
4680 "grep":
4679 (grep,
4681 (grep,
4680 [('0', 'print0', None, _('end fields with NUL')),
4682 [('0', 'print0', None, _('end fields with NUL')),
4681 ('', 'all', None, _('print all revisions that match')),
4683 ('', 'all', None, _('print all revisions that match')),
4682 ('a', 'text', None, _('treat all files as text')),
4684 ('a', 'text', None, _('treat all files as text')),
4683 ('f', 'follow', None,
4685 ('f', 'follow', None,
4684 _('follow changeset history,'
4686 _('follow changeset history,'
4685 ' or file history across copies and renames')),
4687 ' or file history across copies and renames')),
4686 ('i', 'ignore-case', None, _('ignore case when matching')),
4688 ('i', 'ignore-case', None, _('ignore case when matching')),
4687 ('l', 'files-with-matches', None,
4689 ('l', 'files-with-matches', None,
4688 _('print only filenames and revisions that match')),
4690 _('print only filenames and revisions that match')),
4689 ('n', 'line-number', None, _('print matching line numbers')),
4691 ('n', 'line-number', None, _('print matching line numbers')),
4690 ('r', 'rev', [],
4692 ('r', 'rev', [],
4691 _('only search files changed within revision range'), _('REV')),
4693 _('only search files changed within revision range'), _('REV')),
4692 ('u', 'user', None, _('list the author (long with -v)')),
4694 ('u', 'user', None, _('list the author (long with -v)')),
4693 ('d', 'date', None, _('list the date (short with -q)')),
4695 ('d', 'date', None, _('list the date (short with -q)')),
4694 ] + walkopts,
4696 ] + walkopts,
4695 _('[OPTION]... PATTERN [FILE]...')),
4697 _('[OPTION]... PATTERN [FILE]...')),
4696 "heads":
4698 "heads":
4697 (heads,
4699 (heads,
4698 [('r', 'rev', '',
4700 [('r', 'rev', '',
4699 _('show only heads which are descendants of STARTREV'),
4701 _('show only heads which are descendants of STARTREV'),
4700 _('STARTREV')),
4702 _('STARTREV')),
4701 ('t', 'topo', False, _('show topological heads only')),
4703 ('t', 'topo', False, _('show topological heads only')),
4702 ('a', 'active', False,
4704 ('a', 'active', False,
4703 _('show active branchheads only (DEPRECATED)')),
4705 _('show active branchheads only (DEPRECATED)')),
4704 ('c', 'closed', False,
4706 ('c', 'closed', False,
4705 _('show normal and closed branch heads')),
4707 _('show normal and closed branch heads')),
4706 ] + templateopts,
4708 ] + templateopts,
4707 _('[-ac] [-r STARTREV] [REV]...')),
4709 _('[-ac] [-r STARTREV] [REV]...')),
4708 "help": (help_, [], _('[TOPIC]')),
4710 "help": (help_,
4711 [('e', 'extension', None, _('show only help for extensions'))],
4712 _('[-e] [TOPIC]')),
4709 "identify|id":
4713 "identify|id":
4710 (identify,
4714 (identify,
4711 [('r', 'rev', '',
4715 [('r', 'rev', '',
4712 _('identify the specified revision'), _('REV')),
4716 _('identify the specified revision'), _('REV')),
4713 ('n', 'num', None, _('show local revision number')),
4717 ('n', 'num', None, _('show local revision number')),
4714 ('i', 'id', None, _('show global revision id')),
4718 ('i', 'id', None, _('show global revision id')),
4715 ('b', 'branch', None, _('show branch')),
4719 ('b', 'branch', None, _('show branch')),
4716 ('t', 'tags', None, _('show tags')),
4720 ('t', 'tags', None, _('show tags')),
4717 ('B', 'bookmarks', None, _('show bookmarks'))],
4721 ('B', 'bookmarks', None, _('show bookmarks'))],
4718 _('[-nibtB] [-r REV] [SOURCE]')),
4722 _('[-nibtB] [-r REV] [SOURCE]')),
4719 "import|patch":
4723 "import|patch":
4720 (import_,
4724 (import_,
4721 [('p', 'strip', 1,
4725 [('p', 'strip', 1,
4722 _('directory strip option for patch. This has the same '
4726 _('directory strip option for patch. This has the same '
4723 'meaning as the corresponding patch option'),
4727 'meaning as the corresponding patch option'),
4724 _('NUM')),
4728 _('NUM')),
4725 ('b', 'base', '',
4729 ('b', 'base', '',
4726 _('base path'), _('PATH')),
4730 _('base path'), _('PATH')),
4727 ('f', 'force', None,
4731 ('f', 'force', None,
4728 _('skip check for outstanding uncommitted changes')),
4732 _('skip check for outstanding uncommitted changes')),
4729 ('', 'no-commit', None,
4733 ('', 'no-commit', None,
4730 _("don't commit, just update the working directory")),
4734 _("don't commit, just update the working directory")),
4731 ('', 'exact', None,
4735 ('', 'exact', None,
4732 _('apply patch to the nodes from which it was generated')),
4736 _('apply patch to the nodes from which it was generated')),
4733 ('', 'import-branch', None,
4737 ('', 'import-branch', None,
4734 _('use any branch information in patch (implied by --exact)'))] +
4738 _('use any branch information in patch (implied by --exact)'))] +
4735 commitopts + commitopts2 + similarityopts,
4739 commitopts + commitopts2 + similarityopts,
4736 _('[OPTION]... PATCH...')),
4740 _('[OPTION]... PATCH...')),
4737 "incoming|in":
4741 "incoming|in":
4738 (incoming,
4742 (incoming,
4739 [('f', 'force', None,
4743 [('f', 'force', None,
4740 _('run even if remote repository is unrelated')),
4744 _('run even if remote repository is unrelated')),
4741 ('n', 'newest-first', None, _('show newest record first')),
4745 ('n', 'newest-first', None, _('show newest record first')),
4742 ('', 'bundle', '',
4746 ('', 'bundle', '',
4743 _('file to store the bundles into'), _('FILE')),
4747 _('file to store the bundles into'), _('FILE')),
4744 ('r', 'rev', [],
4748 ('r', 'rev', [],
4745 _('a remote changeset intended to be added'), _('REV')),
4749 _('a remote changeset intended to be added'), _('REV')),
4746 ('B', 'bookmarks', False, _("compare bookmarks")),
4750 ('B', 'bookmarks', False, _("compare bookmarks")),
4747 ('b', 'branch', [],
4751 ('b', 'branch', [],
4748 _('a specific branch you would like to pull'), _('BRANCH')),
4752 _('a specific branch you would like to pull'), _('BRANCH')),
4749 ] + logopts + remoteopts + subrepoopts,
4753 ] + logopts + remoteopts + subrepoopts,
4750 _('[-p] [-n] [-M] [-f] [-r REV]...'
4754 _('[-p] [-n] [-M] [-f] [-r REV]...'
4751 ' [--bundle FILENAME] [SOURCE]')),
4755 ' [--bundle FILENAME] [SOURCE]')),
4752 "^init":
4756 "^init":
4753 (init,
4757 (init,
4754 remoteopts,
4758 remoteopts,
4755 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4759 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4756 "locate":
4760 "locate":
4757 (locate,
4761 (locate,
4758 [('r', 'rev', '',
4762 [('r', 'rev', '',
4759 _('search the repository as it is in REV'), _('REV')),
4763 _('search the repository as it is in REV'), _('REV')),
4760 ('0', 'print0', None,
4764 ('0', 'print0', None,
4761 _('end filenames with NUL, for use with xargs')),
4765 _('end filenames with NUL, for use with xargs')),
4762 ('f', 'fullpath', None,
4766 ('f', 'fullpath', None,
4763 _('print complete paths from the filesystem root')),
4767 _('print complete paths from the filesystem root')),
4764 ] + walkopts,
4768 ] + walkopts,
4765 _('[OPTION]... [PATTERN]...')),
4769 _('[OPTION]... [PATTERN]...')),
4766 "^log|history":
4770 "^log|history":
4767 (log,
4771 (log,
4768 [('f', 'follow', None,
4772 [('f', 'follow', None,
4769 _('follow changeset history,'
4773 _('follow changeset history,'
4770 ' or file history across copies and renames')),
4774 ' or file history across copies and renames')),
4771 ('', 'follow-first', None,
4775 ('', 'follow-first', None,
4772 _('only follow the first parent of merge changesets')),
4776 _('only follow the first parent of merge changesets')),
4773 ('d', 'date', '',
4777 ('d', 'date', '',
4774 _('show revisions matching date spec'), _('DATE')),
4778 _('show revisions matching date spec'), _('DATE')),
4775 ('C', 'copies', None, _('show copied files')),
4779 ('C', 'copies', None, _('show copied files')),
4776 ('k', 'keyword', [],
4780 ('k', 'keyword', [],
4777 _('do case-insensitive search for a given text'), _('TEXT')),
4781 _('do case-insensitive search for a given text'), _('TEXT')),
4778 ('r', 'rev', [],
4782 ('r', 'rev', [],
4779 _('show the specified revision or range'), _('REV')),
4783 _('show the specified revision or range'), _('REV')),
4780 ('', 'removed', None, _('include revisions where files were removed')),
4784 ('', 'removed', None, _('include revisions where files were removed')),
4781 ('m', 'only-merges', None, _('show only merges')),
4785 ('m', 'only-merges', None, _('show only merges')),
4782 ('u', 'user', [],
4786 ('u', 'user', [],
4783 _('revisions committed by user'), _('USER')),
4787 _('revisions committed by user'), _('USER')),
4784 ('', 'only-branch', [],
4788 ('', 'only-branch', [],
4785 _('show only changesets within the given named branch (DEPRECATED)'),
4789 _('show only changesets within the given named branch (DEPRECATED)'),
4786 _('BRANCH')),
4790 _('BRANCH')),
4787 ('b', 'branch', [],
4791 ('b', 'branch', [],
4788 _('show changesets within the given named branch'), _('BRANCH')),
4792 _('show changesets within the given named branch'), _('BRANCH')),
4789 ('P', 'prune', [],
4793 ('P', 'prune', [],
4790 _('do not display revision or any of its ancestors'), _('REV')),
4794 _('do not display revision or any of its ancestors'), _('REV')),
4791 ] + logopts + walkopts,
4795 ] + logopts + walkopts,
4792 _('[OPTION]... [FILE]')),
4796 _('[OPTION]... [FILE]')),
4793 "manifest":
4797 "manifest":
4794 (manifest,
4798 (manifest,
4795 [('r', 'rev', '',
4799 [('r', 'rev', '',
4796 _('revision to display'), _('REV'))],
4800 _('revision to display'), _('REV'))],
4797 _('[-r REV]')),
4801 _('[-r REV]')),
4798 "^merge":
4802 "^merge":
4799 (merge,
4803 (merge,
4800 [('f', 'force', None, _('force a merge with outstanding changes')),
4804 [('f', 'force', None, _('force a merge with outstanding changes')),
4801 ('t', 'tool', '', _('specify merge tool')),
4805 ('t', 'tool', '', _('specify merge tool')),
4802 ('r', 'rev', '',
4806 ('r', 'rev', '',
4803 _('revision to merge'), _('REV')),
4807 _('revision to merge'), _('REV')),
4804 ('P', 'preview', None,
4808 ('P', 'preview', None,
4805 _('review revisions to merge (no merge is performed)'))],
4809 _('review revisions to merge (no merge is performed)'))],
4806 _('[-P] [-f] [[-r] REV]')),
4810 _('[-P] [-f] [[-r] REV]')),
4807 "outgoing|out":
4811 "outgoing|out":
4808 (outgoing,
4812 (outgoing,
4809 [('f', 'force', None,
4813 [('f', 'force', None,
4810 _('run even when the destination is unrelated')),
4814 _('run even when the destination is unrelated')),
4811 ('r', 'rev', [],
4815 ('r', 'rev', [],
4812 _('a changeset intended to be included in the destination'),
4816 _('a changeset intended to be included in the destination'),
4813 _('REV')),
4817 _('REV')),
4814 ('n', 'newest-first', None, _('show newest record first')),
4818 ('n', 'newest-first', None, _('show newest record first')),
4815 ('B', 'bookmarks', False, _("compare bookmarks")),
4819 ('B', 'bookmarks', False, _("compare bookmarks")),
4816 ('b', 'branch', [],
4820 ('b', 'branch', [],
4817 _('a specific branch you would like to push'), _('BRANCH')),
4821 _('a specific branch you would like to push'), _('BRANCH')),
4818 ] + logopts + remoteopts + subrepoopts,
4822 ] + logopts + remoteopts + subrepoopts,
4819 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4823 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4820 "parents":
4824 "parents":
4821 (parents,
4825 (parents,
4822 [('r', 'rev', '',
4826 [('r', 'rev', '',
4823 _('show parents of the specified revision'), _('REV')),
4827 _('show parents of the specified revision'), _('REV')),
4824 ] + templateopts,
4828 ] + templateopts,
4825 _('[-r REV] [FILE]')),
4829 _('[-r REV] [FILE]')),
4826 "paths": (paths, [], _('[NAME]')),
4830 "paths": (paths, [], _('[NAME]')),
4827 "^pull":
4831 "^pull":
4828 (pull,
4832 (pull,
4829 [('u', 'update', None,
4833 [('u', 'update', None,
4830 _('update to new branch head if changesets were pulled')),
4834 _('update to new branch head if changesets were pulled')),
4831 ('f', 'force', None,
4835 ('f', 'force', None,
4832 _('run even when remote repository is unrelated')),
4836 _('run even when remote repository is unrelated')),
4833 ('r', 'rev', [],
4837 ('r', 'rev', [],
4834 _('a remote changeset intended to be added'), _('REV')),
4838 _('a remote changeset intended to be added'), _('REV')),
4835 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4839 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4836 ('b', 'branch', [],
4840 ('b', 'branch', [],
4837 _('a specific branch you would like to pull'), _('BRANCH')),
4841 _('a specific branch you would like to pull'), _('BRANCH')),
4838 ] + remoteopts,
4842 ] + remoteopts,
4839 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4843 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4840 "^push":
4844 "^push":
4841 (push,
4845 (push,
4842 [('f', 'force', None, _('force push')),
4846 [('f', 'force', None, _('force push')),
4843 ('r', 'rev', [],
4847 ('r', 'rev', [],
4844 _('a changeset intended to be included in the destination'),
4848 _('a changeset intended to be included in the destination'),
4845 _('REV')),
4849 _('REV')),
4846 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4850 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4847 ('b', 'branch', [],
4851 ('b', 'branch', [],
4848 _('a specific branch you would like to push'), _('BRANCH')),
4852 _('a specific branch you would like to push'), _('BRANCH')),
4849 ('', 'new-branch', False, _('allow pushing a new branch')),
4853 ('', 'new-branch', False, _('allow pushing a new branch')),
4850 ] + remoteopts,
4854 ] + remoteopts,
4851 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4855 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4852 "recover": (recover, []),
4856 "recover": (recover, []),
4853 "^remove|rm":
4857 "^remove|rm":
4854 (remove,
4858 (remove,
4855 [('A', 'after', None, _('record delete for missing files')),
4859 [('A', 'after', None, _('record delete for missing files')),
4856 ('f', 'force', None,
4860 ('f', 'force', None,
4857 _('remove (and delete) file even if added or modified')),
4861 _('remove (and delete) file even if added or modified')),
4858 ] + walkopts,
4862 ] + walkopts,
4859 _('[OPTION]... FILE...')),
4863 _('[OPTION]... FILE...')),
4860 "rename|move|mv":
4864 "rename|move|mv":
4861 (rename,
4865 (rename,
4862 [('A', 'after', None, _('record a rename that has already occurred')),
4866 [('A', 'after', None, _('record a rename that has already occurred')),
4863 ('f', 'force', None,
4867 ('f', 'force', None,
4864 _('forcibly copy over an existing managed file')),
4868 _('forcibly copy over an existing managed file')),
4865 ] + walkopts + dryrunopts,
4869 ] + walkopts + dryrunopts,
4866 _('[OPTION]... SOURCE... DEST')),
4870 _('[OPTION]... SOURCE... DEST')),
4867 "resolve":
4871 "resolve":
4868 (resolve,
4872 (resolve,
4869 [('a', 'all', None, _('select all unresolved files')),
4873 [('a', 'all', None, _('select all unresolved files')),
4870 ('l', 'list', None, _('list state of files needing merge')),
4874 ('l', 'list', None, _('list state of files needing merge')),
4871 ('m', 'mark', None, _('mark files as resolved')),
4875 ('m', 'mark', None, _('mark files as resolved')),
4872 ('u', 'unmark', None, _('mark files as unresolved')),
4876 ('u', 'unmark', None, _('mark files as unresolved')),
4873 ('t', 'tool', '', _('specify merge tool')),
4877 ('t', 'tool', '', _('specify merge tool')),
4874 ('n', 'no-status', None, _('hide status prefix'))]
4878 ('n', 'no-status', None, _('hide status prefix'))]
4875 + walkopts,
4879 + walkopts,
4876 _('[OPTION]... [FILE]...')),
4880 _('[OPTION]... [FILE]...')),
4877 "revert":
4881 "revert":
4878 (revert,
4882 (revert,
4879 [('a', 'all', None, _('revert all changes when no arguments given')),
4883 [('a', 'all', None, _('revert all changes when no arguments given')),
4880 ('d', 'date', '',
4884 ('d', 'date', '',
4881 _('tipmost revision matching date'), _('DATE')),
4885 _('tipmost revision matching date'), _('DATE')),
4882 ('r', 'rev', '',
4886 ('r', 'rev', '',
4883 _('revert to the specified revision'), _('REV')),
4887 _('revert to the specified revision'), _('REV')),
4884 ('', 'no-backup', None, _('do not save backup copies of files')),
4888 ('', 'no-backup', None, _('do not save backup copies of files')),
4885 ] + walkopts + dryrunopts,
4889 ] + walkopts + dryrunopts,
4886 _('[OPTION]... [-r REV] [NAME]...')),
4890 _('[OPTION]... [-r REV] [NAME]...')),
4887 "rollback": (rollback, dryrunopts),
4891 "rollback": (rollback, dryrunopts),
4888 "root": (root, []),
4892 "root": (root, []),
4889 "^serve":
4893 "^serve":
4890 (serve,
4894 (serve,
4891 [('A', 'accesslog', '',
4895 [('A', 'accesslog', '',
4892 _('name of access log file to write to'), _('FILE')),
4896 _('name of access log file to write to'), _('FILE')),
4893 ('d', 'daemon', None, _('run server in background')),
4897 ('d', 'daemon', None, _('run server in background')),
4894 ('', 'daemon-pipefds', '',
4898 ('', 'daemon-pipefds', '',
4895 _('used internally by daemon mode'), _('NUM')),
4899 _('used internally by daemon mode'), _('NUM')),
4896 ('E', 'errorlog', '',
4900 ('E', 'errorlog', '',
4897 _('name of error log file to write to'), _('FILE')),
4901 _('name of error log file to write to'), _('FILE')),
4898 # use string type, then we can check if something was passed
4902 # use string type, then we can check if something was passed
4899 ('p', 'port', '',
4903 ('p', 'port', '',
4900 _('port to listen on (default: 8000)'), _('PORT')),
4904 _('port to listen on (default: 8000)'), _('PORT')),
4901 ('a', 'address', '',
4905 ('a', 'address', '',
4902 _('address to listen on (default: all interfaces)'), _('ADDR')),
4906 _('address to listen on (default: all interfaces)'), _('ADDR')),
4903 ('', 'prefix', '',
4907 ('', 'prefix', '',
4904 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4908 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4905 ('n', 'name', '',
4909 ('n', 'name', '',
4906 _('name to show in web pages (default: working directory)'),
4910 _('name to show in web pages (default: working directory)'),
4907 _('NAME')),
4911 _('NAME')),
4908 ('', 'web-conf', '',
4912 ('', 'web-conf', '',
4909 _('name of the hgweb config file (see "hg help hgweb")'),
4913 _('name of the hgweb config file (see "hg help hgweb")'),
4910 _('FILE')),
4914 _('FILE')),
4911 ('', 'webdir-conf', '',
4915 ('', 'webdir-conf', '',
4912 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4916 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4913 ('', 'pid-file', '',
4917 ('', 'pid-file', '',
4914 _('name of file to write process ID to'), _('FILE')),
4918 _('name of file to write process ID to'), _('FILE')),
4915 ('', 'stdio', None, _('for remote clients')),
4919 ('', 'stdio', None, _('for remote clients')),
4916 ('t', 'templates', '',
4920 ('t', 'templates', '',
4917 _('web templates to use'), _('TEMPLATE')),
4921 _('web templates to use'), _('TEMPLATE')),
4918 ('', 'style', '',
4922 ('', 'style', '',
4919 _('template style to use'), _('STYLE')),
4923 _('template style to use'), _('STYLE')),
4920 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4924 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4921 ('', 'certificate', '',
4925 ('', 'certificate', '',
4922 _('SSL certificate file'), _('FILE'))],
4926 _('SSL certificate file'), _('FILE'))],
4923 _('[OPTION]...')),
4927 _('[OPTION]...')),
4924 "showconfig|debugconfig":
4928 "showconfig|debugconfig":
4925 (showconfig,
4929 (showconfig,
4926 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4930 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4927 _('[-u] [NAME]...')),
4931 _('[-u] [NAME]...')),
4928 "^summary|sum":
4932 "^summary|sum":
4929 (summary,
4933 (summary,
4930 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4934 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4931 "^status|st":
4935 "^status|st":
4932 (status,
4936 (status,
4933 [('A', 'all', None, _('show status of all files')),
4937 [('A', 'all', None, _('show status of all files')),
4934 ('m', 'modified', None, _('show only modified files')),
4938 ('m', 'modified', None, _('show only modified files')),
4935 ('a', 'added', None, _('show only added files')),
4939 ('a', 'added', None, _('show only added files')),
4936 ('r', 'removed', None, _('show only removed files')),
4940 ('r', 'removed', None, _('show only removed files')),
4937 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4941 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4938 ('c', 'clean', None, _('show only files without changes')),
4942 ('c', 'clean', None, _('show only files without changes')),
4939 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4943 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4940 ('i', 'ignored', None, _('show only ignored files')),
4944 ('i', 'ignored', None, _('show only ignored files')),
4941 ('n', 'no-status', None, _('hide status prefix')),
4945 ('n', 'no-status', None, _('hide status prefix')),
4942 ('C', 'copies', None, _('show source of copied files')),
4946 ('C', 'copies', None, _('show source of copied files')),
4943 ('0', 'print0', None,
4947 ('0', 'print0', None,
4944 _('end filenames with NUL, for use with xargs')),
4948 _('end filenames with NUL, for use with xargs')),
4945 ('', 'rev', [],
4949 ('', 'rev', [],
4946 _('show difference from revision'), _('REV')),
4950 _('show difference from revision'), _('REV')),
4947 ('', 'change', '',
4951 ('', 'change', '',
4948 _('list the changed files of a revision'), _('REV')),
4952 _('list the changed files of a revision'), _('REV')),
4949 ] + walkopts + subrepoopts,
4953 ] + walkopts + subrepoopts,
4950 _('[OPTION]... [FILE]...')),
4954 _('[OPTION]... [FILE]...')),
4951 "tag":
4955 "tag":
4952 (tag,
4956 (tag,
4953 [('f', 'force', None, _('force tag')),
4957 [('f', 'force', None, _('force tag')),
4954 ('l', 'local', None, _('make the tag local')),
4958 ('l', 'local', None, _('make the tag local')),
4955 ('r', 'rev', '',
4959 ('r', 'rev', '',
4956 _('revision to tag'), _('REV')),
4960 _('revision to tag'), _('REV')),
4957 ('', 'remove', None, _('remove a tag')),
4961 ('', 'remove', None, _('remove a tag')),
4958 # -l/--local is already there, commitopts cannot be used
4962 # -l/--local is already there, commitopts cannot be used
4959 ('e', 'edit', None, _('edit commit message')),
4963 ('e', 'edit', None, _('edit commit message')),
4960 ('m', 'message', '',
4964 ('m', 'message', '',
4961 _('use <text> as commit message'), _('TEXT')),
4965 _('use <text> as commit message'), _('TEXT')),
4962 ] + commitopts2,
4966 ] + commitopts2,
4963 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4967 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4964 "tags": (tags, [], ''),
4968 "tags": (tags, [], ''),
4965 "tip":
4969 "tip":
4966 (tip,
4970 (tip,
4967 [('p', 'patch', None, _('show patch')),
4971 [('p', 'patch', None, _('show patch')),
4968 ('g', 'git', None, _('use git extended diff format')),
4972 ('g', 'git', None, _('use git extended diff format')),
4969 ] + templateopts,
4973 ] + templateopts,
4970 _('[-p] [-g]')),
4974 _('[-p] [-g]')),
4971 "unbundle":
4975 "unbundle":
4972 (unbundle,
4976 (unbundle,
4973 [('u', 'update', None,
4977 [('u', 'update', None,
4974 _('update to new branch head if changesets were unbundled'))],
4978 _('update to new branch head if changesets were unbundled'))],
4975 _('[-u] FILE...')),
4979 _('[-u] FILE...')),
4976 "^update|up|checkout|co":
4980 "^update|up|checkout|co":
4977 (update,
4981 (update,
4978 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4982 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4979 ('c', 'check', None,
4983 ('c', 'check', None,
4980 _('update across branches if no uncommitted changes')),
4984 _('update across branches if no uncommitted changes')),
4981 ('d', 'date', '',
4985 ('d', 'date', '',
4982 _('tipmost revision matching date'), _('DATE')),
4986 _('tipmost revision matching date'), _('DATE')),
4983 ('r', 'rev', '',
4987 ('r', 'rev', '',
4984 _('revision'), _('REV'))],
4988 _('revision'), _('REV'))],
4985 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4989 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4986 "verify": (verify, []),
4990 "verify": (verify, []),
4987 "version": (version_, []),
4991 "version": (version_, []),
4988 }
4992 }
4989
4993
4990 norepo = ("clone init version help debugcommands debugcomplete"
4994 norepo = ("clone init version help debugcommands debugcomplete"
4991 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
4995 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
4992 " debugknown debuggetbundle debugbundle")
4996 " debugknown debuggetbundle debugbundle")
4993 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
4997 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
4994 " debugdata debugindex debugindexdot")
4998 " debugdata debugindex debugindexdot")
@@ -1,15 +1,15 b''
1 $ echo 'raise Exception("bit bucket overflow")' > badext.py
1 $ echo 'raise Exception("bit bucket overflow")' > badext.py
2 $ abspath=`pwd`/badext.py
2 $ abspath=`pwd`/badext.py
3
3
4 $ echo '[extensions]' >> $HGRCPATH
4 $ echo '[extensions]' >> $HGRCPATH
5 $ echo "gpg =" >> $HGRCPATH
5 $ echo "gpg =" >> $HGRCPATH
6 $ echo "hgext.gpg =" >> $HGRCPATH
6 $ echo "hgext.gpg =" >> $HGRCPATH
7 $ echo "badext = $abspath" >> $HGRCPATH
7 $ echo "badext = $abspath" >> $HGRCPATH
8 $ echo "badext2 =" >> $HGRCPATH
8 $ echo "badext2 =" >> $HGRCPATH
9
9
10 $ hg -q help help
10 $ hg -q help help
11 *** failed to import extension badext from $TESTTMP/badext.py: bit bucket overflow
11 *** failed to import extension badext from $TESTTMP/badext.py: bit bucket overflow
12 *** failed to import extension badext2: No module named badext2
12 *** failed to import extension badext2: No module named badext2
13 hg help [TOPIC]
13 hg help [-e] [TOPIC]
14
14
15 show help for a given topic or a help overview
15 show help for a given topic or a help overview
@@ -1,263 +1,263 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 add
3 add
4 addremove
4 addremove
5 annotate
5 annotate
6 archive
6 archive
7 backout
7 backout
8 bisect
8 bisect
9 bookmarks
9 bookmarks
10 branch
10 branch
11 branches
11 branches
12 bundle
12 bundle
13 cat
13 cat
14 clone
14 clone
15 commit
15 commit
16 copy
16 copy
17 diff
17 diff
18 export
18 export
19 forget
19 forget
20 grep
20 grep
21 heads
21 heads
22 help
22 help
23 identify
23 identify
24 import
24 import
25 incoming
25 incoming
26 init
26 init
27 locate
27 locate
28 log
28 log
29 manifest
29 manifest
30 merge
30 merge
31 outgoing
31 outgoing
32 parents
32 parents
33 paths
33 paths
34 pull
34 pull
35 push
35 push
36 recover
36 recover
37 remove
37 remove
38 rename
38 rename
39 resolve
39 resolve
40 revert
40 revert
41 rollback
41 rollback
42 root
42 root
43 serve
43 serve
44 showconfig
44 showconfig
45 status
45 status
46 summary
46 summary
47 tag
47 tag
48 tags
48 tags
49 tip
49 tip
50 unbundle
50 unbundle
51 update
51 update
52 verify
52 verify
53 version
53 version
54
54
55 Show all commands that start with "a"
55 Show all commands that start with "a"
56 $ hg debugcomplete a
56 $ hg debugcomplete a
57 add
57 add
58 addremove
58 addremove
59 annotate
59 annotate
60 archive
60 archive
61
61
62 Do not show debug commands if there are other candidates
62 Do not show debug commands if there are other candidates
63 $ hg debugcomplete d
63 $ hg debugcomplete d
64 diff
64 diff
65
65
66 Show debug commands if there are no other candidates
66 Show debug commands if there are no other candidates
67 $ hg debugcomplete debug
67 $ hg debugcomplete debug
68 debugancestor
68 debugancestor
69 debugbuilddag
69 debugbuilddag
70 debugbundle
70 debugbundle
71 debugcheckstate
71 debugcheckstate
72 debugcommands
72 debugcommands
73 debugcomplete
73 debugcomplete
74 debugconfig
74 debugconfig
75 debugdag
75 debugdag
76 debugdata
76 debugdata
77 debugdate
77 debugdate
78 debugdiscovery
78 debugdiscovery
79 debugfsinfo
79 debugfsinfo
80 debuggetbundle
80 debuggetbundle
81 debugignore
81 debugignore
82 debugindex
82 debugindex
83 debugindexdot
83 debugindexdot
84 debuginstall
84 debuginstall
85 debugknown
85 debugknown
86 debugpushkey
86 debugpushkey
87 debugrebuildstate
87 debugrebuildstate
88 debugrename
88 debugrename
89 debugrevspec
89 debugrevspec
90 debugsetparents
90 debugsetparents
91 debugstate
91 debugstate
92 debugsub
92 debugsub
93 debugwalk
93 debugwalk
94 debugwireargs
94 debugwireargs
95
95
96 Do not show the alias of a debug command if there are other candidates
96 Do not show the alias of a debug command if there are other candidates
97 (this should hide rawcommit)
97 (this should hide rawcommit)
98 $ hg debugcomplete r
98 $ hg debugcomplete r
99 recover
99 recover
100 remove
100 remove
101 rename
101 rename
102 resolve
102 resolve
103 revert
103 revert
104 rollback
104 rollback
105 root
105 root
106 Show the alias of a debug command if there are no other candidates
106 Show the alias of a debug command if there are no other candidates
107 $ hg debugcomplete rawc
107 $ hg debugcomplete rawc
108
108
109
109
110 Show the global options
110 Show the global options
111 $ hg debugcomplete --options | sort
111 $ hg debugcomplete --options | sort
112 --config
112 --config
113 --cwd
113 --cwd
114 --debug
114 --debug
115 --debugger
115 --debugger
116 --encoding
116 --encoding
117 --encodingmode
117 --encodingmode
118 --help
118 --help
119 --noninteractive
119 --noninteractive
120 --profile
120 --profile
121 --quiet
121 --quiet
122 --repository
122 --repository
123 --time
123 --time
124 --traceback
124 --traceback
125 --verbose
125 --verbose
126 --version
126 --version
127 -R
127 -R
128 -h
128 -h
129 -q
129 -q
130 -v
130 -v
131 -y
131 -y
132
132
133 Show the options for the "serve" command
133 Show the options for the "serve" command
134 $ hg debugcomplete --options serve | sort
134 $ hg debugcomplete --options serve | sort
135 --accesslog
135 --accesslog
136 --address
136 --address
137 --certificate
137 --certificate
138 --config
138 --config
139 --cwd
139 --cwd
140 --daemon
140 --daemon
141 --daemon-pipefds
141 --daemon-pipefds
142 --debug
142 --debug
143 --debugger
143 --debugger
144 --encoding
144 --encoding
145 --encodingmode
145 --encodingmode
146 --errorlog
146 --errorlog
147 --help
147 --help
148 --ipv6
148 --ipv6
149 --name
149 --name
150 --noninteractive
150 --noninteractive
151 --pid-file
151 --pid-file
152 --port
152 --port
153 --prefix
153 --prefix
154 --profile
154 --profile
155 --quiet
155 --quiet
156 --repository
156 --repository
157 --stdio
157 --stdio
158 --style
158 --style
159 --templates
159 --templates
160 --time
160 --time
161 --traceback
161 --traceback
162 --verbose
162 --verbose
163 --version
163 --version
164 --web-conf
164 --web-conf
165 -6
165 -6
166 -A
166 -A
167 -E
167 -E
168 -R
168 -R
169 -a
169 -a
170 -d
170 -d
171 -h
171 -h
172 -n
172 -n
173 -p
173 -p
174 -q
174 -q
175 -t
175 -t
176 -v
176 -v
177 -y
177 -y
178
178
179 Show an error if we use --options with an ambiguous abbreviation
179 Show an error if we use --options with an ambiguous abbreviation
180 $ hg debugcomplete --options s
180 $ hg debugcomplete --options s
181 hg: command 's' is ambiguous:
181 hg: command 's' is ambiguous:
182 serve showconfig status summary
182 serve showconfig status summary
183 [255]
183 [255]
184
184
185 Show all commands + options
185 Show all commands + options
186 $ hg debugcommands
186 $ hg debugcommands
187 add: include, exclude, subrepos, dry-run
187 add: include, exclude, subrepos, dry-run
188 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude
188 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude
189 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
189 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
190 commit: addremove, close-branch, include, exclude, message, logfile, date, user
190 commit: addremove, close-branch, include, exclude, message, logfile, date, user
191 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
191 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
192 export: output, switch-parent, rev, text, git, nodates
192 export: output, switch-parent, rev, text, git, nodates
193 forget: include, exclude
193 forget: include, exclude
194 init: ssh, remotecmd, insecure
194 init: ssh, remotecmd, insecure
195 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, style, template, include, exclude
195 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, style, template, include, exclude
196 merge: force, tool, rev, preview
196 merge: force, tool, rev, preview
197 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
197 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
198 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
198 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
199 remove: after, force, include, exclude
199 remove: after, force, include, exclude
200 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
200 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
201 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
201 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
202 summary: remote
202 summary: remote
203 update: clean, check, date, rev
203 update: clean, check, date, rev
204 addremove: similarity, include, exclude, dry-run
204 addremove: similarity, include, exclude, dry-run
205 archive: no-decode, prefix, rev, type, subrepos, include, exclude
205 archive: no-decode, prefix, rev, type, subrepos, include, exclude
206 backout: merge, parent, tool, rev, include, exclude, message, logfile, date, user
206 backout: merge, parent, tool, rev, include, exclude, message, logfile, date, user
207 bisect: reset, good, bad, skip, extend, command, noupdate
207 bisect: reset, good, bad, skip, extend, command, noupdate
208 bookmarks: force, rev, delete, rename, inactive
208 bookmarks: force, rev, delete, rename, inactive
209 branch: force, clean
209 branch: force, clean
210 branches: active, closed
210 branches: active, closed
211 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
211 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
212 cat: output, rev, decode, include, exclude
212 cat: output, rev, decode, include, exclude
213 copy: after, force, include, exclude, dry-run
213 copy: after, force, include, exclude, dry-run
214 debugancestor:
214 debugancestor:
215 debugbuilddag: mergeable-file, overwritten-file, new-file
215 debugbuilddag: mergeable-file, overwritten-file, new-file
216 debugbundle: all
216 debugbundle: all
217 debugcheckstate:
217 debugcheckstate:
218 debugcommands:
218 debugcommands:
219 debugcomplete: options
219 debugcomplete: options
220 debugdag: tags, branches, dots, spaces
220 debugdag: tags, branches, dots, spaces
221 debugdata:
221 debugdata:
222 debugdate: extended
222 debugdate: extended
223 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
223 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
224 debugfsinfo:
224 debugfsinfo:
225 debuggetbundle: head, common, type
225 debuggetbundle: head, common, type
226 debugignore:
226 debugignore:
227 debugindex: format
227 debugindex: format
228 debugindexdot:
228 debugindexdot:
229 debuginstall:
229 debuginstall:
230 debugknown:
230 debugknown:
231 debugpushkey:
231 debugpushkey:
232 debugrebuildstate: rev
232 debugrebuildstate: rev
233 debugrename: rev
233 debugrename: rev
234 debugrevspec:
234 debugrevspec:
235 debugsetparents:
235 debugsetparents:
236 debugstate: nodates, datesort
236 debugstate: nodates, datesort
237 debugsub: rev
237 debugsub: rev
238 debugwalk: include, exclude
238 debugwalk: include, exclude
239 debugwireargs: three, four, five, ssh, remotecmd, insecure
239 debugwireargs: three, four, five, ssh, remotecmd, insecure
240 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
240 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
241 heads: rev, topo, active, closed, style, template
241 heads: rev, topo, active, closed, style, template
242 help:
242 help: extension
243 identify: rev, num, id, branch, tags, bookmarks
243 identify: rev, num, id, branch, tags, bookmarks
244 import: strip, base, force, no-commit, exact, import-branch, message, logfile, date, user, similarity
244 import: strip, base, force, no-commit, exact, import-branch, message, logfile, date, user, similarity
245 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
245 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
246 locate: rev, print0, fullpath, include, exclude
246 locate: rev, print0, fullpath, include, exclude
247 manifest: rev
247 manifest: rev
248 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
248 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
249 parents: rev, style, template
249 parents: rev, style, template
250 paths:
250 paths:
251 recover:
251 recover:
252 rename: after, force, include, exclude, dry-run
252 rename: after, force, include, exclude, dry-run
253 resolve: all, list, mark, unmark, tool, no-status, include, exclude
253 resolve: all, list, mark, unmark, tool, no-status, include, exclude
254 revert: all, date, rev, no-backup, include, exclude, dry-run
254 revert: all, date, rev, no-backup, include, exclude, dry-run
255 rollback: dry-run
255 rollback: dry-run
256 root:
256 root:
257 showconfig: untrusted
257 showconfig: untrusted
258 tag: force, local, rev, remove, edit, message, date, user
258 tag: force, local, rev, remove, edit, message, date, user
259 tags:
259 tags:
260 tip: patch, git, style, template
260 tip: patch, git, style, template
261 unbundle: update
261 unbundle: update
262 verify:
262 verify:
263 version:
263 version:
@@ -1,325 +1,420 b''
1 Test basic extension support
1 Test basic extension support
2
2
3 $ "$TESTDIR/hghave" no-outer-repo || exit 80
3 $ "$TESTDIR/hghave" no-outer-repo || exit 80
4
4
5 $ cat > foobar.py <<EOF
5 $ cat > foobar.py <<EOF
6 > import os
6 > import os
7 > from mercurial import commands
7 > from mercurial import commands
8 >
8 >
9 > def uisetup(ui):
9 > def uisetup(ui):
10 > ui.write("uisetup called\\n")
10 > ui.write("uisetup called\\n")
11 >
11 >
12 > def reposetup(ui, repo):
12 > def reposetup(ui, repo):
13 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
13 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
14 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
14 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
15 >
15 >
16 > def foo(ui, *args, **kwargs):
16 > def foo(ui, *args, **kwargs):
17 > ui.write("Foo\\n")
17 > ui.write("Foo\\n")
18 >
18 >
19 > def bar(ui, *args, **kwargs):
19 > def bar(ui, *args, **kwargs):
20 > ui.write("Bar\\n")
20 > ui.write("Bar\\n")
21 >
21 >
22 > cmdtable = {
22 > cmdtable = {
23 > "foo": (foo, [], "hg foo"),
23 > "foo": (foo, [], "hg foo"),
24 > "bar": (bar, [], "hg bar"),
24 > "bar": (bar, [], "hg bar"),
25 > }
25 > }
26 >
26 >
27 > commands.norepo += ' bar'
27 > commands.norepo += ' bar'
28 > EOF
28 > EOF
29 $ abspath=`pwd`/foobar.py
29 $ abspath=`pwd`/foobar.py
30
30
31 $ mkdir barfoo
31 $ mkdir barfoo
32 $ cp foobar.py barfoo/__init__.py
32 $ cp foobar.py barfoo/__init__.py
33 $ barfoopath=`pwd`/barfoo
33 $ barfoopath=`pwd`/barfoo
34
34
35 $ hg init a
35 $ hg init a
36 $ cd a
36 $ cd a
37 $ echo foo > file
37 $ echo foo > file
38 $ hg add file
38 $ hg add file
39 $ hg commit -m 'add file'
39 $ hg commit -m 'add file'
40
40
41 $ echo '[extensions]' >> $HGRCPATH
41 $ echo '[extensions]' >> $HGRCPATH
42 $ echo "foobar = $abspath" >> $HGRCPATH
42 $ echo "foobar = $abspath" >> $HGRCPATH
43 $ hg foo
43 $ hg foo
44 uisetup called
44 uisetup called
45 reposetup called for a
45 reposetup called for a
46 ui == repo.ui
46 ui == repo.ui
47 Foo
47 Foo
48
48
49 $ cd ..
49 $ cd ..
50 $ hg clone a b
50 $ hg clone a b
51 uisetup called
51 uisetup called
52 reposetup called for a
52 reposetup called for a
53 ui == repo.ui
53 ui == repo.ui
54 reposetup called for b
54 reposetup called for b
55 ui == repo.ui
55 ui == repo.ui
56 updating to branch default
56 updating to branch default
57 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
57 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
58
58
59 $ hg bar
59 $ hg bar
60 uisetup called
60 uisetup called
61 Bar
61 Bar
62 $ echo 'foobar = !' >> $HGRCPATH
62 $ echo 'foobar = !' >> $HGRCPATH
63
63
64 module/__init__.py-style
64 module/__init__.py-style
65
65
66 $ echo "barfoo = $barfoopath" >> $HGRCPATH
66 $ echo "barfoo = $barfoopath" >> $HGRCPATH
67 $ cd a
67 $ cd a
68 $ hg foo
68 $ hg foo
69 uisetup called
69 uisetup called
70 reposetup called for a
70 reposetup called for a
71 ui == repo.ui
71 ui == repo.ui
72 Foo
72 Foo
73 $ echo 'barfoo = !' >> $HGRCPATH
73 $ echo 'barfoo = !' >> $HGRCPATH
74
74
75 Check that extensions are loaded in phases:
75 Check that extensions are loaded in phases:
76
76
77 $ cat > foo.py <<EOF
77 $ cat > foo.py <<EOF
78 > import os
78 > import os
79 > name = os.path.basename(__file__).rsplit('.', 1)[0]
79 > name = os.path.basename(__file__).rsplit('.', 1)[0]
80 > print "1) %s imported" % name
80 > print "1) %s imported" % name
81 > def uisetup(ui):
81 > def uisetup(ui):
82 > print "2) %s uisetup" % name
82 > print "2) %s uisetup" % name
83 > def extsetup():
83 > def extsetup():
84 > print "3) %s extsetup" % name
84 > print "3) %s extsetup" % name
85 > def reposetup(ui, repo):
85 > def reposetup(ui, repo):
86 > print "4) %s reposetup" % name
86 > print "4) %s reposetup" % name
87 > EOF
87 > EOF
88
88
89 $ cp foo.py bar.py
89 $ cp foo.py bar.py
90 $ echo 'foo = foo.py' >> $HGRCPATH
90 $ echo 'foo = foo.py' >> $HGRCPATH
91 $ echo 'bar = bar.py' >> $HGRCPATH
91 $ echo 'bar = bar.py' >> $HGRCPATH
92
92
93 Command with no output, we just want to see the extensions loaded:
93 Command with no output, we just want to see the extensions loaded:
94
94
95 $ hg paths
95 $ hg paths
96 1) foo imported
96 1) foo imported
97 1) bar imported
97 1) bar imported
98 2) foo uisetup
98 2) foo uisetup
99 2) bar uisetup
99 2) bar uisetup
100 3) foo extsetup
100 3) foo extsetup
101 3) bar extsetup
101 3) bar extsetup
102 4) foo reposetup
102 4) foo reposetup
103 4) bar reposetup
103 4) bar reposetup
104
104
105 Check hgweb's load order:
105 Check hgweb's load order:
106
106
107 $ cat > hgweb.cgi <<EOF
107 $ cat > hgweb.cgi <<EOF
108 > #!/usr/bin/env python
108 > #!/usr/bin/env python
109 > from mercurial import demandimport; demandimport.enable()
109 > from mercurial import demandimport; demandimport.enable()
110 > from mercurial.hgweb import hgweb
110 > from mercurial.hgweb import hgweb
111 > from mercurial.hgweb import wsgicgi
111 > from mercurial.hgweb import wsgicgi
112 >
112 >
113 > application = hgweb('.', 'test repo')
113 > application = hgweb('.', 'test repo')
114 > wsgicgi.launch(application)
114 > wsgicgi.launch(application)
115 > EOF
115 > EOF
116
116
117 $ SCRIPT_NAME='/' SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
117 $ SCRIPT_NAME='/' SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
118 > | grep '^[0-9]) ' # ignores HTML output
118 > | grep '^[0-9]) ' # ignores HTML output
119 1) foo imported
119 1) foo imported
120 1) bar imported
120 1) bar imported
121 2) foo uisetup
121 2) foo uisetup
122 2) bar uisetup
122 2) bar uisetup
123 3) foo extsetup
123 3) foo extsetup
124 3) bar extsetup
124 3) bar extsetup
125 4) foo reposetup
125 4) foo reposetup
126 4) bar reposetup
126 4) bar reposetup
127 4) foo reposetup
127 4) foo reposetup
128 4) bar reposetup
128 4) bar reposetup
129
129
130 $ echo 'foo = !' >> $HGRCPATH
130 $ echo 'foo = !' >> $HGRCPATH
131 $ echo 'bar = !' >> $HGRCPATH
131 $ echo 'bar = !' >> $HGRCPATH
132
132
133 $ cd ..
133 $ cd ..
134
134
135 $ cat > empty.py <<EOF
135 $ cat > empty.py <<EOF
136 > '''empty cmdtable
136 > '''empty cmdtable
137 > '''
137 > '''
138 > cmdtable = {}
138 > cmdtable = {}
139 > EOF
139 > EOF
140 $ emptypath=`pwd`/empty.py
140 $ emptypath=`pwd`/empty.py
141 $ echo "empty = $emptypath" >> $HGRCPATH
141 $ echo "empty = $emptypath" >> $HGRCPATH
142 $ hg help empty
142 $ hg help empty
143 empty extension - empty cmdtable
143 empty extension - empty cmdtable
144
144
145 no commands defined
145 no commands defined
146
146
147 $ echo 'empty = !' >> $HGRCPATH
147 $ echo 'empty = !' >> $HGRCPATH
148
148
149 $ cat > debugextension.py <<EOF
149 $ cat > debugextension.py <<EOF
150 > '''only debugcommands
150 > '''only debugcommands
151 > '''
151 > '''
152 > def debugfoobar(ui, repo, *args, **opts):
152 > def debugfoobar(ui, repo, *args, **opts):
153 > "yet another debug command"
153 > "yet another debug command"
154 > pass
154 > pass
155 >
155 >
156 > def foo(ui, repo, *args, **opts):
156 > def foo(ui, repo, *args, **opts):
157 > """yet another foo command
157 > """yet another foo command
158 >
158 >
159 > This command has been DEPRECATED since forever.
159 > This command has been DEPRECATED since forever.
160 > """
160 > """
161 > pass
161 > pass
162 >
162 >
163 > cmdtable = {
163 > cmdtable = {
164 > "debugfoobar": (debugfoobar, (), "hg debugfoobar"),
164 > "debugfoobar": (debugfoobar, (), "hg debugfoobar"),
165 > "foo": (foo, (), "hg foo")
165 > "foo": (foo, (), "hg foo")
166 > }
166 > }
167 > EOF
167 > EOF
168 $ debugpath=`pwd`/debugextension.py
168 $ debugpath=`pwd`/debugextension.py
169 $ echo "debugextension = $debugpath" >> $HGRCPATH
169 $ echo "debugextension = $debugpath" >> $HGRCPATH
170
170
171 $ hg help debugextension
171 $ hg help debugextension
172 debugextension extension - only debugcommands
172 debugextension extension - only debugcommands
173
173
174 no commands defined
174 no commands defined
175
175
176 $ hg --verbose help debugextension
176 $ hg --verbose help debugextension
177 debugextension extension - only debugcommands
177 debugextension extension - only debugcommands
178
178
179 list of commands:
179 list of commands:
180
180
181 foo:
181 foo:
182 yet another foo command
182 yet another foo command
183
183
184 global options:
184 global options:
185 -R --repository REPO repository root directory or name of overlay bundle
185 -R --repository REPO repository root directory or name of overlay bundle
186 file
186 file
187 --cwd DIR change working directory
187 --cwd DIR change working directory
188 -y --noninteractive do not prompt, assume 'yes' for any required answers
188 -y --noninteractive do not prompt, assume 'yes' for any required answers
189 -q --quiet suppress output
189 -q --quiet suppress output
190 -v --verbose enable additional output
190 -v --verbose enable additional output
191 --config CONFIG [+] set/override config option (use 'section.name=value')
191 --config CONFIG [+] set/override config option (use 'section.name=value')
192 --debug enable debugging output
192 --debug enable debugging output
193 --debugger start debugger
193 --debugger start debugger
194 --encoding ENCODE set the charset encoding (default: ascii)
194 --encoding ENCODE set the charset encoding (default: ascii)
195 --encodingmode MODE set the charset encoding mode (default: strict)
195 --encodingmode MODE set the charset encoding mode (default: strict)
196 --traceback always print a traceback on exception
196 --traceback always print a traceback on exception
197 --time time how long the command takes
197 --time time how long the command takes
198 --profile print command execution profile
198 --profile print command execution profile
199 --version output version information and exit
199 --version output version information and exit
200 -h --help display help and exit
200 -h --help display help and exit
201
201
202 [+] marked option can be specified multiple times
202 [+] marked option can be specified multiple times
203
203
204 $ hg --debug help debugextension
204 $ hg --debug help debugextension
205 debugextension extension - only debugcommands
205 debugextension extension - only debugcommands
206
206
207 list of commands:
207 list of commands:
208
208
209 debugfoobar:
209 debugfoobar:
210 yet another debug command
210 yet another debug command
211 foo:
211 foo:
212 yet another foo command
212 yet another foo command
213
213
214 global options:
214 global options:
215 -R --repository REPO repository root directory or name of overlay bundle
215 -R --repository REPO repository root directory or name of overlay bundle
216 file
216 file
217 --cwd DIR change working directory
217 --cwd DIR change working directory
218 -y --noninteractive do not prompt, assume 'yes' for any required answers
218 -y --noninteractive do not prompt, assume 'yes' for any required answers
219 -q --quiet suppress output
219 -q --quiet suppress output
220 -v --verbose enable additional output
220 -v --verbose enable additional output
221 --config CONFIG [+] set/override config option (use 'section.name=value')
221 --config CONFIG [+] set/override config option (use 'section.name=value')
222 --debug enable debugging output
222 --debug enable debugging output
223 --debugger start debugger
223 --debugger start debugger
224 --encoding ENCODE set the charset encoding (default: ascii)
224 --encoding ENCODE set the charset encoding (default: ascii)
225 --encodingmode MODE set the charset encoding mode (default: strict)
225 --encodingmode MODE set the charset encoding mode (default: strict)
226 --traceback always print a traceback on exception
226 --traceback always print a traceback on exception
227 --time time how long the command takes
227 --time time how long the command takes
228 --profile print command execution profile
228 --profile print command execution profile
229 --version output version information and exit
229 --version output version information and exit
230 -h --help display help and exit
230 -h --help display help and exit
231
231
232 [+] marked option can be specified multiple times
232 [+] marked option can be specified multiple times
233 $ echo 'debugextension = !' >> $HGRCPATH
233 $ echo 'debugextension = !' >> $HGRCPATH
234
234
235 Extension module help vs command help:
236
237 $ echo 'extdiff =' >> $HGRCPATH
238 $ hg help extdiff
239 hg extdiff [OPT]... [FILE]...
240
241 use external program to diff repository (or selected files)
242
243 Show differences between revisions for the specified files, using an
244 external program. The default program used is diff, with default options
245 "-Npru".
246
247 To select a different program, use the -p/--program option. The program
248 will be passed the names of two directories to compare. To pass additional
249 options to the program, use -o/--option. These will be passed before the
250 names of the directories to compare.
251
252 When two revision arguments are given, then changes are shown between
253 those revisions. If only one revision is specified then that revision is
254 compared to the working directory, and, when no revisions are specified,
255 the working directory files are compared to its parent.
256
257 options:
258
259 -p --program CMD comparison program to run
260 -o --option OPT [+] pass option to comparison program
261 -r --rev REV [+] revision
262 -c --change REV change made by revision
263 -I --include PATTERN [+] include names matching the given patterns
264 -X --exclude PATTERN [+] exclude names matching the given patterns
265
266 [+] marked option can be specified multiple times
267
268 use "hg -v help extdiff" to show global options
269
270 $ hg help --extension extdiff
271 extdiff extension - command to allow external programs to compare revisions
272
273 The extdiff Mercurial extension allows you to use external programs to compare
274 revisions, or revision with working directory. The external diff programs are
275 called with a configurable set of options and two non-option arguments: paths
276 to directories containing snapshots of files to compare.
277
278 The extdiff extension also allows to configure new diff commands, so you do
279 not need to type "hg extdiff -p kdiff3" always.
280
281 [extdiff]
282 # add new command that runs GNU diff(1) in 'context diff' mode
283 cdiff = gdiff -Nprc5
284 ## or the old way:
285 #cmd.cdiff = gdiff
286 #opts.cdiff = -Nprc5
287
288 # add new command called vdiff, runs kdiff3
289 vdiff = kdiff3
290
291 # add new command called meld, runs meld (no need to name twice)
292 meld =
293
294 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
295 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
296 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
297 # your .vimrc
298 vimdiff = gvim -f '+next' '+execute "DirDiff" argv(0) argv(1)'
299
300 Tool arguments can include variables that are expanded at runtime:
301
302 $parent1, $plabel1 - filename, descriptive label of first parent
303 $child, $clabel - filename, descriptive label of child revision
304 $parent2, $plabel2 - filename, descriptive label of second parent
305 $root - repository root
306 $parent is an alias for $parent1.
307
308 The extdiff extension will look in your [diff-tools] and [merge-tools]
309 sections for diff tool arguments, when none are specified in [extdiff].
310
311 [extdiff]
312 kdiff3 =
313
314 [diff-tools]
315 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
316
317 You can use -I/-X and list of file or directory names like normal "hg diff"
318 command. The extdiff extension makes snapshots of only needed files, so
319 running the external diff program will actually be pretty fast (at least
320 faster than having to compare the entire tree).
321
322 list of commands:
323
324 extdiff use external program to diff repository (or selected files)
325
326 use "hg -v help extdiff" to show builtin aliases and global options
327
328 $ echo 'extdiff = !' >> $HGRCPATH
329
235 Issue811: Problem loading extensions twice (by site and by user)
330 Issue811: Problem loading extensions twice (by site and by user)
236
331
237 $ debugpath=`pwd`/debugissue811.py
332 $ debugpath=`pwd`/debugissue811.py
238 $ cat > debugissue811.py <<EOF
333 $ cat > debugissue811.py <<EOF
239 > '''show all loaded extensions
334 > '''show all loaded extensions
240 > '''
335 > '''
241 > from mercurial import extensions, commands
336 > from mercurial import extensions, commands
242 >
337 >
243 > def debugextensions(ui):
338 > def debugextensions(ui):
244 > "yet another debug command"
339 > "yet another debug command"
245 > ui.write("%s\n" % '\n'.join([x for x, y in extensions.extensions()]))
340 > ui.write("%s\n" % '\n'.join([x for x, y in extensions.extensions()]))
246 >
341 >
247 > cmdtable = {"debugextensions": (debugextensions, (), "hg debugextensions")}
342 > cmdtable = {"debugextensions": (debugextensions, (), "hg debugextensions")}
248 > commands.norepo += " debugextensions"
343 > commands.norepo += " debugextensions"
249 > EOF
344 > EOF
250 $ echo "debugissue811 = $debugpath" >> $HGRCPATH
345 $ echo "debugissue811 = $debugpath" >> $HGRCPATH
251 $ echo "mq=" >> $HGRCPATH
346 $ echo "mq=" >> $HGRCPATH
252 $ echo "hgext.mq=" >> $HGRCPATH
347 $ echo "hgext.mq=" >> $HGRCPATH
253 $ echo "hgext/mq=" >> $HGRCPATH
348 $ echo "hgext/mq=" >> $HGRCPATH
254
349
255 Show extensions:
350 Show extensions:
256
351
257 $ hg debugextensions
352 $ hg debugextensions
258 debugissue811
353 debugissue811
259 mq
354 mq
260
355
261 Disabled extension commands:
356 Disabled extension commands:
262
357
263 $ HGRCPATH=
358 $ HGRCPATH=
264 $ export HGRCPATH
359 $ export HGRCPATH
265 $ hg help email
360 $ hg help email
266 'email' is provided by the following extension:
361 'email' is provided by the following extension:
267
362
268 patchbomb command to send changesets as (a series of) patch emails
363 patchbomb command to send changesets as (a series of) patch emails
269
364
270 use "hg help extensions" for information on enabling extensions
365 use "hg help extensions" for information on enabling extensions
271 $ hg qdel
366 $ hg qdel
272 hg: unknown command 'qdel'
367 hg: unknown command 'qdel'
273 'qdelete' is provided by the following extension:
368 'qdelete' is provided by the following extension:
274
369
275 mq manage a stack of patches
370 mq manage a stack of patches
276
371
277 use "hg help extensions" for information on enabling extensions
372 use "hg help extensions" for information on enabling extensions
278 [255]
373 [255]
279 $ hg churn
374 $ hg churn
280 hg: unknown command 'churn'
375 hg: unknown command 'churn'
281 'churn' is provided by the following extension:
376 'churn' is provided by the following extension:
282
377
283 churn command to display statistics about repository history
378 churn command to display statistics about repository history
284
379
285 use "hg help extensions" for information on enabling extensions
380 use "hg help extensions" for information on enabling extensions
286 [255]
381 [255]
287
382
288 Disabled extensions:
383 Disabled extensions:
289
384
290 $ hg help churn
385 $ hg help churn
291 churn extension - command to display statistics about repository history
386 churn extension - command to display statistics about repository history
292
387
293 use "hg help extensions" for information on enabling extensions
388 use "hg help extensions" for information on enabling extensions
294 $ hg help patchbomb
389 $ hg help patchbomb
295 patchbomb extension - command to send changesets as (a series of) patch emails
390 patchbomb extension - command to send changesets as (a series of) patch emails
296
391
297 use "hg help extensions" for information on enabling extensions
392 use "hg help extensions" for information on enabling extensions
298
393
299 Broken disabled extension and command:
394 Broken disabled extension and command:
300
395
301 $ mkdir hgext
396 $ mkdir hgext
302 $ echo > hgext/__init__.py
397 $ echo > hgext/__init__.py
303 $ cat > hgext/broken.py <<EOF
398 $ cat > hgext/broken.py <<EOF
304 > "broken extension'
399 > "broken extension'
305 > EOF
400 > EOF
306 $ cat > path.py <<EOF
401 $ cat > path.py <<EOF
307 > import os, sys
402 > import os, sys
308 > sys.path.insert(0, os.environ['HGEXTPATH'])
403 > sys.path.insert(0, os.environ['HGEXTPATH'])
309 > EOF
404 > EOF
310 $ HGEXTPATH=`pwd`
405 $ HGEXTPATH=`pwd`
311 $ export HGEXTPATH
406 $ export HGEXTPATH
312
407
313 $ hg --config extensions.path=./path.py help broken
408 $ hg --config extensions.path=./path.py help broken
314 broken extension - (no help text available)
409 broken extension - (no help text available)
315
410
316 use "hg help extensions" for information on enabling extensions
411 use "hg help extensions" for information on enabling extensions
317
412
318 $ cat > hgext/forest.py <<EOF
413 $ cat > hgext/forest.py <<EOF
319 > cmdtable = None
414 > cmdtable = None
320 > EOF
415 > EOF
321 $ hg --config extensions.path=./path.py help foo > /dev/null
416 $ hg --config extensions.path=./path.py help foo > /dev/null
322 warning: error finding commands in $TESTTMP/hgext/forest.py
417 warning: error finding commands in $TESTTMP/hgext/forest.py
323 hg: unknown command 'foo'
418 hg: unknown command 'foo'
324 warning: error finding commands in $TESTTMP/hgext/forest.py
419 warning: error finding commands in $TESTTMP/hgext/forest.py
325 [255]
420 [255]
General Comments 0
You need to be logged in to leave comments. Login now