##// END OF EJS Templates
help: do not show full help text for command on option errors...
Adrian Buehlmann -
r13950:14d0553b default
parent child Browse files
Show More
@@ -1,4889 +1,4891 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, util, revlog, extensions, copies, error, bookmarks
12 import hg, util, revlog, extensions, copies, error, bookmarks
13 import patch, help, mdiff, url, encoding, templatekw, discovery
13 import patch, help, mdiff, 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
17 import dagparser
18
18
19 # Commands start here, listed alphabetically
19 # Commands start here, listed alphabetically
20
20
21 def add(ui, repo, *pats, **opts):
21 def add(ui, repo, *pats, **opts):
22 """add the specified files on the next commit
22 """add the specified files on the next commit
23
23
24 Schedule files to be version controlled and added to the
24 Schedule files to be version controlled and added to the
25 repository.
25 repository.
26
26
27 The files will be added to the repository at the next commit. To
27 The files will be added to the repository at the next commit. To
28 undo an add before that, see :hg:`forget`.
28 undo an add before that, see :hg:`forget`.
29
29
30 If no names are given, add all files to the repository.
30 If no names are given, add all files to the repository.
31
31
32 .. container:: verbose
32 .. container:: verbose
33
33
34 An example showing how new (unknown) files are added
34 An example showing how new (unknown) files are added
35 automatically by :hg:`add`::
35 automatically by :hg:`add`::
36
36
37 $ ls
37 $ ls
38 foo.c
38 foo.c
39 $ hg status
39 $ hg status
40 ? foo.c
40 ? foo.c
41 $ hg add
41 $ hg add
42 adding foo.c
42 adding foo.c
43 $ hg status
43 $ hg status
44 A foo.c
44 A foo.c
45
45
46 Returns 0 if all files are successfully added.
46 Returns 0 if all files are successfully added.
47 """
47 """
48
48
49 m = cmdutil.match(repo, pats, opts)
49 m = cmdutil.match(repo, pats, opts)
50 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
50 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
51 opts.get('subrepos'), prefix="")
51 opts.get('subrepos'), prefix="")
52 return rejected and 1 or 0
52 return rejected and 1 or 0
53
53
54 def addremove(ui, repo, *pats, **opts):
54 def addremove(ui, repo, *pats, **opts):
55 """add all new files, delete all missing files
55 """add all new files, delete all missing files
56
56
57 Add all new files and remove all missing files from the
57 Add all new files and remove all missing files from the
58 repository.
58 repository.
59
59
60 New files are ignored if they match any of the patterns in
60 New files are ignored if they match any of the patterns in
61 ``.hgignore``. As with add, these changes take effect at the next
61 ``.hgignore``. As with add, these changes take effect at the next
62 commit.
62 commit.
63
63
64 Use the -s/--similarity option to detect renamed files. With a
64 Use the -s/--similarity option to detect renamed files. With a
65 parameter greater than 0, this compares every removed file with
65 parameter greater than 0, this compares every removed file with
66 every added file and records those similar enough as renames. This
66 every added file and records those similar enough as renames. This
67 option takes a percentage between 0 (disabled) and 100 (files must
67 option takes a percentage between 0 (disabled) and 100 (files must
68 be identical) as its parameter. Detecting renamed files this way
68 be identical) as its parameter. Detecting renamed files this way
69 can be expensive. After using this option, :hg:`status -C` can be
69 can be expensive. After using this option, :hg:`status -C` can be
70 used to check which files were identified as moved or renamed.
70 used to check which files were identified as moved or renamed.
71
71
72 Returns 0 if all files are successfully added.
72 Returns 0 if all files are successfully added.
73 """
73 """
74 try:
74 try:
75 sim = float(opts.get('similarity') or 100)
75 sim = float(opts.get('similarity') or 100)
76 except ValueError:
76 except ValueError:
77 raise util.Abort(_('similarity must be a number'))
77 raise util.Abort(_('similarity must be a number'))
78 if sim < 0 or sim > 100:
78 if sim < 0 or sim > 100:
79 raise util.Abort(_('similarity must be between 0 and 100'))
79 raise util.Abort(_('similarity must be between 0 and 100'))
80 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
80 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
81
81
82 def annotate(ui, repo, *pats, **opts):
82 def annotate(ui, repo, *pats, **opts):
83 """show changeset information by line for each file
83 """show changeset information by line for each file
84
84
85 List changes in files, showing the revision id responsible for
85 List changes in files, showing the revision id responsible for
86 each line
86 each line
87
87
88 This command is useful for discovering when a change was made and
88 This command is useful for discovering when a change was made and
89 by whom.
89 by whom.
90
90
91 Without the -a/--text option, annotate will avoid processing files
91 Without the -a/--text option, annotate will avoid processing files
92 it detects as binary. With -a, annotate will annotate the file
92 it detects as binary. With -a, annotate will annotate the file
93 anyway, although the results will probably be neither useful
93 anyway, although the results will probably be neither useful
94 nor desirable.
94 nor desirable.
95
95
96 Returns 0 on success.
96 Returns 0 on success.
97 """
97 """
98 if opts.get('follow'):
98 if opts.get('follow'):
99 # --follow is deprecated and now just an alias for -f/--file
99 # --follow is deprecated and now just an alias for -f/--file
100 # to mimic the behavior of Mercurial before version 1.5
100 # to mimic the behavior of Mercurial before version 1.5
101 opts['file'] = 1
101 opts['file'] = 1
102
102
103 datefunc = ui.quiet and util.shortdate or util.datestr
103 datefunc = ui.quiet and util.shortdate or util.datestr
104 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
104 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
105
105
106 if not pats:
106 if not pats:
107 raise util.Abort(_('at least one filename or pattern is required'))
107 raise util.Abort(_('at least one filename or pattern is required'))
108
108
109 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
109 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
110 ('number', lambda x: str(x[0].rev())),
110 ('number', lambda x: str(x[0].rev())),
111 ('changeset', lambda x: short(x[0].node())),
111 ('changeset', lambda x: short(x[0].node())),
112 ('date', getdate),
112 ('date', getdate),
113 ('file', lambda x: x[0].path()),
113 ('file', lambda x: x[0].path()),
114 ]
114 ]
115
115
116 if (not opts.get('user') and not opts.get('changeset')
116 if (not opts.get('user') and not opts.get('changeset')
117 and not opts.get('date') and not opts.get('file')):
117 and not opts.get('date') and not opts.get('file')):
118 opts['number'] = 1
118 opts['number'] = 1
119
119
120 linenumber = opts.get('line_number') is not None
120 linenumber = opts.get('line_number') is not None
121 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
121 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
122 raise util.Abort(_('at least one of -n/-c is required for -l'))
122 raise util.Abort(_('at least one of -n/-c is required for -l'))
123
123
124 funcmap = [func for op, func in opmap if opts.get(op)]
124 funcmap = [func for op, func in opmap if opts.get(op)]
125 if linenumber:
125 if linenumber:
126 lastfunc = funcmap[-1]
126 lastfunc = funcmap[-1]
127 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
127 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
128
128
129 def bad(x, y):
129 def bad(x, y):
130 raise util.Abort("%s: %s" % (x, y))
130 raise util.Abort("%s: %s" % (x, y))
131
131
132 ctx = cmdutil.revsingle(repo, opts.get('rev'))
132 ctx = cmdutil.revsingle(repo, opts.get('rev'))
133 m = cmdutil.match(repo, pats, opts)
133 m = cmdutil.match(repo, pats, opts)
134 m.bad = bad
134 m.bad = bad
135 follow = not opts.get('no_follow')
135 follow = not opts.get('no_follow')
136 for abs in ctx.walk(m):
136 for abs in ctx.walk(m):
137 fctx = ctx[abs]
137 fctx = ctx[abs]
138 if not opts.get('text') and util.binary(fctx.data()):
138 if not opts.get('text') and util.binary(fctx.data()):
139 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
139 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
140 continue
140 continue
141
141
142 lines = fctx.annotate(follow=follow, linenumber=linenumber)
142 lines = fctx.annotate(follow=follow, linenumber=linenumber)
143 pieces = []
143 pieces = []
144
144
145 for f in funcmap:
145 for f in funcmap:
146 l = [f(n) for n, dummy in lines]
146 l = [f(n) for n, dummy in lines]
147 if l:
147 if l:
148 sized = [(x, encoding.colwidth(x)) for x in l]
148 sized = [(x, encoding.colwidth(x)) for x in l]
149 ml = max([w for x, w in sized])
149 ml = max([w for x, w in sized])
150 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
150 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
151
151
152 if pieces:
152 if pieces:
153 for p, l in zip(zip(*pieces), lines):
153 for p, l in zip(zip(*pieces), lines):
154 ui.write("%s: %s" % (" ".join(p), l[1]))
154 ui.write("%s: %s" % (" ".join(p), l[1]))
155
155
156 def archive(ui, repo, dest, **opts):
156 def archive(ui, repo, dest, **opts):
157 '''create an unversioned archive of a repository revision
157 '''create an unversioned archive of a repository revision
158
158
159 By default, the revision used is the parent of the working
159 By default, the revision used is the parent of the working
160 directory; use -r/--rev to specify a different revision.
160 directory; use -r/--rev to specify a different revision.
161
161
162 The archive type is automatically detected based on file
162 The archive type is automatically detected based on file
163 extension (or override using -t/--type).
163 extension (or override using -t/--type).
164
164
165 Valid types are:
165 Valid types are:
166
166
167 :``files``: a directory full of files (default)
167 :``files``: a directory full of files (default)
168 :``tar``: tar archive, uncompressed
168 :``tar``: tar archive, uncompressed
169 :``tbz2``: tar archive, compressed using bzip2
169 :``tbz2``: tar archive, compressed using bzip2
170 :``tgz``: tar archive, compressed using gzip
170 :``tgz``: tar archive, compressed using gzip
171 :``uzip``: zip archive, uncompressed
171 :``uzip``: zip archive, uncompressed
172 :``zip``: zip archive, compressed using deflate
172 :``zip``: zip archive, compressed using deflate
173
173
174 The exact name of the destination archive or directory is given
174 The exact name of the destination archive or directory is given
175 using a format string; see :hg:`help export` for details.
175 using a format string; see :hg:`help export` for details.
176
176
177 Each member added to an archive file has a directory prefix
177 Each member added to an archive file has a directory prefix
178 prepended. Use -p/--prefix to specify a format string for the
178 prepended. Use -p/--prefix to specify a format string for the
179 prefix. The default is the basename of the archive, with suffixes
179 prefix. The default is the basename of the archive, with suffixes
180 removed.
180 removed.
181
181
182 Returns 0 on success.
182 Returns 0 on success.
183 '''
183 '''
184
184
185 ctx = cmdutil.revsingle(repo, opts.get('rev'))
185 ctx = cmdutil.revsingle(repo, opts.get('rev'))
186 if not ctx:
186 if not ctx:
187 raise util.Abort(_('no working directory: please specify a revision'))
187 raise util.Abort(_('no working directory: please specify a revision'))
188 node = ctx.node()
188 node = ctx.node()
189 dest = cmdutil.make_filename(repo, dest, node)
189 dest = cmdutil.make_filename(repo, dest, node)
190 if os.path.realpath(dest) == repo.root:
190 if os.path.realpath(dest) == repo.root:
191 raise util.Abort(_('repository root cannot be destination'))
191 raise util.Abort(_('repository root cannot be destination'))
192
192
193 kind = opts.get('type') or archival.guesskind(dest) or 'files'
193 kind = opts.get('type') or archival.guesskind(dest) or 'files'
194 prefix = opts.get('prefix')
194 prefix = opts.get('prefix')
195
195
196 if dest == '-':
196 if dest == '-':
197 if kind == 'files':
197 if kind == 'files':
198 raise util.Abort(_('cannot archive plain files to stdout'))
198 raise util.Abort(_('cannot archive plain files to stdout'))
199 dest = sys.stdout
199 dest = sys.stdout
200 if not prefix:
200 if not prefix:
201 prefix = os.path.basename(repo.root) + '-%h'
201 prefix = os.path.basename(repo.root) + '-%h'
202
202
203 prefix = cmdutil.make_filename(repo, prefix, node)
203 prefix = cmdutil.make_filename(repo, prefix, node)
204 matchfn = cmdutil.match(repo, [], opts)
204 matchfn = cmdutil.match(repo, [], opts)
205 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
205 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
206 matchfn, prefix, subrepos=opts.get('subrepos'))
206 matchfn, prefix, subrepos=opts.get('subrepos'))
207
207
208 def backout(ui, repo, node=None, rev=None, **opts):
208 def backout(ui, repo, node=None, rev=None, **opts):
209 '''reverse effect of earlier changeset
209 '''reverse effect of earlier changeset
210
210
211 Prepare a new changeset with the effect of REV undone in the
211 Prepare a new changeset with the effect of REV undone in the
212 current working directory.
212 current working directory.
213
213
214 If REV is the parent of the working directory, then this new changeset
214 If REV is the parent of the working directory, then this new changeset
215 is committed automatically. Otherwise, hg needs to merge the
215 is committed automatically. Otherwise, hg needs to merge the
216 changes and the merged result is left uncommitted.
216 changes and the merged result is left uncommitted.
217
217
218 By default, the pending changeset will have one parent,
218 By default, the pending changeset will have one parent,
219 maintaining a linear history. With --merge, the pending changeset
219 maintaining a linear history. With --merge, the pending changeset
220 will instead have two parents: the old parent of the working
220 will instead have two parents: the old parent of the working
221 directory and a new child of REV that simply undoes REV.
221 directory and a new child of REV that simply undoes REV.
222
222
223 Before version 1.7, the behavior without --merge was equivalent to
223 Before version 1.7, the behavior without --merge was equivalent to
224 specifying --merge followed by :hg:`update --clean .` to cancel
224 specifying --merge followed by :hg:`update --clean .` to cancel
225 the merge and leave the child of REV as a head to be merged
225 the merge and leave the child of REV as a head to be merged
226 separately.
226 separately.
227
227
228 See :hg:`help dates` for a list of formats valid for -d/--date.
228 See :hg:`help dates` for a list of formats valid for -d/--date.
229
229
230 Returns 0 on success.
230 Returns 0 on success.
231 '''
231 '''
232 if rev and node:
232 if rev and node:
233 raise util.Abort(_("please specify just one revision"))
233 raise util.Abort(_("please specify just one revision"))
234
234
235 if not rev:
235 if not rev:
236 rev = node
236 rev = node
237
237
238 if not rev:
238 if not rev:
239 raise util.Abort(_("please specify a revision to backout"))
239 raise util.Abort(_("please specify a revision to backout"))
240
240
241 date = opts.get('date')
241 date = opts.get('date')
242 if date:
242 if date:
243 opts['date'] = util.parsedate(date)
243 opts['date'] = util.parsedate(date)
244
244
245 cmdutil.bail_if_changed(repo)
245 cmdutil.bail_if_changed(repo)
246 node = cmdutil.revsingle(repo, rev).node()
246 node = cmdutil.revsingle(repo, rev).node()
247
247
248 op1, op2 = repo.dirstate.parents()
248 op1, op2 = repo.dirstate.parents()
249 a = repo.changelog.ancestor(op1, node)
249 a = repo.changelog.ancestor(op1, node)
250 if a != node:
250 if a != node:
251 raise util.Abort(_('cannot backout change on a different branch'))
251 raise util.Abort(_('cannot backout change on a different branch'))
252
252
253 p1, p2 = repo.changelog.parents(node)
253 p1, p2 = repo.changelog.parents(node)
254 if p1 == nullid:
254 if p1 == nullid:
255 raise util.Abort(_('cannot backout a change with no parents'))
255 raise util.Abort(_('cannot backout a change with no parents'))
256 if p2 != nullid:
256 if p2 != nullid:
257 if not opts.get('parent'):
257 if not opts.get('parent'):
258 raise util.Abort(_('cannot backout a merge changeset without '
258 raise util.Abort(_('cannot backout a merge changeset without '
259 '--parent'))
259 '--parent'))
260 p = repo.lookup(opts['parent'])
260 p = repo.lookup(opts['parent'])
261 if p not in (p1, p2):
261 if p not in (p1, p2):
262 raise util.Abort(_('%s is not a parent of %s') %
262 raise util.Abort(_('%s is not a parent of %s') %
263 (short(p), short(node)))
263 (short(p), short(node)))
264 parent = p
264 parent = p
265 else:
265 else:
266 if opts.get('parent'):
266 if opts.get('parent'):
267 raise util.Abort(_('cannot use --parent on non-merge changeset'))
267 raise util.Abort(_('cannot use --parent on non-merge changeset'))
268 parent = p1
268 parent = p1
269
269
270 # the backout should appear on the same branch
270 # the backout should appear on the same branch
271 branch = repo.dirstate.branch()
271 branch = repo.dirstate.branch()
272 hg.clean(repo, node, show_stats=False)
272 hg.clean(repo, node, show_stats=False)
273 repo.dirstate.setbranch(branch)
273 repo.dirstate.setbranch(branch)
274 revert_opts = opts.copy()
274 revert_opts = opts.copy()
275 revert_opts['date'] = None
275 revert_opts['date'] = None
276 revert_opts['all'] = True
276 revert_opts['all'] = True
277 revert_opts['rev'] = hex(parent)
277 revert_opts['rev'] = hex(parent)
278 revert_opts['no_backup'] = None
278 revert_opts['no_backup'] = None
279 revert(ui, repo, **revert_opts)
279 revert(ui, repo, **revert_opts)
280 if not opts.get('merge') and op1 != node:
280 if not opts.get('merge') and op1 != node:
281 try:
281 try:
282 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
282 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
283 return hg.update(repo, op1)
283 return hg.update(repo, op1)
284 finally:
284 finally:
285 ui.setconfig('ui', 'forcemerge', '')
285 ui.setconfig('ui', 'forcemerge', '')
286
286
287 commit_opts = opts.copy()
287 commit_opts = opts.copy()
288 commit_opts['addremove'] = False
288 commit_opts['addremove'] = False
289 if not commit_opts['message'] and not commit_opts['logfile']:
289 if not commit_opts['message'] and not commit_opts['logfile']:
290 # we don't translate commit messages
290 # we don't translate commit messages
291 commit_opts['message'] = "Backed out changeset %s" % short(node)
291 commit_opts['message'] = "Backed out changeset %s" % short(node)
292 commit_opts['force_editor'] = True
292 commit_opts['force_editor'] = True
293 commit(ui, repo, **commit_opts)
293 commit(ui, repo, **commit_opts)
294 def nice(node):
294 def nice(node):
295 return '%d:%s' % (repo.changelog.rev(node), short(node))
295 return '%d:%s' % (repo.changelog.rev(node), short(node))
296 ui.status(_('changeset %s backs out changeset %s\n') %
296 ui.status(_('changeset %s backs out changeset %s\n') %
297 (nice(repo.changelog.tip()), nice(node)))
297 (nice(repo.changelog.tip()), nice(node)))
298 if opts.get('merge') and op1 != node:
298 if opts.get('merge') and op1 != node:
299 hg.clean(repo, op1, show_stats=False)
299 hg.clean(repo, op1, show_stats=False)
300 ui.status(_('merging with changeset %s\n')
300 ui.status(_('merging with changeset %s\n')
301 % nice(repo.changelog.tip()))
301 % nice(repo.changelog.tip()))
302 try:
302 try:
303 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
303 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
304 return hg.merge(repo, hex(repo.changelog.tip()))
304 return hg.merge(repo, hex(repo.changelog.tip()))
305 finally:
305 finally:
306 ui.setconfig('ui', 'forcemerge', '')
306 ui.setconfig('ui', 'forcemerge', '')
307 return 0
307 return 0
308
308
309 def bisect(ui, repo, rev=None, extra=None, command=None,
309 def bisect(ui, repo, rev=None, extra=None, command=None,
310 reset=None, good=None, bad=None, skip=None, extend=None,
310 reset=None, good=None, bad=None, skip=None, extend=None,
311 noupdate=None):
311 noupdate=None):
312 """subdivision search of changesets
312 """subdivision search of changesets
313
313
314 This command helps to find changesets which introduce problems. To
314 This command helps to find changesets which introduce problems. To
315 use, mark the earliest changeset you know exhibits the problem as
315 use, mark the earliest changeset you know exhibits the problem as
316 bad, then mark the latest changeset which is free from the problem
316 bad, then mark the latest changeset which is free from the problem
317 as good. Bisect will update your working directory to a revision
317 as good. Bisect will update your working directory to a revision
318 for testing (unless the -U/--noupdate option is specified). Once
318 for testing (unless the -U/--noupdate option is specified). Once
319 you have performed tests, mark the working directory as good or
319 you have performed tests, mark the working directory as good or
320 bad, and bisect will either update to another candidate changeset
320 bad, and bisect will either update to another candidate changeset
321 or announce that it has found the bad revision.
321 or announce that it has found the bad revision.
322
322
323 As a shortcut, you can also use the revision argument to mark a
323 As a shortcut, you can also use the revision argument to mark a
324 revision as good or bad without checking it out first.
324 revision as good or bad without checking it out first.
325
325
326 If you supply a command, it will be used for automatic bisection.
326 If you supply a command, it will be used for automatic bisection.
327 Its exit status will be used to mark revisions as good or bad:
327 Its exit status will be used to mark revisions as good or bad:
328 status 0 means good, 125 means to skip the revision, 127
328 status 0 means good, 125 means to skip the revision, 127
329 (command not found) will abort the bisection, and any other
329 (command not found) will abort the bisection, and any other
330 non-zero exit status means the revision is bad.
330 non-zero exit status means the revision is bad.
331
331
332 Returns 0 on success.
332 Returns 0 on success.
333 """
333 """
334 def extendbisectrange(nodes, good):
334 def extendbisectrange(nodes, good):
335 # bisect is incomplete when it ends on a merge node and
335 # bisect is incomplete when it ends on a merge node and
336 # one of the parent was not checked.
336 # one of the parent was not checked.
337 parents = repo[nodes[0]].parents()
337 parents = repo[nodes[0]].parents()
338 if len(parents) > 1:
338 if len(parents) > 1:
339 side = good and state['bad'] or state['good']
339 side = good and state['bad'] or state['good']
340 num = len(set(i.node() for i in parents) & set(side))
340 num = len(set(i.node() for i in parents) & set(side))
341 if num == 1:
341 if num == 1:
342 return parents[0].ancestor(parents[1])
342 return parents[0].ancestor(parents[1])
343 return None
343 return None
344
344
345 def print_result(nodes, good):
345 def print_result(nodes, good):
346 displayer = cmdutil.show_changeset(ui, repo, {})
346 displayer = cmdutil.show_changeset(ui, repo, {})
347 if len(nodes) == 1:
347 if len(nodes) == 1:
348 # narrowed it down to a single revision
348 # narrowed it down to a single revision
349 if good:
349 if good:
350 ui.write(_("The first good revision is:\n"))
350 ui.write(_("The first good revision is:\n"))
351 else:
351 else:
352 ui.write(_("The first bad revision is:\n"))
352 ui.write(_("The first bad revision is:\n"))
353 displayer.show(repo[nodes[0]])
353 displayer.show(repo[nodes[0]])
354 parents = repo[nodes[0]].parents()
354 parents = repo[nodes[0]].parents()
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 % short(extendnode.node()))
360 % short(extendnode.node()))
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(), short(extendnode.node()))))
462 % (extendnode.rev(), short(extendnode.node()))))
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, rename=None):
486 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, rename=None):
487 '''track a line of development with movable markers
487 '''track a line of development with movable markers
488
488
489 Bookmarks are pointers to certain commits that move when
489 Bookmarks are pointers to certain commits that move when
490 committing. Bookmarks are local. They can be renamed, copied and
490 committing. Bookmarks are local. They can be renamed, copied and
491 deleted. It is possible to use bookmark names in :hg:`merge` and
491 deleted. It is possible to use bookmark names in :hg:`merge` and
492 :hg:`update` to merge and update respectively to a given bookmark.
492 :hg:`update` to merge and update respectively to a given bookmark.
493
493
494 You can use :hg:`bookmark NAME` to set a bookmark on the working
494 You can use :hg:`bookmark NAME` to set a bookmark on the working
495 directory's parent revision with the given name. If you specify
495 directory's parent revision with the given name. If you specify
496 a revision using -r REV (where REV may be an existing bookmark),
496 a revision using -r REV (where REV may be an existing bookmark),
497 the bookmark is assigned to that revision.
497 the bookmark is assigned to that revision.
498
498
499 Bookmarks can be pushed and pulled between repositories (see :hg:`help
499 Bookmarks can be pushed and pulled between repositories (see :hg:`help
500 push` and :hg:`help pull`). This requires both the local and remote
500 push` and :hg:`help pull`). This requires both the local and remote
501 repositories to support bookmarks. For versions prior to 1.8, this means
501 repositories to support bookmarks. For versions prior to 1.8, this means
502 the bookmarks extension must be enabled.
502 the bookmarks extension must be enabled.
503 '''
503 '''
504 hexfn = ui.debugflag and hex or short
504 hexfn = ui.debugflag and hex or short
505 marks = repo._bookmarks
505 marks = repo._bookmarks
506 cur = repo.changectx('.').node()
506 cur = repo.changectx('.').node()
507
507
508 if rename:
508 if rename:
509 if rename not in marks:
509 if rename not in marks:
510 raise util.Abort(_("bookmark '%s' does not exist") % rename)
510 raise util.Abort(_("bookmark '%s' does not exist") % rename)
511 if mark in marks and not force:
511 if mark in marks and not force:
512 raise util.Abort(_("bookmark '%s' already exists "
512 raise util.Abort(_("bookmark '%s' already exists "
513 "(use -f to force)") % mark)
513 "(use -f to force)") % mark)
514 if mark is None:
514 if mark is None:
515 raise util.Abort(_("new bookmark name required"))
515 raise util.Abort(_("new bookmark name required"))
516 marks[mark] = marks[rename]
516 marks[mark] = marks[rename]
517 if repo._bookmarkcurrent == rename:
517 if repo._bookmarkcurrent == rename:
518 bookmarks.setcurrent(repo, mark)
518 bookmarks.setcurrent(repo, mark)
519 del marks[rename]
519 del marks[rename]
520 bookmarks.write(repo)
520 bookmarks.write(repo)
521 return
521 return
522
522
523 if delete:
523 if delete:
524 if mark is None:
524 if mark is None:
525 raise util.Abort(_("bookmark name required"))
525 raise util.Abort(_("bookmark name required"))
526 if mark not in marks:
526 if mark not in marks:
527 raise util.Abort(_("bookmark '%s' does not exist") % mark)
527 raise util.Abort(_("bookmark '%s' does not exist") % mark)
528 if mark == repo._bookmarkcurrent:
528 if mark == repo._bookmarkcurrent:
529 bookmarks.setcurrent(repo, None)
529 bookmarks.setcurrent(repo, None)
530 del marks[mark]
530 del marks[mark]
531 bookmarks.write(repo)
531 bookmarks.write(repo)
532 return
532 return
533
533
534 if mark is not None:
534 if mark is not None:
535 if "\n" in mark:
535 if "\n" in mark:
536 raise util.Abort(_("bookmark name cannot contain newlines"))
536 raise util.Abort(_("bookmark name cannot contain newlines"))
537 mark = mark.strip()
537 mark = mark.strip()
538 if not mark:
538 if not mark:
539 raise util.Abort(_("bookmark names cannot consist entirely of "
539 raise util.Abort(_("bookmark names cannot consist entirely of "
540 "whitespace"))
540 "whitespace"))
541 if mark in marks and not force:
541 if mark in marks and not force:
542 raise util.Abort(_("bookmark '%s' already exists "
542 raise util.Abort(_("bookmark '%s' already exists "
543 "(use -f to force)") % mark)
543 "(use -f to force)") % mark)
544 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
544 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
545 and not force):
545 and not force):
546 raise util.Abort(
546 raise util.Abort(
547 _("a bookmark cannot have the name of an existing branch"))
547 _("a bookmark cannot have the name of an existing branch"))
548 if rev:
548 if rev:
549 marks[mark] = repo.lookup(rev)
549 marks[mark] = repo.lookup(rev)
550 else:
550 else:
551 marks[mark] = repo.changectx('.').node()
551 marks[mark] = repo.changectx('.').node()
552 if repo.changectx('.').node() == marks[mark]:
552 if repo.changectx('.').node() == marks[mark]:
553 bookmarks.setcurrent(repo, mark)
553 bookmarks.setcurrent(repo, mark)
554 bookmarks.write(repo)
554 bookmarks.write(repo)
555 return
555 return
556
556
557 if mark is None:
557 if mark is None:
558 if rev:
558 if rev:
559 raise util.Abort(_("bookmark name required"))
559 raise util.Abort(_("bookmark name required"))
560 if len(marks) == 0:
560 if len(marks) == 0:
561 ui.status(_("no bookmarks set\n"))
561 ui.status(_("no bookmarks set\n"))
562 else:
562 else:
563 for bmark, n in sorted(marks.iteritems()):
563 for bmark, n in sorted(marks.iteritems()):
564 current = repo._bookmarkcurrent
564 current = repo._bookmarkcurrent
565 if bmark == current and n == cur:
565 if bmark == current and n == cur:
566 prefix, label = '*', 'bookmarks.current'
566 prefix, label = '*', 'bookmarks.current'
567 else:
567 else:
568 prefix, label = ' ', ''
568 prefix, label = ' ', ''
569
569
570 if ui.quiet:
570 if ui.quiet:
571 ui.write("%s\n" % bmark, label=label)
571 ui.write("%s\n" % bmark, label=label)
572 else:
572 else:
573 ui.write(" %s %-25s %d:%s\n" % (
573 ui.write(" %s %-25s %d:%s\n" % (
574 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
574 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
575 label=label)
575 label=label)
576 return
576 return
577
577
578 def branch(ui, repo, label=None, **opts):
578 def branch(ui, repo, label=None, **opts):
579 """set or show the current branch name
579 """set or show the current branch name
580
580
581 With no argument, show the current branch name. With one argument,
581 With no argument, show the current branch name. With one argument,
582 set the working directory branch name (the branch will not exist
582 set the working directory branch name (the branch will not exist
583 in the repository until the next commit). Standard practice
583 in the repository until the next commit). Standard practice
584 recommends that primary development take place on the 'default'
584 recommends that primary development take place on the 'default'
585 branch.
585 branch.
586
586
587 Unless -f/--force is specified, branch will not let you set a
587 Unless -f/--force is specified, branch will not let you set a
588 branch name that already exists, even if it's inactive.
588 branch name that already exists, even if it's inactive.
589
589
590 Use -C/--clean to reset the working directory branch to that of
590 Use -C/--clean to reset the working directory branch to that of
591 the parent of the working directory, negating a previous branch
591 the parent of the working directory, negating a previous branch
592 change.
592 change.
593
593
594 Use the command :hg:`update` to switch to an existing branch. Use
594 Use the command :hg:`update` to switch to an existing branch. Use
595 :hg:`commit --close-branch` to mark this branch as closed.
595 :hg:`commit --close-branch` to mark this branch as closed.
596
596
597 Returns 0 on success.
597 Returns 0 on success.
598 """
598 """
599
599
600 if opts.get('clean'):
600 if opts.get('clean'):
601 label = repo[None].p1().branch()
601 label = repo[None].p1().branch()
602 repo.dirstate.setbranch(label)
602 repo.dirstate.setbranch(label)
603 ui.status(_('reset working directory to branch %s\n') % label)
603 ui.status(_('reset working directory to branch %s\n') % label)
604 elif label:
604 elif label:
605 if not opts.get('force') and label in repo.branchtags():
605 if not opts.get('force') and label in repo.branchtags():
606 if label not in [p.branch() for p in repo.parents()]:
606 if label not in [p.branch() for p in repo.parents()]:
607 raise util.Abort(_('a branch of the same name already exists'
607 raise util.Abort(_('a branch of the same name already exists'
608 " (use 'hg update' to switch to it)"))
608 " (use 'hg update' to switch to it)"))
609 repo.dirstate.setbranch(label)
609 repo.dirstate.setbranch(label)
610 ui.status(_('marked working directory as branch %s\n') % label)
610 ui.status(_('marked working directory as branch %s\n') % label)
611 else:
611 else:
612 ui.write("%s\n" % repo.dirstate.branch())
612 ui.write("%s\n" % repo.dirstate.branch())
613
613
614 def branches(ui, repo, active=False, closed=False):
614 def branches(ui, repo, active=False, closed=False):
615 """list repository named branches
615 """list repository named branches
616
616
617 List the repository's named branches, indicating which ones are
617 List the repository's named branches, indicating which ones are
618 inactive. If -c/--closed is specified, also list branches which have
618 inactive. If -c/--closed is specified, also list branches which have
619 been marked closed (see :hg:`commit --close-branch`).
619 been marked closed (see :hg:`commit --close-branch`).
620
620
621 If -a/--active is specified, only show active branches. A branch
621 If -a/--active is specified, only show active branches. A branch
622 is considered active if it contains repository heads.
622 is considered active if it contains repository heads.
623
623
624 Use the command :hg:`update` to switch to an existing branch.
624 Use the command :hg:`update` to switch to an existing branch.
625
625
626 Returns 0.
626 Returns 0.
627 """
627 """
628
628
629 hexfunc = ui.debugflag and hex or short
629 hexfunc = ui.debugflag and hex or short
630 activebranches = [repo[n].branch() for n in repo.heads()]
630 activebranches = [repo[n].branch() for n in repo.heads()]
631 def testactive(tag, node):
631 def testactive(tag, node):
632 realhead = tag in activebranches
632 realhead = tag in activebranches
633 open = node in repo.branchheads(tag, closed=False)
633 open = node in repo.branchheads(tag, closed=False)
634 return realhead and open
634 return realhead and open
635 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
635 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
636 for tag, node in repo.branchtags().items()],
636 for tag, node in repo.branchtags().items()],
637 reverse=True)
637 reverse=True)
638
638
639 for isactive, node, tag in branches:
639 for isactive, node, tag in branches:
640 if (not active) or isactive:
640 if (not active) or isactive:
641 if ui.quiet:
641 if ui.quiet:
642 ui.write("%s\n" % tag)
642 ui.write("%s\n" % tag)
643 else:
643 else:
644 hn = repo.lookup(node)
644 hn = repo.lookup(node)
645 if isactive:
645 if isactive:
646 label = 'branches.active'
646 label = 'branches.active'
647 notice = ''
647 notice = ''
648 elif hn not in repo.branchheads(tag, closed=False):
648 elif hn not in repo.branchheads(tag, closed=False):
649 if not closed:
649 if not closed:
650 continue
650 continue
651 label = 'branches.closed'
651 label = 'branches.closed'
652 notice = _(' (closed)')
652 notice = _(' (closed)')
653 else:
653 else:
654 label = 'branches.inactive'
654 label = 'branches.inactive'
655 notice = _(' (inactive)')
655 notice = _(' (inactive)')
656 if tag == repo.dirstate.branch():
656 if tag == repo.dirstate.branch():
657 label = 'branches.current'
657 label = 'branches.current'
658 rev = str(node).rjust(31 - encoding.colwidth(tag))
658 rev = str(node).rjust(31 - encoding.colwidth(tag))
659 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
659 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
660 tag = ui.label(tag, label)
660 tag = ui.label(tag, label)
661 ui.write("%s %s%s\n" % (tag, rev, notice))
661 ui.write("%s %s%s\n" % (tag, rev, notice))
662
662
663 def bundle(ui, repo, fname, dest=None, **opts):
663 def bundle(ui, repo, fname, dest=None, **opts):
664 """create a changegroup file
664 """create a changegroup file
665
665
666 Generate a compressed changegroup file collecting changesets not
666 Generate a compressed changegroup file collecting changesets not
667 known to be in another repository.
667 known to be in another repository.
668
668
669 If you omit the destination repository, then hg assumes the
669 If you omit the destination repository, then hg assumes the
670 destination will have all the nodes you specify with --base
670 destination will have all the nodes you specify with --base
671 parameters. To create a bundle containing all changesets, use
671 parameters. To create a bundle containing all changesets, use
672 -a/--all (or --base null).
672 -a/--all (or --base null).
673
673
674 You can change compression method with the -t/--type option.
674 You can change compression method with the -t/--type option.
675 The available compression methods are: none, bzip2, and
675 The available compression methods are: none, bzip2, and
676 gzip (by default, bundles are compressed using bzip2).
676 gzip (by default, bundles are compressed using bzip2).
677
677
678 The bundle file can then be transferred using conventional means
678 The bundle file can then be transferred using conventional means
679 and applied to another repository with the unbundle or pull
679 and applied to another repository with the unbundle or pull
680 command. This is useful when direct push and pull are not
680 command. This is useful when direct push and pull are not
681 available or when exporting an entire repository is undesirable.
681 available or when exporting an entire repository is undesirable.
682
682
683 Applying bundles preserves all changeset contents including
683 Applying bundles preserves all changeset contents including
684 permissions, copy/rename information, and revision history.
684 permissions, copy/rename information, and revision history.
685
685
686 Returns 0 on success, 1 if no changes found.
686 Returns 0 on success, 1 if no changes found.
687 """
687 """
688 revs = None
688 revs = None
689 if 'rev' in opts:
689 if 'rev' in opts:
690 revs = cmdutil.revrange(repo, opts['rev'])
690 revs = cmdutil.revrange(repo, opts['rev'])
691
691
692 if opts.get('all'):
692 if opts.get('all'):
693 base = ['null']
693 base = ['null']
694 else:
694 else:
695 base = cmdutil.revrange(repo, opts.get('base'))
695 base = cmdutil.revrange(repo, opts.get('base'))
696 if base:
696 if base:
697 if dest:
697 if dest:
698 raise util.Abort(_("--base is incompatible with specifying "
698 raise util.Abort(_("--base is incompatible with specifying "
699 "a destination"))
699 "a destination"))
700 base = [repo.lookup(rev) for rev in base]
700 base = [repo.lookup(rev) for rev in base]
701 # create the right base
701 # create the right base
702 # XXX: nodesbetween / changegroup* should be "fixed" instead
702 # XXX: nodesbetween / changegroup* should be "fixed" instead
703 o = []
703 o = []
704 has = set((nullid,))
704 has = set((nullid,))
705 for n in base:
705 for n in base:
706 has.update(repo.changelog.reachable(n))
706 has.update(repo.changelog.reachable(n))
707 if revs:
707 if revs:
708 revs = [repo.lookup(rev) for rev in revs]
708 revs = [repo.lookup(rev) for rev in revs]
709 visit = revs[:]
709 visit = revs[:]
710 has.difference_update(visit)
710 has.difference_update(visit)
711 else:
711 else:
712 visit = repo.changelog.heads()
712 visit = repo.changelog.heads()
713 seen = {}
713 seen = {}
714 while visit:
714 while visit:
715 n = visit.pop(0)
715 n = visit.pop(0)
716 parents = [p for p in repo.changelog.parents(n) if p not in has]
716 parents = [p for p in repo.changelog.parents(n) if p not in has]
717 if len(parents) == 0:
717 if len(parents) == 0:
718 if n not in has:
718 if n not in has:
719 o.append(n)
719 o.append(n)
720 else:
720 else:
721 for p in parents:
721 for p in parents:
722 if p not in seen:
722 if p not in seen:
723 seen[p] = 1
723 seen[p] = 1
724 visit.append(p)
724 visit.append(p)
725 else:
725 else:
726 dest = ui.expandpath(dest or 'default-push', dest or 'default')
726 dest = ui.expandpath(dest or 'default-push', dest or 'default')
727 dest, branches = hg.parseurl(dest, opts.get('branch'))
727 dest, branches = hg.parseurl(dest, opts.get('branch'))
728 other = hg.repository(hg.remoteui(repo, opts), dest)
728 other = hg.repository(hg.remoteui(repo, opts), dest)
729 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
729 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
730 if revs:
730 if revs:
731 revs = [repo.lookup(rev) for rev in revs]
731 revs = [repo.lookup(rev) for rev in revs]
732 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
732 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
733
733
734 if not o:
734 if not o:
735 ui.status(_("no changes found\n"))
735 ui.status(_("no changes found\n"))
736 return 1
736 return 1
737
737
738 if revs:
738 if revs:
739 cg = repo.changegroupsubset(o, revs, 'bundle')
739 cg = repo.changegroupsubset(o, revs, 'bundle')
740 else:
740 else:
741 cg = repo.changegroup(o, 'bundle')
741 cg = repo.changegroup(o, 'bundle')
742
742
743 bundletype = opts.get('type', 'bzip2').lower()
743 bundletype = opts.get('type', 'bzip2').lower()
744 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
744 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
745 bundletype = btypes.get(bundletype)
745 bundletype = btypes.get(bundletype)
746 if bundletype not in changegroup.bundletypes:
746 if bundletype not in changegroup.bundletypes:
747 raise util.Abort(_('unknown bundle type specified with --type'))
747 raise util.Abort(_('unknown bundle type specified with --type'))
748
748
749 changegroup.writebundle(cg, fname, bundletype)
749 changegroup.writebundle(cg, fname, bundletype)
750
750
751 def cat(ui, repo, file1, *pats, **opts):
751 def cat(ui, repo, file1, *pats, **opts):
752 """output the current or given revision of files
752 """output the current or given revision of files
753
753
754 Print the specified files as they were at the given revision. If
754 Print the specified files as they were at the given revision. If
755 no revision is given, the parent of the working directory is used,
755 no revision is given, the parent of the working directory is used,
756 or tip if no revision is checked out.
756 or tip if no revision is checked out.
757
757
758 Output may be to a file, in which case the name of the file is
758 Output may be to a file, in which case the name of the file is
759 given using a format string. The formatting rules are the same as
759 given using a format string. The formatting rules are the same as
760 for the export command, with the following additions:
760 for the export command, with the following additions:
761
761
762 :``%s``: basename of file being printed
762 :``%s``: basename of file being printed
763 :``%d``: dirname of file being printed, or '.' if in repository root
763 :``%d``: dirname of file being printed, or '.' if in repository root
764 :``%p``: root-relative path name of file being printed
764 :``%p``: root-relative path name of file being printed
765
765
766 Returns 0 on success.
766 Returns 0 on success.
767 """
767 """
768 ctx = cmdutil.revsingle(repo, opts.get('rev'))
768 ctx = cmdutil.revsingle(repo, opts.get('rev'))
769 err = 1
769 err = 1
770 m = cmdutil.match(repo, (file1,) + pats, opts)
770 m = cmdutil.match(repo, (file1,) + pats, opts)
771 for abs in ctx.walk(m):
771 for abs in ctx.walk(m):
772 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
772 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
773 data = ctx[abs].data()
773 data = ctx[abs].data()
774 if opts.get('decode'):
774 if opts.get('decode'):
775 data = repo.wwritedata(abs, data)
775 data = repo.wwritedata(abs, data)
776 fp.write(data)
776 fp.write(data)
777 fp.close()
777 fp.close()
778 err = 0
778 err = 0
779 return err
779 return err
780
780
781 def clone(ui, source, dest=None, **opts):
781 def clone(ui, source, dest=None, **opts):
782 """make a copy of an existing repository
782 """make a copy of an existing repository
783
783
784 Create a copy of an existing repository in a new directory.
784 Create a copy of an existing repository in a new directory.
785
785
786 If no destination directory name is specified, it defaults to the
786 If no destination directory name is specified, it defaults to the
787 basename of the source.
787 basename of the source.
788
788
789 The location of the source is added to the new repository's
789 The location of the source is added to the new repository's
790 ``.hg/hgrc`` file, as the default to be used for future pulls.
790 ``.hg/hgrc`` file, as the default to be used for future pulls.
791
791
792 See :hg:`help urls` for valid source format details.
792 See :hg:`help urls` for valid source format details.
793
793
794 It is possible to specify an ``ssh://`` URL as the destination, but no
794 It is possible to specify an ``ssh://`` URL as the destination, but no
795 ``.hg/hgrc`` and working directory will be created on the remote side.
795 ``.hg/hgrc`` and working directory will be created on the remote side.
796 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
796 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
797
797
798 A set of changesets (tags, or branch names) to pull may be specified
798 A set of changesets (tags, or branch names) to pull may be specified
799 by listing each changeset (tag, or branch name) with -r/--rev.
799 by listing each changeset (tag, or branch name) with -r/--rev.
800 If -r/--rev is used, the cloned repository will contain only a subset
800 If -r/--rev is used, the cloned repository will contain only a subset
801 of the changesets of the source repository. Only the set of changesets
801 of the changesets of the source repository. Only the set of changesets
802 defined by all -r/--rev options (including all their ancestors)
802 defined by all -r/--rev options (including all their ancestors)
803 will be pulled into the destination repository.
803 will be pulled into the destination repository.
804 No subsequent changesets (including subsequent tags) will be present
804 No subsequent changesets (including subsequent tags) will be present
805 in the destination.
805 in the destination.
806
806
807 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
807 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
808 local source repositories.
808 local source repositories.
809
809
810 For efficiency, hardlinks are used for cloning whenever the source
810 For efficiency, hardlinks are used for cloning whenever the source
811 and destination are on the same filesystem (note this applies only
811 and destination are on the same filesystem (note this applies only
812 to the repository data, not to the working directory). Some
812 to the repository data, not to the working directory). Some
813 filesystems, such as AFS, implement hardlinking incorrectly, but
813 filesystems, such as AFS, implement hardlinking incorrectly, but
814 do not report errors. In these cases, use the --pull option to
814 do not report errors. In these cases, use the --pull option to
815 avoid hardlinking.
815 avoid hardlinking.
816
816
817 In some cases, you can clone repositories and the working directory
817 In some cases, you can clone repositories and the working directory
818 using full hardlinks with ::
818 using full hardlinks with ::
819
819
820 $ cp -al REPO REPOCLONE
820 $ cp -al REPO REPOCLONE
821
821
822 This is the fastest way to clone, but it is not always safe. The
822 This is the fastest way to clone, but it is not always safe. The
823 operation is not atomic (making sure REPO is not modified during
823 operation is not atomic (making sure REPO is not modified during
824 the operation is up to you) and you have to make sure your editor
824 the operation is up to you) and you have to make sure your editor
825 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
825 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
826 this is not compatible with certain extensions that place their
826 this is not compatible with certain extensions that place their
827 metadata under the .hg directory, such as mq.
827 metadata under the .hg directory, such as mq.
828
828
829 Mercurial will update the working directory to the first applicable
829 Mercurial will update the working directory to the first applicable
830 revision from this list:
830 revision from this list:
831
831
832 a) null if -U or the source repository has no changesets
832 a) null if -U or the source repository has no changesets
833 b) if -u . and the source repository is local, the first parent of
833 b) if -u . and the source repository is local, the first parent of
834 the source repository's working directory
834 the source repository's working directory
835 c) the changeset specified with -u (if a branch name, this means the
835 c) the changeset specified with -u (if a branch name, this means the
836 latest head of that branch)
836 latest head of that branch)
837 d) the changeset specified with -r
837 d) the changeset specified with -r
838 e) the tipmost head specified with -b
838 e) the tipmost head specified with -b
839 f) the tipmost head specified with the url#branch source syntax
839 f) the tipmost head specified with the url#branch source syntax
840 g) the tipmost head of the default branch
840 g) the tipmost head of the default branch
841 h) tip
841 h) tip
842
842
843 Returns 0 on success.
843 Returns 0 on success.
844 """
844 """
845 if opts.get('noupdate') and opts.get('updaterev'):
845 if opts.get('noupdate') and opts.get('updaterev'):
846 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
846 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
847
847
848 r = hg.clone(hg.remoteui(ui, opts), source, dest,
848 r = hg.clone(hg.remoteui(ui, opts), source, dest,
849 pull=opts.get('pull'),
849 pull=opts.get('pull'),
850 stream=opts.get('uncompressed'),
850 stream=opts.get('uncompressed'),
851 rev=opts.get('rev'),
851 rev=opts.get('rev'),
852 update=opts.get('updaterev') or not opts.get('noupdate'),
852 update=opts.get('updaterev') or not opts.get('noupdate'),
853 branch=opts.get('branch'))
853 branch=opts.get('branch'))
854
854
855 return r is None
855 return r is None
856
856
857 def commit(ui, repo, *pats, **opts):
857 def commit(ui, repo, *pats, **opts):
858 """commit the specified files or all outstanding changes
858 """commit the specified files or all outstanding changes
859
859
860 Commit changes to the given files into the repository. Unlike a
860 Commit changes to the given files into the repository. Unlike a
861 centralized SCM, this operation is a local operation. See
861 centralized SCM, this operation is a local operation. See
862 :hg:`push` for a way to actively distribute your changes.
862 :hg:`push` for a way to actively distribute your changes.
863
863
864 If a list of files is omitted, all changes reported by :hg:`status`
864 If a list of files is omitted, all changes reported by :hg:`status`
865 will be committed.
865 will be committed.
866
866
867 If you are committing the result of a merge, do not provide any
867 If you are committing the result of a merge, do not provide any
868 filenames or -I/-X filters.
868 filenames or -I/-X filters.
869
869
870 If no commit message is specified, Mercurial starts your
870 If no commit message is specified, Mercurial starts your
871 configured editor where you can enter a message. In case your
871 configured editor where you can enter a message. In case your
872 commit fails, you will find a backup of your message in
872 commit fails, you will find a backup of your message in
873 ``.hg/last-message.txt``.
873 ``.hg/last-message.txt``.
874
874
875 See :hg:`help dates` for a list of formats valid for -d/--date.
875 See :hg:`help dates` for a list of formats valid for -d/--date.
876
876
877 Returns 0 on success, 1 if nothing changed.
877 Returns 0 on success, 1 if nothing changed.
878 """
878 """
879 extra = {}
879 extra = {}
880 if opts.get('close_branch'):
880 if opts.get('close_branch'):
881 if repo['.'].node() not in repo.branchheads():
881 if repo['.'].node() not in repo.branchheads():
882 # The topo heads set is included in the branch heads set of the
882 # The topo heads set is included in the branch heads set of the
883 # current branch, so it's sufficient to test branchheads
883 # current branch, so it's sufficient to test branchheads
884 raise util.Abort(_('can only close branch heads'))
884 raise util.Abort(_('can only close branch heads'))
885 extra['close'] = 1
885 extra['close'] = 1
886 e = cmdutil.commiteditor
886 e = cmdutil.commiteditor
887 if opts.get('force_editor'):
887 if opts.get('force_editor'):
888 e = cmdutil.commitforceeditor
888 e = cmdutil.commitforceeditor
889
889
890 def commitfunc(ui, repo, message, match, opts):
890 def commitfunc(ui, repo, message, match, opts):
891 return repo.commit(message, opts.get('user'), opts.get('date'), match,
891 return repo.commit(message, opts.get('user'), opts.get('date'), match,
892 editor=e, extra=extra)
892 editor=e, extra=extra)
893
893
894 branch = repo[None].branch()
894 branch = repo[None].branch()
895 bheads = repo.branchheads(branch)
895 bheads = repo.branchheads(branch)
896
896
897 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
897 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
898 if not node:
898 if not node:
899 stat = repo.status(match=cmdutil.match(repo, pats, opts))
899 stat = repo.status(match=cmdutil.match(repo, pats, opts))
900 if stat[3]:
900 if stat[3]:
901 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
901 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
902 % len(stat[3]))
902 % len(stat[3]))
903 else:
903 else:
904 ui.status(_("nothing changed\n"))
904 ui.status(_("nothing changed\n"))
905 return 1
905 return 1
906
906
907 ctx = repo[node]
907 ctx = repo[node]
908 parents = ctx.parents()
908 parents = ctx.parents()
909
909
910 if bheads and not [x for x in parents
910 if bheads and not [x for x in parents
911 if x.node() in bheads and x.branch() == branch]:
911 if x.node() in bheads and x.branch() == branch]:
912 ui.status(_('created new head\n'))
912 ui.status(_('created new head\n'))
913 # The message is not printed for initial roots. For the other
913 # The message is not printed for initial roots. For the other
914 # changesets, it is printed in the following situations:
914 # changesets, it is printed in the following situations:
915 #
915 #
916 # Par column: for the 2 parents with ...
916 # Par column: for the 2 parents with ...
917 # N: null or no parent
917 # N: null or no parent
918 # B: parent is on another named branch
918 # B: parent is on another named branch
919 # C: parent is a regular non head changeset
919 # C: parent is a regular non head changeset
920 # H: parent was a branch head of the current branch
920 # H: parent was a branch head of the current branch
921 # Msg column: whether we print "created new head" message
921 # Msg column: whether we print "created new head" message
922 # In the following, it is assumed that there already exists some
922 # In the following, it is assumed that there already exists some
923 # initial branch heads of the current branch, otherwise nothing is
923 # initial branch heads of the current branch, otherwise nothing is
924 # printed anyway.
924 # printed anyway.
925 #
925 #
926 # Par Msg Comment
926 # Par Msg Comment
927 # NN y additional topo root
927 # NN y additional topo root
928 #
928 #
929 # BN y additional branch root
929 # BN y additional branch root
930 # CN y additional topo head
930 # CN y additional topo head
931 # HN n usual case
931 # HN n usual case
932 #
932 #
933 # BB y weird additional branch root
933 # BB y weird additional branch root
934 # CB y branch merge
934 # CB y branch merge
935 # HB n merge with named branch
935 # HB n merge with named branch
936 #
936 #
937 # CC y additional head from merge
937 # CC y additional head from merge
938 # CH n merge with a head
938 # CH n merge with a head
939 #
939 #
940 # HH n head merge: head count decreases
940 # HH n head merge: head count decreases
941
941
942 if not opts.get('close_branch'):
942 if not opts.get('close_branch'):
943 for r in parents:
943 for r in parents:
944 if r.extra().get('close') and r.branch() == branch:
944 if r.extra().get('close') and r.branch() == branch:
945 ui.status(_('reopening closed branch head %d\n') % r)
945 ui.status(_('reopening closed branch head %d\n') % r)
946
946
947 if ui.debugflag:
947 if ui.debugflag:
948 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
948 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
949 elif ui.verbose:
949 elif ui.verbose:
950 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
950 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
951
951
952 def copy(ui, repo, *pats, **opts):
952 def copy(ui, repo, *pats, **opts):
953 """mark files as copied for the next commit
953 """mark files as copied for the next commit
954
954
955 Mark dest as having copies of source files. If dest is a
955 Mark dest as having copies of source files. If dest is a
956 directory, copies are put in that directory. If dest is a file,
956 directory, copies are put in that directory. If dest is a file,
957 the source must be a single file.
957 the source must be a single file.
958
958
959 By default, this command copies the contents of files as they
959 By default, this command copies the contents of files as they
960 exist in the working directory. If invoked with -A/--after, the
960 exist in the working directory. If invoked with -A/--after, the
961 operation is recorded, but no copying is performed.
961 operation is recorded, but no copying is performed.
962
962
963 This command takes effect with the next commit. To undo a copy
963 This command takes effect with the next commit. To undo a copy
964 before that, see :hg:`revert`.
964 before that, see :hg:`revert`.
965
965
966 Returns 0 on success, 1 if errors are encountered.
966 Returns 0 on success, 1 if errors are encountered.
967 """
967 """
968 wlock = repo.wlock(False)
968 wlock = repo.wlock(False)
969 try:
969 try:
970 return cmdutil.copy(ui, repo, pats, opts)
970 return cmdutil.copy(ui, repo, pats, opts)
971 finally:
971 finally:
972 wlock.release()
972 wlock.release()
973
973
974 def debugancestor(ui, repo, *args):
974 def debugancestor(ui, repo, *args):
975 """find the ancestor revision of two revisions in a given index"""
975 """find the ancestor revision of two revisions in a given index"""
976 if len(args) == 3:
976 if len(args) == 3:
977 index, rev1, rev2 = args
977 index, rev1, rev2 = args
978 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
978 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
979 lookup = r.lookup
979 lookup = r.lookup
980 elif len(args) == 2:
980 elif len(args) == 2:
981 if not repo:
981 if not repo:
982 raise util.Abort(_("there is no Mercurial repository here "
982 raise util.Abort(_("there is no Mercurial repository here "
983 "(.hg not found)"))
983 "(.hg not found)"))
984 rev1, rev2 = args
984 rev1, rev2 = args
985 r = repo.changelog
985 r = repo.changelog
986 lookup = repo.lookup
986 lookup = repo.lookup
987 else:
987 else:
988 raise util.Abort(_('either two or three arguments required'))
988 raise util.Abort(_('either two or three arguments required'))
989 a = r.ancestor(lookup(rev1), lookup(rev2))
989 a = r.ancestor(lookup(rev1), lookup(rev2))
990 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
990 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
991
991
992 def debugbuilddag(ui, repo, text,
992 def debugbuilddag(ui, repo, text,
993 mergeable_file=False,
993 mergeable_file=False,
994 appended_file=False,
994 appended_file=False,
995 overwritten_file=False,
995 overwritten_file=False,
996 new_file=False):
996 new_file=False):
997 """builds a repo with a given dag from scratch in the current empty repo
997 """builds a repo with a given dag from scratch in the current empty repo
998
998
999 Elements:
999 Elements:
1000
1000
1001 - "+n" is a linear run of n nodes based on the current default parent
1001 - "+n" is a linear run of n nodes based on the current default parent
1002 - "." is a single node based on the current default parent
1002 - "." is a single node based on the current default parent
1003 - "$" resets the default parent to null (implied at the start);
1003 - "$" resets the default parent to null (implied at the start);
1004 otherwise the default parent is always the last node created
1004 otherwise the default parent is always the last node created
1005 - "<p" sets the default parent to the backref p
1005 - "<p" sets the default parent to the backref p
1006 - "*p" is a fork at parent p, which is a backref
1006 - "*p" is a fork at parent p, which is a backref
1007 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1007 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1008 - "/p2" is a merge of the preceding node and p2
1008 - "/p2" is a merge of the preceding node and p2
1009 - ":tag" defines a local tag for the preceding node
1009 - ":tag" defines a local tag for the preceding node
1010 - "@branch" sets the named branch for subsequent nodes
1010 - "@branch" sets the named branch for subsequent nodes
1011 - "!command" runs the command using your shell
1011 - "!command" runs the command using your shell
1012 - "!!my command\\n" is like "!", but to the end of the line
1012 - "!!my command\\n" is like "!", but to the end of the line
1013 - "#...\\n" is a comment up to the end of the line
1013 - "#...\\n" is a comment up to the end of the line
1014
1014
1015 Whitespace between the above elements is ignored.
1015 Whitespace between the above elements is ignored.
1016
1016
1017 A backref is either
1017 A backref is either
1018
1018
1019 - a number n, which references the node curr-n, where curr is the current
1019 - a number n, which references the node curr-n, where curr is the current
1020 node, or
1020 node, or
1021 - the name of a local tag you placed earlier using ":tag", or
1021 - the name of a local tag you placed earlier using ":tag", or
1022 - empty to denote the default parent.
1022 - empty to denote the default parent.
1023
1023
1024 All string valued-elements are either strictly alphanumeric, or must
1024 All string valued-elements are either strictly alphanumeric, or must
1025 be enclosed in double quotes ("..."), with "\\" as escape character.
1025 be enclosed in double quotes ("..."), with "\\" as escape character.
1026
1026
1027 Note that the --overwritten-file and --appended-file options imply the
1027 Note that the --overwritten-file and --appended-file options imply the
1028 use of "HGMERGE=internal:local" during DAG buildup.
1028 use of "HGMERGE=internal:local" during DAG buildup.
1029 """
1029 """
1030
1030
1031 if not (mergeable_file or appended_file or overwritten_file or new_file):
1031 if not (mergeable_file or appended_file or overwritten_file or new_file):
1032 raise util.Abort(_('need at least one of -m, -a, -o, -n'))
1032 raise util.Abort(_('need at least one of -m, -a, -o, -n'))
1033
1033
1034 if len(repo.changelog) > 0:
1034 if len(repo.changelog) > 0:
1035 raise util.Abort(_('repository is not empty'))
1035 raise util.Abort(_('repository is not empty'))
1036
1036
1037 if overwritten_file or appended_file:
1037 if overwritten_file or appended_file:
1038 # we don't want to fail in merges during buildup
1038 # we don't want to fail in merges during buildup
1039 os.environ['HGMERGE'] = 'internal:local'
1039 os.environ['HGMERGE'] = 'internal:local'
1040
1040
1041 def writefile(fname, text, fmode="wb"):
1041 def writefile(fname, text, fmode="wb"):
1042 f = open(fname, fmode)
1042 f = open(fname, fmode)
1043 try:
1043 try:
1044 f.write(text)
1044 f.write(text)
1045 finally:
1045 finally:
1046 f.close()
1046 f.close()
1047
1047
1048 if mergeable_file:
1048 if mergeable_file:
1049 linesperrev = 2
1049 linesperrev = 2
1050 # determine number of revs in DAG
1050 # determine number of revs in DAG
1051 n = 0
1051 n = 0
1052 for type, data in dagparser.parsedag(text):
1052 for type, data in dagparser.parsedag(text):
1053 if type == 'n':
1053 if type == 'n':
1054 n += 1
1054 n += 1
1055 # make a file with k lines per rev
1055 # make a file with k lines per rev
1056 writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
1056 writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
1057 + "\n")
1057 + "\n")
1058
1058
1059 at = -1
1059 at = -1
1060 atbranch = 'default'
1060 atbranch = 'default'
1061 for type, data in dagparser.parsedag(text):
1061 for type, data in dagparser.parsedag(text):
1062 if type == 'n':
1062 if type == 'n':
1063 ui.status('node %s\n' % str(data))
1063 ui.status('node %s\n' % str(data))
1064 id, ps = data
1064 id, ps = data
1065 p1 = ps[0]
1065 p1 = ps[0]
1066 if p1 != at:
1066 if p1 != at:
1067 update(ui, repo, node=str(p1), clean=True)
1067 update(ui, repo, node=str(p1), clean=True)
1068 at = p1
1068 at = p1
1069 if repo.dirstate.branch() != atbranch:
1069 if repo.dirstate.branch() != atbranch:
1070 branch(ui, repo, atbranch, force=True)
1070 branch(ui, repo, atbranch, force=True)
1071 if len(ps) > 1:
1071 if len(ps) > 1:
1072 p2 = ps[1]
1072 p2 = ps[1]
1073 merge(ui, repo, node=p2)
1073 merge(ui, repo, node=p2)
1074
1074
1075 if mergeable_file:
1075 if mergeable_file:
1076 f = open("mf", "rb+")
1076 f = open("mf", "rb+")
1077 try:
1077 try:
1078 lines = f.read().split("\n")
1078 lines = f.read().split("\n")
1079 lines[id * linesperrev] += " r%i" % id
1079 lines[id * linesperrev] += " r%i" % id
1080 f.seek(0)
1080 f.seek(0)
1081 f.write("\n".join(lines))
1081 f.write("\n".join(lines))
1082 finally:
1082 finally:
1083 f.close()
1083 f.close()
1084
1084
1085 if appended_file:
1085 if appended_file:
1086 writefile("af", "r%i\n" % id, "ab")
1086 writefile("af", "r%i\n" % id, "ab")
1087
1087
1088 if overwritten_file:
1088 if overwritten_file:
1089 writefile("of", "r%i\n" % id)
1089 writefile("of", "r%i\n" % id)
1090
1090
1091 if new_file:
1091 if new_file:
1092 writefile("nf%i" % id, "r%i\n" % id)
1092 writefile("nf%i" % id, "r%i\n" % id)
1093
1093
1094 commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
1094 commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
1095 at = id
1095 at = id
1096 elif type == 'l':
1096 elif type == 'l':
1097 id, name = data
1097 id, name = data
1098 ui.status('tag %s\n' % name)
1098 ui.status('tag %s\n' % name)
1099 tag(ui, repo, name, local=True)
1099 tag(ui, repo, name, local=True)
1100 elif type == 'a':
1100 elif type == 'a':
1101 ui.status('branch %s\n' % data)
1101 ui.status('branch %s\n' % data)
1102 atbranch = data
1102 atbranch = data
1103 elif type in 'cC':
1103 elif type in 'cC':
1104 r = util.system(data, cwd=repo.root)
1104 r = util.system(data, cwd=repo.root)
1105 if r:
1105 if r:
1106 desc, r = util.explain_exit(r)
1106 desc, r = util.explain_exit(r)
1107 raise util.Abort(_('%s command %s') % (data, desc))
1107 raise util.Abort(_('%s command %s') % (data, desc))
1108
1108
1109 def debugcommands(ui, cmd='', *args):
1109 def debugcommands(ui, cmd='', *args):
1110 """list all available commands and options"""
1110 """list all available commands and options"""
1111 for cmd, vals in sorted(table.iteritems()):
1111 for cmd, vals in sorted(table.iteritems()):
1112 cmd = cmd.split('|')[0].strip('^')
1112 cmd = cmd.split('|')[0].strip('^')
1113 opts = ', '.join([i[1] for i in vals[1]])
1113 opts = ', '.join([i[1] for i in vals[1]])
1114 ui.write('%s: %s\n' % (cmd, opts))
1114 ui.write('%s: %s\n' % (cmd, opts))
1115
1115
1116 def debugcomplete(ui, cmd='', **opts):
1116 def debugcomplete(ui, cmd='', **opts):
1117 """returns the completion list associated with the given command"""
1117 """returns the completion list associated with the given command"""
1118
1118
1119 if opts.get('options'):
1119 if opts.get('options'):
1120 options = []
1120 options = []
1121 otables = [globalopts]
1121 otables = [globalopts]
1122 if cmd:
1122 if cmd:
1123 aliases, entry = cmdutil.findcmd(cmd, table, False)
1123 aliases, entry = cmdutil.findcmd(cmd, table, False)
1124 otables.append(entry[1])
1124 otables.append(entry[1])
1125 for t in otables:
1125 for t in otables:
1126 for o in t:
1126 for o in t:
1127 if "(DEPRECATED)" in o[3]:
1127 if "(DEPRECATED)" in o[3]:
1128 continue
1128 continue
1129 if o[0]:
1129 if o[0]:
1130 options.append('-%s' % o[0])
1130 options.append('-%s' % o[0])
1131 options.append('--%s' % o[1])
1131 options.append('--%s' % o[1])
1132 ui.write("%s\n" % "\n".join(options))
1132 ui.write("%s\n" % "\n".join(options))
1133 return
1133 return
1134
1134
1135 cmdlist = cmdutil.findpossible(cmd, table)
1135 cmdlist = cmdutil.findpossible(cmd, table)
1136 if ui.verbose:
1136 if ui.verbose:
1137 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1137 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1138 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1138 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1139
1139
1140 def debugfsinfo(ui, path = "."):
1140 def debugfsinfo(ui, path = "."):
1141 """show information detected about current filesystem"""
1141 """show information detected about current filesystem"""
1142 open('.debugfsinfo', 'w').write('')
1142 open('.debugfsinfo', 'w').write('')
1143 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1143 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1144 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1144 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1145 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1145 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1146 and 'yes' or 'no'))
1146 and 'yes' or 'no'))
1147 os.unlink('.debugfsinfo')
1147 os.unlink('.debugfsinfo')
1148
1148
1149 def debugrebuildstate(ui, repo, rev="tip"):
1149 def debugrebuildstate(ui, repo, rev="tip"):
1150 """rebuild the dirstate as it would look like for the given revision"""
1150 """rebuild the dirstate as it would look like for the given revision"""
1151 ctx = cmdutil.revsingle(repo, rev)
1151 ctx = cmdutil.revsingle(repo, rev)
1152 wlock = repo.wlock()
1152 wlock = repo.wlock()
1153 try:
1153 try:
1154 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1154 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1155 finally:
1155 finally:
1156 wlock.release()
1156 wlock.release()
1157
1157
1158 def debugcheckstate(ui, repo):
1158 def debugcheckstate(ui, repo):
1159 """validate the correctness of the current dirstate"""
1159 """validate the correctness of the current dirstate"""
1160 parent1, parent2 = repo.dirstate.parents()
1160 parent1, parent2 = repo.dirstate.parents()
1161 m1 = repo[parent1].manifest()
1161 m1 = repo[parent1].manifest()
1162 m2 = repo[parent2].manifest()
1162 m2 = repo[parent2].manifest()
1163 errors = 0
1163 errors = 0
1164 for f in repo.dirstate:
1164 for f in repo.dirstate:
1165 state = repo.dirstate[f]
1165 state = repo.dirstate[f]
1166 if state in "nr" and f not in m1:
1166 if state in "nr" and f not in m1:
1167 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1167 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1168 errors += 1
1168 errors += 1
1169 if state in "a" and f in m1:
1169 if state in "a" and f in m1:
1170 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1170 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1171 errors += 1
1171 errors += 1
1172 if state in "m" and f not in m1 and f not in m2:
1172 if state in "m" and f not in m1 and f not in m2:
1173 ui.warn(_("%s in state %s, but not in either manifest\n") %
1173 ui.warn(_("%s in state %s, but not in either manifest\n") %
1174 (f, state))
1174 (f, state))
1175 errors += 1
1175 errors += 1
1176 for f in m1:
1176 for f in m1:
1177 state = repo.dirstate[f]
1177 state = repo.dirstate[f]
1178 if state not in "nrm":
1178 if state not in "nrm":
1179 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1179 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1180 errors += 1
1180 errors += 1
1181 if errors:
1181 if errors:
1182 error = _(".hg/dirstate inconsistent with current parent's manifest")
1182 error = _(".hg/dirstate inconsistent with current parent's manifest")
1183 raise util.Abort(error)
1183 raise util.Abort(error)
1184
1184
1185 def showconfig(ui, repo, *values, **opts):
1185 def showconfig(ui, repo, *values, **opts):
1186 """show combined config settings from all hgrc files
1186 """show combined config settings from all hgrc files
1187
1187
1188 With no arguments, print names and values of all config items.
1188 With no arguments, print names and values of all config items.
1189
1189
1190 With one argument of the form section.name, print just the value
1190 With one argument of the form section.name, print just the value
1191 of that config item.
1191 of that config item.
1192
1192
1193 With multiple arguments, print names and values of all config
1193 With multiple arguments, print names and values of all config
1194 items with matching section names.
1194 items with matching section names.
1195
1195
1196 With --debug, the source (filename and line number) is printed
1196 With --debug, the source (filename and line number) is printed
1197 for each config item.
1197 for each config item.
1198
1198
1199 Returns 0 on success.
1199 Returns 0 on success.
1200 """
1200 """
1201
1201
1202 for f in util.rcpath():
1202 for f in util.rcpath():
1203 ui.debug(_('read config from: %s\n') % f)
1203 ui.debug(_('read config from: %s\n') % f)
1204 untrusted = bool(opts.get('untrusted'))
1204 untrusted = bool(opts.get('untrusted'))
1205 if values:
1205 if values:
1206 sections = [v for v in values if '.' not in v]
1206 sections = [v for v in values if '.' not in v]
1207 items = [v for v in values if '.' in v]
1207 items = [v for v in values if '.' in v]
1208 if len(items) > 1 or items and sections:
1208 if len(items) > 1 or items and sections:
1209 raise util.Abort(_('only one config item permitted'))
1209 raise util.Abort(_('only one config item permitted'))
1210 for section, name, value in ui.walkconfig(untrusted=untrusted):
1210 for section, name, value in ui.walkconfig(untrusted=untrusted):
1211 value = str(value).replace('\n', '\\n')
1211 value = str(value).replace('\n', '\\n')
1212 sectname = section + '.' + name
1212 sectname = section + '.' + name
1213 if values:
1213 if values:
1214 for v in values:
1214 for v in values:
1215 if v == section:
1215 if v == section:
1216 ui.debug('%s: ' %
1216 ui.debug('%s: ' %
1217 ui.configsource(section, name, untrusted))
1217 ui.configsource(section, name, untrusted))
1218 ui.write('%s=%s\n' % (sectname, value))
1218 ui.write('%s=%s\n' % (sectname, value))
1219 elif v == sectname:
1219 elif v == sectname:
1220 ui.debug('%s: ' %
1220 ui.debug('%s: ' %
1221 ui.configsource(section, name, untrusted))
1221 ui.configsource(section, name, untrusted))
1222 ui.write(value, '\n')
1222 ui.write(value, '\n')
1223 else:
1223 else:
1224 ui.debug('%s: ' %
1224 ui.debug('%s: ' %
1225 ui.configsource(section, name, untrusted))
1225 ui.configsource(section, name, untrusted))
1226 ui.write('%s=%s\n' % (sectname, value))
1226 ui.write('%s=%s\n' % (sectname, value))
1227
1227
1228 def debugknown(ui, repopath, *ids, **opts):
1228 def debugknown(ui, repopath, *ids, **opts):
1229 """test whether node ids are known to a repo
1229 """test whether node ids are known to a repo
1230
1230
1231 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1231 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1232 indicating unknown/known.
1232 indicating unknown/known.
1233 """
1233 """
1234 repo = hg.repository(ui, repopath)
1234 repo = hg.repository(ui, repopath)
1235 if not repo.capable('known'):
1235 if not repo.capable('known'):
1236 raise util.Abort("known() not supported by target repository")
1236 raise util.Abort("known() not supported by target repository")
1237 flags = repo.known([bin(s) for s in ids])
1237 flags = repo.known([bin(s) for s in ids])
1238 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1238 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1239
1239
1240 def debugbundle(ui, bundlepath, all=None, **opts):
1240 def debugbundle(ui, bundlepath, all=None, **opts):
1241 """lists the contents of a bundle"""
1241 """lists the contents of a bundle"""
1242 f = url.open(ui, bundlepath)
1242 f = url.open(ui, bundlepath)
1243 try:
1243 try:
1244 gen = changegroup.readbundle(f, bundlepath)
1244 gen = changegroup.readbundle(f, bundlepath)
1245 if all:
1245 if all:
1246 ui.write("format: id, p1, p2, cset, len(delta)\n")
1246 ui.write("format: id, p1, p2, cset, len(delta)\n")
1247
1247
1248 def showchunks(named):
1248 def showchunks(named):
1249 ui.write("\n%s\n" % named)
1249 ui.write("\n%s\n" % named)
1250 while 1:
1250 while 1:
1251 chunkdata = gen.parsechunk()
1251 chunkdata = gen.parsechunk()
1252 if not chunkdata:
1252 if not chunkdata:
1253 break
1253 break
1254 node = chunkdata['node']
1254 node = chunkdata['node']
1255 p1 = chunkdata['p1']
1255 p1 = chunkdata['p1']
1256 p2 = chunkdata['p2']
1256 p2 = chunkdata['p2']
1257 cs = chunkdata['cs']
1257 cs = chunkdata['cs']
1258 delta = chunkdata['data']
1258 delta = chunkdata['data']
1259 ui.write("%s %s %s %s %s\n" %
1259 ui.write("%s %s %s %s %s\n" %
1260 (hex(node), hex(p1), hex(p2),
1260 (hex(node), hex(p1), hex(p2),
1261 hex(cs), len(delta)))
1261 hex(cs), len(delta)))
1262
1262
1263 showchunks("changelog")
1263 showchunks("changelog")
1264 showchunks("manifest")
1264 showchunks("manifest")
1265 while 1:
1265 while 1:
1266 fname = gen.chunk()
1266 fname = gen.chunk()
1267 if not fname:
1267 if not fname:
1268 break
1268 break
1269 showchunks(fname)
1269 showchunks(fname)
1270 else:
1270 else:
1271 while 1:
1271 while 1:
1272 chunkdata = gen.parsechunk()
1272 chunkdata = gen.parsechunk()
1273 if not chunkdata:
1273 if not chunkdata:
1274 break
1274 break
1275 node = chunkdata['node']
1275 node = chunkdata['node']
1276 ui.write("%s\n" % hex(node))
1276 ui.write("%s\n" % hex(node))
1277 finally:
1277 finally:
1278 f.close()
1278 f.close()
1279
1279
1280 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1280 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1281 """retrieves a bundle from a repo
1281 """retrieves a bundle from a repo
1282
1282
1283 Every ID must be a full-length hex node id string. Saves the bundle to the
1283 Every ID must be a full-length hex node id string. Saves the bundle to the
1284 given file.
1284 given file.
1285 """
1285 """
1286 repo = hg.repository(ui, repopath)
1286 repo = hg.repository(ui, repopath)
1287 if not repo.capable('getbundle'):
1287 if not repo.capable('getbundle'):
1288 raise util.Abort("getbundle() not supported by target repository")
1288 raise util.Abort("getbundle() not supported by target repository")
1289 args = {}
1289 args = {}
1290 if common:
1290 if common:
1291 args['common'] = [bin(s) for s in common]
1291 args['common'] = [bin(s) for s in common]
1292 if head:
1292 if head:
1293 args['heads'] = [bin(s) for s in head]
1293 args['heads'] = [bin(s) for s in head]
1294 bundle = repo.getbundle('debug', **args)
1294 bundle = repo.getbundle('debug', **args)
1295
1295
1296 bundletype = opts.get('type', 'bzip2').lower()
1296 bundletype = opts.get('type', 'bzip2').lower()
1297 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1297 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1298 bundletype = btypes.get(bundletype)
1298 bundletype = btypes.get(bundletype)
1299 if bundletype not in changegroup.bundletypes:
1299 if bundletype not in changegroup.bundletypes:
1300 raise util.Abort(_('unknown bundle type specified with --type'))
1300 raise util.Abort(_('unknown bundle type specified with --type'))
1301 changegroup.writebundle(bundle, bundlepath, bundletype)
1301 changegroup.writebundle(bundle, bundlepath, bundletype)
1302
1302
1303 def debugpushkey(ui, repopath, namespace, *keyinfo):
1303 def debugpushkey(ui, repopath, namespace, *keyinfo):
1304 '''access the pushkey key/value protocol
1304 '''access the pushkey key/value protocol
1305
1305
1306 With two args, list the keys in the given namespace.
1306 With two args, list the keys in the given namespace.
1307
1307
1308 With five args, set a key to new if it currently is set to old.
1308 With five args, set a key to new if it currently is set to old.
1309 Reports success or failure.
1309 Reports success or failure.
1310 '''
1310 '''
1311
1311
1312 target = hg.repository(ui, repopath)
1312 target = hg.repository(ui, repopath)
1313 if keyinfo:
1313 if keyinfo:
1314 key, old, new = keyinfo
1314 key, old, new = keyinfo
1315 r = target.pushkey(namespace, key, old, new)
1315 r = target.pushkey(namespace, key, old, new)
1316 ui.status(str(r) + '\n')
1316 ui.status(str(r) + '\n')
1317 return not r
1317 return not r
1318 else:
1318 else:
1319 for k, v in target.listkeys(namespace).iteritems():
1319 for k, v in target.listkeys(namespace).iteritems():
1320 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1320 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1321 v.encode('string-escape')))
1321 v.encode('string-escape')))
1322
1322
1323 def debugrevspec(ui, repo, expr):
1323 def debugrevspec(ui, repo, expr):
1324 '''parse and apply a revision specification'''
1324 '''parse and apply a revision specification'''
1325 if ui.verbose:
1325 if ui.verbose:
1326 tree = revset.parse(expr)[0]
1326 tree = revset.parse(expr)[0]
1327 ui.note(tree, "\n")
1327 ui.note(tree, "\n")
1328 func = revset.match(expr)
1328 func = revset.match(expr)
1329 for c in func(repo, range(len(repo))):
1329 for c in func(repo, range(len(repo))):
1330 ui.write("%s\n" % c)
1330 ui.write("%s\n" % c)
1331
1331
1332 def debugsetparents(ui, repo, rev1, rev2=None):
1332 def debugsetparents(ui, repo, rev1, rev2=None):
1333 """manually set the parents of the current working directory
1333 """manually set the parents of the current working directory
1334
1334
1335 This is useful for writing repository conversion tools, but should
1335 This is useful for writing repository conversion tools, but should
1336 be used with care.
1336 be used with care.
1337
1337
1338 Returns 0 on success.
1338 Returns 0 on success.
1339 """
1339 """
1340
1340
1341 r1 = cmdutil.revsingle(repo, rev1).node()
1341 r1 = cmdutil.revsingle(repo, rev1).node()
1342 r2 = cmdutil.revsingle(repo, rev2, 'null').node()
1342 r2 = cmdutil.revsingle(repo, rev2, 'null').node()
1343
1343
1344 wlock = repo.wlock()
1344 wlock = repo.wlock()
1345 try:
1345 try:
1346 repo.dirstate.setparents(r1, r2)
1346 repo.dirstate.setparents(r1, r2)
1347 finally:
1347 finally:
1348 wlock.release()
1348 wlock.release()
1349
1349
1350 def debugstate(ui, repo, nodates=None, datesort=None):
1350 def debugstate(ui, repo, nodates=None, datesort=None):
1351 """show the contents of the current dirstate"""
1351 """show the contents of the current dirstate"""
1352 timestr = ""
1352 timestr = ""
1353 showdate = not nodates
1353 showdate = not nodates
1354 if datesort:
1354 if datesort:
1355 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
1355 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
1356 else:
1356 else:
1357 keyfunc = None # sort by filename
1357 keyfunc = None # sort by filename
1358 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
1358 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
1359 if showdate:
1359 if showdate:
1360 if ent[3] == -1:
1360 if ent[3] == -1:
1361 # Pad or slice to locale representation
1361 # Pad or slice to locale representation
1362 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1362 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1363 time.localtime(0)))
1363 time.localtime(0)))
1364 timestr = 'unset'
1364 timestr = 'unset'
1365 timestr = (timestr[:locale_len] +
1365 timestr = (timestr[:locale_len] +
1366 ' ' * (locale_len - len(timestr)))
1366 ' ' * (locale_len - len(timestr)))
1367 else:
1367 else:
1368 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1368 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1369 time.localtime(ent[3]))
1369 time.localtime(ent[3]))
1370 if ent[1] & 020000:
1370 if ent[1] & 020000:
1371 mode = 'lnk'
1371 mode = 'lnk'
1372 else:
1372 else:
1373 mode = '%3o' % (ent[1] & 0777)
1373 mode = '%3o' % (ent[1] & 0777)
1374 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1374 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1375 for f in repo.dirstate.copies():
1375 for f in repo.dirstate.copies():
1376 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1376 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1377
1377
1378 def debugsub(ui, repo, rev=None):
1378 def debugsub(ui, repo, rev=None):
1379 ctx = cmdutil.revsingle(repo, rev, None)
1379 ctx = cmdutil.revsingle(repo, rev, None)
1380 for k, v in sorted(ctx.substate.items()):
1380 for k, v in sorted(ctx.substate.items()):
1381 ui.write('path %s\n' % k)
1381 ui.write('path %s\n' % k)
1382 ui.write(' source %s\n' % v[0])
1382 ui.write(' source %s\n' % v[0])
1383 ui.write(' revision %s\n' % v[1])
1383 ui.write(' revision %s\n' % v[1])
1384
1384
1385 def debugdag(ui, repo, file_=None, *revs, **opts):
1385 def debugdag(ui, repo, file_=None, *revs, **opts):
1386 """format the changelog or an index DAG as a concise textual description
1386 """format the changelog or an index DAG as a concise textual description
1387
1387
1388 If you pass a revlog index, the revlog's DAG is emitted. If you list
1388 If you pass a revlog index, the revlog's DAG is emitted. If you list
1389 revision numbers, they get labelled in the output as rN.
1389 revision numbers, they get labelled in the output as rN.
1390
1390
1391 Otherwise, the changelog DAG of the current repo is emitted.
1391 Otherwise, the changelog DAG of the current repo is emitted.
1392 """
1392 """
1393 spaces = opts.get('spaces')
1393 spaces = opts.get('spaces')
1394 dots = opts.get('dots')
1394 dots = opts.get('dots')
1395 if file_:
1395 if file_:
1396 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1396 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1397 revs = set((int(r) for r in revs))
1397 revs = set((int(r) for r in revs))
1398 def events():
1398 def events():
1399 for r in rlog:
1399 for r in rlog:
1400 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1400 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1401 if r in revs:
1401 if r in revs:
1402 yield 'l', (r, "r%i" % r)
1402 yield 'l', (r, "r%i" % r)
1403 elif repo:
1403 elif repo:
1404 cl = repo.changelog
1404 cl = repo.changelog
1405 tags = opts.get('tags')
1405 tags = opts.get('tags')
1406 branches = opts.get('branches')
1406 branches = opts.get('branches')
1407 if tags:
1407 if tags:
1408 labels = {}
1408 labels = {}
1409 for l, n in repo.tags().items():
1409 for l, n in repo.tags().items():
1410 labels.setdefault(cl.rev(n), []).append(l)
1410 labels.setdefault(cl.rev(n), []).append(l)
1411 def events():
1411 def events():
1412 b = "default"
1412 b = "default"
1413 for r in cl:
1413 for r in cl:
1414 if branches:
1414 if branches:
1415 newb = cl.read(cl.node(r))[5]['branch']
1415 newb = cl.read(cl.node(r))[5]['branch']
1416 if newb != b:
1416 if newb != b:
1417 yield 'a', newb
1417 yield 'a', newb
1418 b = newb
1418 b = newb
1419 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1419 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1420 if tags:
1420 if tags:
1421 ls = labels.get(r)
1421 ls = labels.get(r)
1422 if ls:
1422 if ls:
1423 for l in ls:
1423 for l in ls:
1424 yield 'l', (r, l)
1424 yield 'l', (r, l)
1425 else:
1425 else:
1426 raise util.Abort(_('need repo for changelog dag'))
1426 raise util.Abort(_('need repo for changelog dag'))
1427
1427
1428 for line in dagparser.dagtextlines(events(),
1428 for line in dagparser.dagtextlines(events(),
1429 addspaces=spaces,
1429 addspaces=spaces,
1430 wraplabels=True,
1430 wraplabels=True,
1431 wrapannotations=True,
1431 wrapannotations=True,
1432 wrapnonlinear=dots,
1432 wrapnonlinear=dots,
1433 usedots=dots,
1433 usedots=dots,
1434 maxlinewidth=70):
1434 maxlinewidth=70):
1435 ui.write(line)
1435 ui.write(line)
1436 ui.write("\n")
1436 ui.write("\n")
1437
1437
1438 def debugdata(ui, repo, file_, rev):
1438 def debugdata(ui, repo, file_, rev):
1439 """dump the contents of a data file revision"""
1439 """dump the contents of a data file revision"""
1440 r = None
1440 r = None
1441 if repo:
1441 if repo:
1442 filelog = repo.file(file_)
1442 filelog = repo.file(file_)
1443 if len(filelog):
1443 if len(filelog):
1444 r = filelog
1444 r = filelog
1445 if not r:
1445 if not r:
1446 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1446 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1447 try:
1447 try:
1448 ui.write(r.revision(r.lookup(rev)))
1448 ui.write(r.revision(r.lookup(rev)))
1449 except KeyError:
1449 except KeyError:
1450 raise util.Abort(_('invalid revision identifier %s') % rev)
1450 raise util.Abort(_('invalid revision identifier %s') % rev)
1451
1451
1452 def debugdate(ui, date, range=None, **opts):
1452 def debugdate(ui, date, range=None, **opts):
1453 """parse and display a date"""
1453 """parse and display a date"""
1454 if opts["extended"]:
1454 if opts["extended"]:
1455 d = util.parsedate(date, util.extendeddateformats)
1455 d = util.parsedate(date, util.extendeddateformats)
1456 else:
1456 else:
1457 d = util.parsedate(date)
1457 d = util.parsedate(date)
1458 ui.write("internal: %s %s\n" % d)
1458 ui.write("internal: %s %s\n" % d)
1459 ui.write("standard: %s\n" % util.datestr(d))
1459 ui.write("standard: %s\n" % util.datestr(d))
1460 if range:
1460 if range:
1461 m = util.matchdate(range)
1461 m = util.matchdate(range)
1462 ui.write("match: %s\n" % m(d[0]))
1462 ui.write("match: %s\n" % m(d[0]))
1463
1463
1464 def debugignore(ui, repo, *values, **opts):
1464 def debugignore(ui, repo, *values, **opts):
1465 """display the combined ignore pattern"""
1465 """display the combined ignore pattern"""
1466 ignore = repo.dirstate._ignore
1466 ignore = repo.dirstate._ignore
1467 if hasattr(ignore, 'includepat'):
1467 if hasattr(ignore, 'includepat'):
1468 ui.write("%s\n" % ignore.includepat)
1468 ui.write("%s\n" % ignore.includepat)
1469 else:
1469 else:
1470 raise util.Abort(_("no ignore patterns found"))
1470 raise util.Abort(_("no ignore patterns found"))
1471
1471
1472 def debugindex(ui, repo, file_, **opts):
1472 def debugindex(ui, repo, file_, **opts):
1473 """dump the contents of an index file"""
1473 """dump the contents of an index file"""
1474 r = None
1474 r = None
1475 if repo:
1475 if repo:
1476 filelog = repo.file(file_)
1476 filelog = repo.file(file_)
1477 if len(filelog):
1477 if len(filelog):
1478 r = filelog
1478 r = filelog
1479
1479
1480 format = opts.get('format', 0)
1480 format = opts.get('format', 0)
1481 if format not in (0, 1):
1481 if format not in (0, 1):
1482 raise util.Abort(_("unknown format %d") % format)
1482 raise util.Abort(_("unknown format %d") % format)
1483
1483
1484 if not r:
1484 if not r:
1485 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1485 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1486
1486
1487 if format == 0:
1487 if format == 0:
1488 ui.write(" rev offset length base linkrev"
1488 ui.write(" rev offset length base linkrev"
1489 " nodeid p1 p2\n")
1489 " nodeid p1 p2\n")
1490 elif format == 1:
1490 elif format == 1:
1491 ui.write(" rev flag offset length"
1491 ui.write(" rev flag offset length"
1492 " size base link p1 p2 nodeid\n")
1492 " size base link p1 p2 nodeid\n")
1493
1493
1494 for i in r:
1494 for i in r:
1495 node = r.node(i)
1495 node = r.node(i)
1496 if format == 0:
1496 if format == 0:
1497 try:
1497 try:
1498 pp = r.parents(node)
1498 pp = r.parents(node)
1499 except:
1499 except:
1500 pp = [nullid, nullid]
1500 pp = [nullid, nullid]
1501 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1501 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1502 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1502 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1503 short(node), short(pp[0]), short(pp[1])))
1503 short(node), short(pp[0]), short(pp[1])))
1504 elif format == 1:
1504 elif format == 1:
1505 pr = r.parentrevs(i)
1505 pr = r.parentrevs(i)
1506 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1506 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1507 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1507 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1508 r.base(i), r.linkrev(i), pr[0], pr[1], short(node)))
1508 r.base(i), r.linkrev(i), pr[0], pr[1], short(node)))
1509
1509
1510 def debugindexdot(ui, repo, file_):
1510 def debugindexdot(ui, repo, file_):
1511 """dump an index DAG as a graphviz dot file"""
1511 """dump an index DAG as a graphviz dot file"""
1512 r = None
1512 r = None
1513 if repo:
1513 if repo:
1514 filelog = repo.file(file_)
1514 filelog = repo.file(file_)
1515 if len(filelog):
1515 if len(filelog):
1516 r = filelog
1516 r = filelog
1517 if not r:
1517 if not r:
1518 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1518 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1519 ui.write("digraph G {\n")
1519 ui.write("digraph G {\n")
1520 for i in r:
1520 for i in r:
1521 node = r.node(i)
1521 node = r.node(i)
1522 pp = r.parents(node)
1522 pp = r.parents(node)
1523 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1523 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1524 if pp[1] != nullid:
1524 if pp[1] != nullid:
1525 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1525 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1526 ui.write("}\n")
1526 ui.write("}\n")
1527
1527
1528 def debuginstall(ui):
1528 def debuginstall(ui):
1529 '''test Mercurial installation
1529 '''test Mercurial installation
1530
1530
1531 Returns 0 on success.
1531 Returns 0 on success.
1532 '''
1532 '''
1533
1533
1534 def writetemp(contents):
1534 def writetemp(contents):
1535 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1535 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1536 f = os.fdopen(fd, "wb")
1536 f = os.fdopen(fd, "wb")
1537 f.write(contents)
1537 f.write(contents)
1538 f.close()
1538 f.close()
1539 return name
1539 return name
1540
1540
1541 problems = 0
1541 problems = 0
1542
1542
1543 # encoding
1543 # encoding
1544 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1544 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1545 try:
1545 try:
1546 encoding.fromlocal("test")
1546 encoding.fromlocal("test")
1547 except util.Abort, inst:
1547 except util.Abort, inst:
1548 ui.write(" %s\n" % inst)
1548 ui.write(" %s\n" % inst)
1549 ui.write(_(" (check that your locale is properly set)\n"))
1549 ui.write(_(" (check that your locale is properly set)\n"))
1550 problems += 1
1550 problems += 1
1551
1551
1552 # compiled modules
1552 # compiled modules
1553 ui.status(_("Checking installed modules (%s)...\n")
1553 ui.status(_("Checking installed modules (%s)...\n")
1554 % os.path.dirname(__file__))
1554 % os.path.dirname(__file__))
1555 try:
1555 try:
1556 import bdiff, mpatch, base85, osutil
1556 import bdiff, mpatch, base85, osutil
1557 except Exception, inst:
1557 except Exception, inst:
1558 ui.write(" %s\n" % inst)
1558 ui.write(" %s\n" % inst)
1559 ui.write(_(" One or more extensions could not be found"))
1559 ui.write(_(" One or more extensions could not be found"))
1560 ui.write(_(" (check that you compiled the extensions)\n"))
1560 ui.write(_(" (check that you compiled the extensions)\n"))
1561 problems += 1
1561 problems += 1
1562
1562
1563 # templates
1563 # templates
1564 ui.status(_("Checking templates...\n"))
1564 ui.status(_("Checking templates...\n"))
1565 try:
1565 try:
1566 import templater
1566 import templater
1567 templater.templater(templater.templatepath("map-cmdline.default"))
1567 templater.templater(templater.templatepath("map-cmdline.default"))
1568 except Exception, inst:
1568 except Exception, inst:
1569 ui.write(" %s\n" % inst)
1569 ui.write(" %s\n" % inst)
1570 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1570 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1571 problems += 1
1571 problems += 1
1572
1572
1573 # editor
1573 # editor
1574 ui.status(_("Checking commit editor...\n"))
1574 ui.status(_("Checking commit editor...\n"))
1575 editor = ui.geteditor()
1575 editor = ui.geteditor()
1576 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1576 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1577 if not cmdpath:
1577 if not cmdpath:
1578 if editor == 'vi':
1578 if editor == 'vi':
1579 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1579 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1580 ui.write(_(" (specify a commit editor in your configuration"
1580 ui.write(_(" (specify a commit editor in your configuration"
1581 " file)\n"))
1581 " file)\n"))
1582 else:
1582 else:
1583 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1583 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1584 ui.write(_(" (specify a commit editor in your configuration"
1584 ui.write(_(" (specify a commit editor in your configuration"
1585 " file)\n"))
1585 " file)\n"))
1586 problems += 1
1586 problems += 1
1587
1587
1588 # check username
1588 # check username
1589 ui.status(_("Checking username...\n"))
1589 ui.status(_("Checking username...\n"))
1590 try:
1590 try:
1591 ui.username()
1591 ui.username()
1592 except util.Abort, e:
1592 except util.Abort, e:
1593 ui.write(" %s\n" % e)
1593 ui.write(" %s\n" % e)
1594 ui.write(_(" (specify a username in your configuration file)\n"))
1594 ui.write(_(" (specify a username in your configuration file)\n"))
1595 problems += 1
1595 problems += 1
1596
1596
1597 if not problems:
1597 if not problems:
1598 ui.status(_("No problems detected\n"))
1598 ui.status(_("No problems detected\n"))
1599 else:
1599 else:
1600 ui.write(_("%s problems detected,"
1600 ui.write(_("%s problems detected,"
1601 " please check your install!\n") % problems)
1601 " please check your install!\n") % problems)
1602
1602
1603 return problems
1603 return problems
1604
1604
1605 def debugrename(ui, repo, file1, *pats, **opts):
1605 def debugrename(ui, repo, file1, *pats, **opts):
1606 """dump rename information"""
1606 """dump rename information"""
1607
1607
1608 ctx = cmdutil.revsingle(repo, opts.get('rev'))
1608 ctx = cmdutil.revsingle(repo, opts.get('rev'))
1609 m = cmdutil.match(repo, (file1,) + pats, opts)
1609 m = cmdutil.match(repo, (file1,) + pats, opts)
1610 for abs in ctx.walk(m):
1610 for abs in ctx.walk(m):
1611 fctx = ctx[abs]
1611 fctx = ctx[abs]
1612 o = fctx.filelog().renamed(fctx.filenode())
1612 o = fctx.filelog().renamed(fctx.filenode())
1613 rel = m.rel(abs)
1613 rel = m.rel(abs)
1614 if o:
1614 if o:
1615 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1615 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1616 else:
1616 else:
1617 ui.write(_("%s not renamed\n") % rel)
1617 ui.write(_("%s not renamed\n") % rel)
1618
1618
1619 def debugwalk(ui, repo, *pats, **opts):
1619 def debugwalk(ui, repo, *pats, **opts):
1620 """show how files match on given patterns"""
1620 """show how files match on given patterns"""
1621 m = cmdutil.match(repo, pats, opts)
1621 m = cmdutil.match(repo, pats, opts)
1622 items = list(repo.walk(m))
1622 items = list(repo.walk(m))
1623 if not items:
1623 if not items:
1624 return
1624 return
1625 fmt = 'f %%-%ds %%-%ds %%s' % (
1625 fmt = 'f %%-%ds %%-%ds %%s' % (
1626 max([len(abs) for abs in items]),
1626 max([len(abs) for abs in items]),
1627 max([len(m.rel(abs)) for abs in items]))
1627 max([len(m.rel(abs)) for abs in items]))
1628 for abs in items:
1628 for abs in items:
1629 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1629 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1630 ui.write("%s\n" % line.rstrip())
1630 ui.write("%s\n" % line.rstrip())
1631
1631
1632 def debugwireargs(ui, repopath, *vals, **opts):
1632 def debugwireargs(ui, repopath, *vals, **opts):
1633 repo = hg.repository(hg.remoteui(ui, opts), repopath)
1633 repo = hg.repository(hg.remoteui(ui, opts), repopath)
1634 for opt in remoteopts:
1634 for opt in remoteopts:
1635 del opts[opt[1]]
1635 del opts[opt[1]]
1636 args = {}
1636 args = {}
1637 for k, v in opts.iteritems():
1637 for k, v in opts.iteritems():
1638 if v:
1638 if v:
1639 args[k] = v
1639 args[k] = v
1640 # run twice to check that we don't mess up the stream for the next command
1640 # run twice to check that we don't mess up the stream for the next command
1641 res1 = repo.debugwireargs(*vals, **args)
1641 res1 = repo.debugwireargs(*vals, **args)
1642 res2 = repo.debugwireargs(*vals, **args)
1642 res2 = repo.debugwireargs(*vals, **args)
1643 ui.write("%s\n" % res1)
1643 ui.write("%s\n" % res1)
1644 if res1 != res2:
1644 if res1 != res2:
1645 ui.warn("%s\n" % res2)
1645 ui.warn("%s\n" % res2)
1646
1646
1647 def diff(ui, repo, *pats, **opts):
1647 def diff(ui, repo, *pats, **opts):
1648 """diff repository (or selected files)
1648 """diff repository (or selected files)
1649
1649
1650 Show differences between revisions for the specified files.
1650 Show differences between revisions for the specified files.
1651
1651
1652 Differences between files are shown using the unified diff format.
1652 Differences between files are shown using the unified diff format.
1653
1653
1654 .. note::
1654 .. note::
1655 diff may generate unexpected results for merges, as it will
1655 diff may generate unexpected results for merges, as it will
1656 default to comparing against the working directory's first
1656 default to comparing against the working directory's first
1657 parent changeset if no revisions are specified.
1657 parent changeset if no revisions are specified.
1658
1658
1659 When two revision arguments are given, then changes are shown
1659 When two revision arguments are given, then changes are shown
1660 between those revisions. If only one revision is specified then
1660 between those revisions. If only one revision is specified then
1661 that revision is compared to the working directory, and, when no
1661 that revision is compared to the working directory, and, when no
1662 revisions are specified, the working directory files are compared
1662 revisions are specified, the working directory files are compared
1663 to its parent.
1663 to its parent.
1664
1664
1665 Alternatively you can specify -c/--change with a revision to see
1665 Alternatively you can specify -c/--change with a revision to see
1666 the changes in that changeset relative to its first parent.
1666 the changes in that changeset relative to its first parent.
1667
1667
1668 Without the -a/--text option, diff will avoid generating diffs of
1668 Without the -a/--text option, diff will avoid generating diffs of
1669 files it detects as binary. With -a, diff will generate a diff
1669 files it detects as binary. With -a, diff will generate a diff
1670 anyway, probably with undesirable results.
1670 anyway, probably with undesirable results.
1671
1671
1672 Use the -g/--git option to generate diffs in the git extended diff
1672 Use the -g/--git option to generate diffs in the git extended diff
1673 format. For more information, read :hg:`help diffs`.
1673 format. For more information, read :hg:`help diffs`.
1674
1674
1675 Returns 0 on success.
1675 Returns 0 on success.
1676 """
1676 """
1677
1677
1678 revs = opts.get('rev')
1678 revs = opts.get('rev')
1679 change = opts.get('change')
1679 change = opts.get('change')
1680 stat = opts.get('stat')
1680 stat = opts.get('stat')
1681 reverse = opts.get('reverse')
1681 reverse = opts.get('reverse')
1682
1682
1683 if revs and change:
1683 if revs and change:
1684 msg = _('cannot specify --rev and --change at the same time')
1684 msg = _('cannot specify --rev and --change at the same time')
1685 raise util.Abort(msg)
1685 raise util.Abort(msg)
1686 elif change:
1686 elif change:
1687 node2 = cmdutil.revsingle(repo, change, None).node()
1687 node2 = cmdutil.revsingle(repo, change, None).node()
1688 node1 = repo[node2].p1().node()
1688 node1 = repo[node2].p1().node()
1689 else:
1689 else:
1690 node1, node2 = cmdutil.revpair(repo, revs)
1690 node1, node2 = cmdutil.revpair(repo, revs)
1691
1691
1692 if reverse:
1692 if reverse:
1693 node1, node2 = node2, node1
1693 node1, node2 = node2, node1
1694
1694
1695 diffopts = patch.diffopts(ui, opts)
1695 diffopts = patch.diffopts(ui, opts)
1696 m = cmdutil.match(repo, pats, opts)
1696 m = cmdutil.match(repo, pats, opts)
1697 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1697 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1698 listsubrepos=opts.get('subrepos'))
1698 listsubrepos=opts.get('subrepos'))
1699
1699
1700 def export(ui, repo, *changesets, **opts):
1700 def export(ui, repo, *changesets, **opts):
1701 """dump the header and diffs for one or more changesets
1701 """dump the header and diffs for one or more changesets
1702
1702
1703 Print the changeset header and diffs for one or more revisions.
1703 Print the changeset header and diffs for one or more revisions.
1704
1704
1705 The information shown in the changeset header is: author, date,
1705 The information shown in the changeset header is: author, date,
1706 branch name (if non-default), changeset hash, parent(s) and commit
1706 branch name (if non-default), changeset hash, parent(s) and commit
1707 comment.
1707 comment.
1708
1708
1709 .. note::
1709 .. note::
1710 export may generate unexpected diff output for merge
1710 export may generate unexpected diff output for merge
1711 changesets, as it will compare the merge changeset against its
1711 changesets, as it will compare the merge changeset against its
1712 first parent only.
1712 first parent only.
1713
1713
1714 Output may be to a file, in which case the name of the file is
1714 Output may be to a file, in which case the name of the file is
1715 given using a format string. The formatting rules are as follows:
1715 given using a format string. The formatting rules are as follows:
1716
1716
1717 :``%%``: literal "%" character
1717 :``%%``: literal "%" character
1718 :``%H``: changeset hash (40 hexadecimal digits)
1718 :``%H``: changeset hash (40 hexadecimal digits)
1719 :``%N``: number of patches being generated
1719 :``%N``: number of patches being generated
1720 :``%R``: changeset revision number
1720 :``%R``: changeset revision number
1721 :``%b``: basename of the exporting repository
1721 :``%b``: basename of the exporting repository
1722 :``%h``: short-form changeset hash (12 hexadecimal digits)
1722 :``%h``: short-form changeset hash (12 hexadecimal digits)
1723 :``%n``: zero-padded sequence number, starting at 1
1723 :``%n``: zero-padded sequence number, starting at 1
1724 :``%r``: zero-padded changeset revision number
1724 :``%r``: zero-padded changeset revision number
1725
1725
1726 Without the -a/--text option, export will avoid generating diffs
1726 Without the -a/--text option, export will avoid generating diffs
1727 of files it detects as binary. With -a, export will generate a
1727 of files it detects as binary. With -a, export will generate a
1728 diff anyway, probably with undesirable results.
1728 diff anyway, probably with undesirable results.
1729
1729
1730 Use the -g/--git option to generate diffs in the git extended diff
1730 Use the -g/--git option to generate diffs in the git extended diff
1731 format. See :hg:`help diffs` for more information.
1731 format. See :hg:`help diffs` for more information.
1732
1732
1733 With the --switch-parent option, the diff will be against the
1733 With the --switch-parent option, the diff will be against the
1734 second parent. It can be useful to review a merge.
1734 second parent. It can be useful to review a merge.
1735
1735
1736 Returns 0 on success.
1736 Returns 0 on success.
1737 """
1737 """
1738 changesets += tuple(opts.get('rev', []))
1738 changesets += tuple(opts.get('rev', []))
1739 if not changesets:
1739 if not changesets:
1740 raise util.Abort(_("export requires at least one changeset"))
1740 raise util.Abort(_("export requires at least one changeset"))
1741 revs = cmdutil.revrange(repo, changesets)
1741 revs = cmdutil.revrange(repo, changesets)
1742 if len(revs) > 1:
1742 if len(revs) > 1:
1743 ui.note(_('exporting patches:\n'))
1743 ui.note(_('exporting patches:\n'))
1744 else:
1744 else:
1745 ui.note(_('exporting patch:\n'))
1745 ui.note(_('exporting patch:\n'))
1746 cmdutil.export(repo, revs, template=opts.get('output'),
1746 cmdutil.export(repo, revs, template=opts.get('output'),
1747 switch_parent=opts.get('switch_parent'),
1747 switch_parent=opts.get('switch_parent'),
1748 opts=patch.diffopts(ui, opts))
1748 opts=patch.diffopts(ui, opts))
1749
1749
1750 def forget(ui, repo, *pats, **opts):
1750 def forget(ui, repo, *pats, **opts):
1751 """forget the specified files on the next commit
1751 """forget the specified files on the next commit
1752
1752
1753 Mark the specified files so they will no longer be tracked
1753 Mark the specified files so they will no longer be tracked
1754 after the next commit.
1754 after the next commit.
1755
1755
1756 This only removes files from the current branch, not from the
1756 This only removes files from the current branch, not from the
1757 entire project history, and it does not delete them from the
1757 entire project history, and it does not delete them from the
1758 working directory.
1758 working directory.
1759
1759
1760 To undo a forget before the next commit, see :hg:`add`.
1760 To undo a forget before the next commit, see :hg:`add`.
1761
1761
1762 Returns 0 on success.
1762 Returns 0 on success.
1763 """
1763 """
1764
1764
1765 if not pats:
1765 if not pats:
1766 raise util.Abort(_('no files specified'))
1766 raise util.Abort(_('no files specified'))
1767
1767
1768 m = cmdutil.match(repo, pats, opts)
1768 m = cmdutil.match(repo, pats, opts)
1769 s = repo.status(match=m, clean=True)
1769 s = repo.status(match=m, clean=True)
1770 forget = sorted(s[0] + s[1] + s[3] + s[6])
1770 forget = sorted(s[0] + s[1] + s[3] + s[6])
1771 errs = 0
1771 errs = 0
1772
1772
1773 for f in m.files():
1773 for f in m.files():
1774 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1774 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1775 ui.warn(_('not removing %s: file is already untracked\n')
1775 ui.warn(_('not removing %s: file is already untracked\n')
1776 % m.rel(f))
1776 % m.rel(f))
1777 errs = 1
1777 errs = 1
1778
1778
1779 for f in forget:
1779 for f in forget:
1780 if ui.verbose or not m.exact(f):
1780 if ui.verbose or not m.exact(f):
1781 ui.status(_('removing %s\n') % m.rel(f))
1781 ui.status(_('removing %s\n') % m.rel(f))
1782
1782
1783 repo[None].remove(forget, unlink=False)
1783 repo[None].remove(forget, unlink=False)
1784 return errs
1784 return errs
1785
1785
1786 def grep(ui, repo, pattern, *pats, **opts):
1786 def grep(ui, repo, pattern, *pats, **opts):
1787 """search for a pattern in specified files and revisions
1787 """search for a pattern in specified files and revisions
1788
1788
1789 Search revisions of files for a regular expression.
1789 Search revisions of files for a regular expression.
1790
1790
1791 This command behaves differently than Unix grep. It only accepts
1791 This command behaves differently than Unix grep. It only accepts
1792 Python/Perl regexps. It searches repository history, not the
1792 Python/Perl regexps. It searches repository history, not the
1793 working directory. It always prints the revision number in which a
1793 working directory. It always prints the revision number in which a
1794 match appears.
1794 match appears.
1795
1795
1796 By default, grep only prints output for the first revision of a
1796 By default, grep only prints output for the first revision of a
1797 file in which it finds a match. To get it to print every revision
1797 file in which it finds a match. To get it to print every revision
1798 that contains a change in match status ("-" for a match that
1798 that contains a change in match status ("-" for a match that
1799 becomes a non-match, or "+" for a non-match that becomes a match),
1799 becomes a non-match, or "+" for a non-match that becomes a match),
1800 use the --all flag.
1800 use the --all flag.
1801
1801
1802 Returns 0 if a match is found, 1 otherwise.
1802 Returns 0 if a match is found, 1 otherwise.
1803 """
1803 """
1804 reflags = 0
1804 reflags = 0
1805 if opts.get('ignore_case'):
1805 if opts.get('ignore_case'):
1806 reflags |= re.I
1806 reflags |= re.I
1807 try:
1807 try:
1808 regexp = re.compile(pattern, reflags)
1808 regexp = re.compile(pattern, reflags)
1809 except re.error, inst:
1809 except re.error, inst:
1810 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1810 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1811 return 1
1811 return 1
1812 sep, eol = ':', '\n'
1812 sep, eol = ':', '\n'
1813 if opts.get('print0'):
1813 if opts.get('print0'):
1814 sep = eol = '\0'
1814 sep = eol = '\0'
1815
1815
1816 getfile = util.lrucachefunc(repo.file)
1816 getfile = util.lrucachefunc(repo.file)
1817
1817
1818 def matchlines(body):
1818 def matchlines(body):
1819 begin = 0
1819 begin = 0
1820 linenum = 0
1820 linenum = 0
1821 while True:
1821 while True:
1822 match = regexp.search(body, begin)
1822 match = regexp.search(body, begin)
1823 if not match:
1823 if not match:
1824 break
1824 break
1825 mstart, mend = match.span()
1825 mstart, mend = match.span()
1826 linenum += body.count('\n', begin, mstart) + 1
1826 linenum += body.count('\n', begin, mstart) + 1
1827 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1827 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1828 begin = body.find('\n', mend) + 1 or len(body)
1828 begin = body.find('\n', mend) + 1 or len(body)
1829 lend = begin - 1
1829 lend = begin - 1
1830 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1830 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1831
1831
1832 class linestate(object):
1832 class linestate(object):
1833 def __init__(self, line, linenum, colstart, colend):
1833 def __init__(self, line, linenum, colstart, colend):
1834 self.line = line
1834 self.line = line
1835 self.linenum = linenum
1835 self.linenum = linenum
1836 self.colstart = colstart
1836 self.colstart = colstart
1837 self.colend = colend
1837 self.colend = colend
1838
1838
1839 def __hash__(self):
1839 def __hash__(self):
1840 return hash((self.linenum, self.line))
1840 return hash((self.linenum, self.line))
1841
1841
1842 def __eq__(self, other):
1842 def __eq__(self, other):
1843 return self.line == other.line
1843 return self.line == other.line
1844
1844
1845 matches = {}
1845 matches = {}
1846 copies = {}
1846 copies = {}
1847 def grepbody(fn, rev, body):
1847 def grepbody(fn, rev, body):
1848 matches[rev].setdefault(fn, [])
1848 matches[rev].setdefault(fn, [])
1849 m = matches[rev][fn]
1849 m = matches[rev][fn]
1850 for lnum, cstart, cend, line in matchlines(body):
1850 for lnum, cstart, cend, line in matchlines(body):
1851 s = linestate(line, lnum, cstart, cend)
1851 s = linestate(line, lnum, cstart, cend)
1852 m.append(s)
1852 m.append(s)
1853
1853
1854 def difflinestates(a, b):
1854 def difflinestates(a, b):
1855 sm = difflib.SequenceMatcher(None, a, b)
1855 sm = difflib.SequenceMatcher(None, a, b)
1856 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1856 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1857 if tag == 'insert':
1857 if tag == 'insert':
1858 for i in xrange(blo, bhi):
1858 for i in xrange(blo, bhi):
1859 yield ('+', b[i])
1859 yield ('+', b[i])
1860 elif tag == 'delete':
1860 elif tag == 'delete':
1861 for i in xrange(alo, ahi):
1861 for i in xrange(alo, ahi):
1862 yield ('-', a[i])
1862 yield ('-', a[i])
1863 elif tag == 'replace':
1863 elif tag == 'replace':
1864 for i in xrange(alo, ahi):
1864 for i in xrange(alo, ahi):
1865 yield ('-', a[i])
1865 yield ('-', a[i])
1866 for i in xrange(blo, bhi):
1866 for i in xrange(blo, bhi):
1867 yield ('+', b[i])
1867 yield ('+', b[i])
1868
1868
1869 def display(fn, ctx, pstates, states):
1869 def display(fn, ctx, pstates, states):
1870 rev = ctx.rev()
1870 rev = ctx.rev()
1871 datefunc = ui.quiet and util.shortdate or util.datestr
1871 datefunc = ui.quiet and util.shortdate or util.datestr
1872 found = False
1872 found = False
1873 filerevmatches = {}
1873 filerevmatches = {}
1874 def binary():
1874 def binary():
1875 flog = getfile(fn)
1875 flog = getfile(fn)
1876 return util.binary(flog.read(ctx.filenode(fn)))
1876 return util.binary(flog.read(ctx.filenode(fn)))
1877
1877
1878 if opts.get('all'):
1878 if opts.get('all'):
1879 iter = difflinestates(pstates, states)
1879 iter = difflinestates(pstates, states)
1880 else:
1880 else:
1881 iter = [('', l) for l in states]
1881 iter = [('', l) for l in states]
1882 for change, l in iter:
1882 for change, l in iter:
1883 cols = [fn, str(rev)]
1883 cols = [fn, str(rev)]
1884 before, match, after = None, None, None
1884 before, match, after = None, None, None
1885 if opts.get('line_number'):
1885 if opts.get('line_number'):
1886 cols.append(str(l.linenum))
1886 cols.append(str(l.linenum))
1887 if opts.get('all'):
1887 if opts.get('all'):
1888 cols.append(change)
1888 cols.append(change)
1889 if opts.get('user'):
1889 if opts.get('user'):
1890 cols.append(ui.shortuser(ctx.user()))
1890 cols.append(ui.shortuser(ctx.user()))
1891 if opts.get('date'):
1891 if opts.get('date'):
1892 cols.append(datefunc(ctx.date()))
1892 cols.append(datefunc(ctx.date()))
1893 if opts.get('files_with_matches'):
1893 if opts.get('files_with_matches'):
1894 c = (fn, rev)
1894 c = (fn, rev)
1895 if c in filerevmatches:
1895 if c in filerevmatches:
1896 continue
1896 continue
1897 filerevmatches[c] = 1
1897 filerevmatches[c] = 1
1898 else:
1898 else:
1899 before = l.line[:l.colstart]
1899 before = l.line[:l.colstart]
1900 match = l.line[l.colstart:l.colend]
1900 match = l.line[l.colstart:l.colend]
1901 after = l.line[l.colend:]
1901 after = l.line[l.colend:]
1902 ui.write(sep.join(cols))
1902 ui.write(sep.join(cols))
1903 if before is not None:
1903 if before is not None:
1904 if not opts.get('text') and binary():
1904 if not opts.get('text') and binary():
1905 ui.write(sep + " Binary file matches")
1905 ui.write(sep + " Binary file matches")
1906 else:
1906 else:
1907 ui.write(sep + before)
1907 ui.write(sep + before)
1908 ui.write(match, label='grep.match')
1908 ui.write(match, label='grep.match')
1909 ui.write(after)
1909 ui.write(after)
1910 ui.write(eol)
1910 ui.write(eol)
1911 found = True
1911 found = True
1912 return found
1912 return found
1913
1913
1914 skip = {}
1914 skip = {}
1915 revfiles = {}
1915 revfiles = {}
1916 matchfn = cmdutil.match(repo, pats, opts)
1916 matchfn = cmdutil.match(repo, pats, opts)
1917 found = False
1917 found = False
1918 follow = opts.get('follow')
1918 follow = opts.get('follow')
1919
1919
1920 def prep(ctx, fns):
1920 def prep(ctx, fns):
1921 rev = ctx.rev()
1921 rev = ctx.rev()
1922 pctx = ctx.p1()
1922 pctx = ctx.p1()
1923 parent = pctx.rev()
1923 parent = pctx.rev()
1924 matches.setdefault(rev, {})
1924 matches.setdefault(rev, {})
1925 matches.setdefault(parent, {})
1925 matches.setdefault(parent, {})
1926 files = revfiles.setdefault(rev, [])
1926 files = revfiles.setdefault(rev, [])
1927 for fn in fns:
1927 for fn in fns:
1928 flog = getfile(fn)
1928 flog = getfile(fn)
1929 try:
1929 try:
1930 fnode = ctx.filenode(fn)
1930 fnode = ctx.filenode(fn)
1931 except error.LookupError:
1931 except error.LookupError:
1932 continue
1932 continue
1933
1933
1934 copied = flog.renamed(fnode)
1934 copied = flog.renamed(fnode)
1935 copy = follow and copied and copied[0]
1935 copy = follow and copied and copied[0]
1936 if copy:
1936 if copy:
1937 copies.setdefault(rev, {})[fn] = copy
1937 copies.setdefault(rev, {})[fn] = copy
1938 if fn in skip:
1938 if fn in skip:
1939 if copy:
1939 if copy:
1940 skip[copy] = True
1940 skip[copy] = True
1941 continue
1941 continue
1942 files.append(fn)
1942 files.append(fn)
1943
1943
1944 if fn not in matches[rev]:
1944 if fn not in matches[rev]:
1945 grepbody(fn, rev, flog.read(fnode))
1945 grepbody(fn, rev, flog.read(fnode))
1946
1946
1947 pfn = copy or fn
1947 pfn = copy or fn
1948 if pfn not in matches[parent]:
1948 if pfn not in matches[parent]:
1949 try:
1949 try:
1950 fnode = pctx.filenode(pfn)
1950 fnode = pctx.filenode(pfn)
1951 grepbody(pfn, parent, flog.read(fnode))
1951 grepbody(pfn, parent, flog.read(fnode))
1952 except error.LookupError:
1952 except error.LookupError:
1953 pass
1953 pass
1954
1954
1955 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1955 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1956 rev = ctx.rev()
1956 rev = ctx.rev()
1957 parent = ctx.p1().rev()
1957 parent = ctx.p1().rev()
1958 for fn in sorted(revfiles.get(rev, [])):
1958 for fn in sorted(revfiles.get(rev, [])):
1959 states = matches[rev][fn]
1959 states = matches[rev][fn]
1960 copy = copies.get(rev, {}).get(fn)
1960 copy = copies.get(rev, {}).get(fn)
1961 if fn in skip:
1961 if fn in skip:
1962 if copy:
1962 if copy:
1963 skip[copy] = True
1963 skip[copy] = True
1964 continue
1964 continue
1965 pstates = matches.get(parent, {}).get(copy or fn, [])
1965 pstates = matches.get(parent, {}).get(copy or fn, [])
1966 if pstates or states:
1966 if pstates or states:
1967 r = display(fn, ctx, pstates, states)
1967 r = display(fn, ctx, pstates, states)
1968 found = found or r
1968 found = found or r
1969 if r and not opts.get('all'):
1969 if r and not opts.get('all'):
1970 skip[fn] = True
1970 skip[fn] = True
1971 if copy:
1971 if copy:
1972 skip[copy] = True
1972 skip[copy] = True
1973 del matches[rev]
1973 del matches[rev]
1974 del revfiles[rev]
1974 del revfiles[rev]
1975
1975
1976 return not found
1976 return not found
1977
1977
1978 def heads(ui, repo, *branchrevs, **opts):
1978 def heads(ui, repo, *branchrevs, **opts):
1979 """show current repository heads or show branch heads
1979 """show current repository heads or show branch heads
1980
1980
1981 With no arguments, show all repository branch heads.
1981 With no arguments, show all repository branch heads.
1982
1982
1983 Repository "heads" are changesets with no child changesets. They are
1983 Repository "heads" are changesets with no child changesets. They are
1984 where development generally takes place and are the usual targets
1984 where development generally takes place and are the usual targets
1985 for update and merge operations. Branch heads are changesets that have
1985 for update and merge operations. Branch heads are changesets that have
1986 no child changeset on the same branch.
1986 no child changeset on the same branch.
1987
1987
1988 If one or more REVs are given, only branch heads on the branches
1988 If one or more REVs are given, only branch heads on the branches
1989 associated with the specified changesets are shown.
1989 associated with the specified changesets are shown.
1990
1990
1991 If -c/--closed is specified, also show branch heads marked closed
1991 If -c/--closed is specified, also show branch heads marked closed
1992 (see :hg:`commit --close-branch`).
1992 (see :hg:`commit --close-branch`).
1993
1993
1994 If STARTREV is specified, only those heads that are descendants of
1994 If STARTREV is specified, only those heads that are descendants of
1995 STARTREV will be displayed.
1995 STARTREV will be displayed.
1996
1996
1997 If -t/--topo is specified, named branch mechanics will be ignored and only
1997 If -t/--topo is specified, named branch mechanics will be ignored and only
1998 changesets without children will be shown.
1998 changesets without children will be shown.
1999
1999
2000 Returns 0 if matching heads are found, 1 if not.
2000 Returns 0 if matching heads are found, 1 if not.
2001 """
2001 """
2002
2002
2003 start = None
2003 start = None
2004 if 'rev' in opts:
2004 if 'rev' in opts:
2005 start = cmdutil.revsingle(repo, opts['rev'], None).node()
2005 start = cmdutil.revsingle(repo, opts['rev'], None).node()
2006
2006
2007 if opts.get('topo'):
2007 if opts.get('topo'):
2008 heads = [repo[h] for h in repo.heads(start)]
2008 heads = [repo[h] for h in repo.heads(start)]
2009 else:
2009 else:
2010 heads = []
2010 heads = []
2011 for b, ls in repo.branchmap().iteritems():
2011 for b, ls in repo.branchmap().iteritems():
2012 if start is None:
2012 if start is None:
2013 heads += [repo[h] for h in ls]
2013 heads += [repo[h] for h in ls]
2014 continue
2014 continue
2015 startrev = repo.changelog.rev(start)
2015 startrev = repo.changelog.rev(start)
2016 descendants = set(repo.changelog.descendants(startrev))
2016 descendants = set(repo.changelog.descendants(startrev))
2017 descendants.add(startrev)
2017 descendants.add(startrev)
2018 rev = repo.changelog.rev
2018 rev = repo.changelog.rev
2019 heads += [repo[h] for h in ls if rev(h) in descendants]
2019 heads += [repo[h] for h in ls if rev(h) in descendants]
2020
2020
2021 if branchrevs:
2021 if branchrevs:
2022 branches = set(repo[br].branch() for br in branchrevs)
2022 branches = set(repo[br].branch() for br in branchrevs)
2023 heads = [h for h in heads if h.branch() in branches]
2023 heads = [h for h in heads if h.branch() in branches]
2024
2024
2025 if not opts.get('closed'):
2025 if not opts.get('closed'):
2026 heads = [h for h in heads if not h.extra().get('close')]
2026 heads = [h for h in heads if not h.extra().get('close')]
2027
2027
2028 if opts.get('active') and branchrevs:
2028 if opts.get('active') and branchrevs:
2029 dagheads = repo.heads(start)
2029 dagheads = repo.heads(start)
2030 heads = [h for h in heads if h.node() in dagheads]
2030 heads = [h for h in heads if h.node() in dagheads]
2031
2031
2032 if branchrevs:
2032 if branchrevs:
2033 haveheads = set(h.branch() for h in heads)
2033 haveheads = set(h.branch() for h in heads)
2034 if branches - haveheads:
2034 if branches - haveheads:
2035 headless = ', '.join(b for b in branches - haveheads)
2035 headless = ', '.join(b for b in branches - haveheads)
2036 msg = _('no open branch heads found on branches %s')
2036 msg = _('no open branch heads found on branches %s')
2037 if opts.get('rev'):
2037 if opts.get('rev'):
2038 msg += _(' (started at %s)' % opts['rev'])
2038 msg += _(' (started at %s)' % opts['rev'])
2039 ui.warn((msg + '\n') % headless)
2039 ui.warn((msg + '\n') % headless)
2040
2040
2041 if not heads:
2041 if not heads:
2042 return 1
2042 return 1
2043
2043
2044 heads = sorted(heads, key=lambda x: -x.rev())
2044 heads = sorted(heads, key=lambda x: -x.rev())
2045 displayer = cmdutil.show_changeset(ui, repo, opts)
2045 displayer = cmdutil.show_changeset(ui, repo, opts)
2046 for ctx in heads:
2046 for ctx in heads:
2047 displayer.show(ctx)
2047 displayer.show(ctx)
2048 displayer.close()
2048 displayer.close()
2049
2049
2050 def help_(ui, name=None, with_version=False, unknowncmd=False):
2050 def help_(ui, name=None, with_version=False, unknowncmd=False, full=True):
2051 """show help for a given topic or a help overview
2051 """show help for a given topic or a help overview
2052
2052
2053 With no arguments, print a list of commands with short help messages.
2053 With no arguments, print a list of commands with short help messages.
2054
2054
2055 Given a topic, extension, or command name, print help for that
2055 Given a topic, extension, or command name, print help for that
2056 topic.
2056 topic.
2057
2057
2058 Returns 0 if successful.
2058 Returns 0 if successful.
2059 """
2059 """
2060 option_lists = []
2060 option_lists = []
2061 textwidth = min(ui.termwidth(), 80) - 2
2061 textwidth = min(ui.termwidth(), 80) - 2
2062
2062
2063 def addglobalopts(aliases):
2063 def addglobalopts(aliases):
2064 if ui.verbose:
2064 if ui.verbose:
2065 option_lists.append((_("global options:"), globalopts))
2065 option_lists.append((_("global options:"), globalopts))
2066 if name == 'shortlist':
2066 if name == 'shortlist':
2067 option_lists.append((_('use "hg help" for the full list '
2067 option_lists.append((_('use "hg help" for the full list '
2068 'of commands'), ()))
2068 'of commands'), ()))
2069 else:
2069 else:
2070 if name == 'shortlist':
2070 if name == 'shortlist':
2071 msg = _('use "hg help" for the full list of commands '
2071 msg = _('use "hg help" for the full list of commands '
2072 'or "hg -v" for details')
2072 'or "hg -v" for details')
2073 elif name and not full:
2074 msg = _('use "hg help %s" to show the full help text' % name)
2073 elif aliases:
2075 elif aliases:
2074 msg = _('use "hg -v help%s" to show builtin aliases and '
2076 msg = _('use "hg -v help%s" to show builtin aliases and '
2075 'global options') % (name and " " + name or "")
2077 'global options') % (name and " " + name or "")
2076 else:
2078 else:
2077 msg = _('use "hg -v help %s" to show global options') % name
2079 msg = _('use "hg -v help %s" to show global options') % name
2078 option_lists.append((msg, ()))
2080 option_lists.append((msg, ()))
2079
2081
2080 def helpcmd(name):
2082 def helpcmd(name):
2081 if with_version:
2083 if with_version:
2082 version_(ui)
2084 version_(ui)
2083 ui.write('\n')
2085 ui.write('\n')
2084
2086
2085 try:
2087 try:
2086 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
2088 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
2087 except error.AmbiguousCommand, inst:
2089 except error.AmbiguousCommand, inst:
2088 # py3k fix: except vars can't be used outside the scope of the
2090 # py3k fix: except vars can't be used outside the scope of the
2089 # except block, nor can be used inside a lambda. python issue4617
2091 # except block, nor can be used inside a lambda. python issue4617
2090 prefix = inst.args[0]
2092 prefix = inst.args[0]
2091 select = lambda c: c.lstrip('^').startswith(prefix)
2093 select = lambda c: c.lstrip('^').startswith(prefix)
2092 helplist(_('list of commands:\n\n'), select)
2094 helplist(_('list of commands:\n\n'), select)
2093 return
2095 return
2094
2096
2095 # check if it's an invalid alias and display its error if it is
2097 # check if it's an invalid alias and display its error if it is
2096 if getattr(entry[0], 'badalias', False):
2098 if getattr(entry[0], 'badalias', False):
2097 if not unknowncmd:
2099 if not unknowncmd:
2098 entry[0](ui)
2100 entry[0](ui)
2099 return
2101 return
2100
2102
2101 # synopsis
2103 # synopsis
2102 if len(entry) > 2:
2104 if len(entry) > 2:
2103 if entry[2].startswith('hg'):
2105 if entry[2].startswith('hg'):
2104 ui.write("%s\n" % entry[2])
2106 ui.write("%s\n" % entry[2])
2105 else:
2107 else:
2106 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
2108 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
2107 else:
2109 else:
2108 ui.write('hg %s\n' % aliases[0])
2110 ui.write('hg %s\n' % aliases[0])
2109
2111
2110 # aliases
2112 # aliases
2111 if not ui.quiet and len(aliases) > 1:
2113 if full and not ui.quiet and len(aliases) > 1:
2112 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
2114 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
2113
2115
2114 # description
2116 # description
2115 doc = gettext(entry[0].__doc__)
2117 doc = gettext(entry[0].__doc__)
2116 if not doc:
2118 if not doc:
2117 doc = _("(no help text available)")
2119 doc = _("(no help text available)")
2118 if hasattr(entry[0], 'definition'): # aliased command
2120 if hasattr(entry[0], 'definition'): # aliased command
2119 if entry[0].definition.startswith('!'): # shell alias
2121 if entry[0].definition.startswith('!'): # shell alias
2120 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
2122 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
2121 else:
2123 else:
2122 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
2124 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
2123 if ui.quiet:
2125 if ui.quiet or not full:
2124 doc = doc.splitlines()[0]
2126 doc = doc.splitlines()[0]
2125 keep = ui.verbose and ['verbose'] or []
2127 keep = ui.verbose and ['verbose'] or []
2126 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
2128 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
2127 ui.write("\n%s\n" % formatted)
2129 ui.write("\n%s\n" % formatted)
2128 if pruned:
2130 if pruned:
2129 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
2131 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
2130
2132
2131 if not ui.quiet:
2133 if not ui.quiet:
2132 # options
2134 # options
2133 if entry[1]:
2135 if entry[1]:
2134 option_lists.append((_("options:\n"), entry[1]))
2136 option_lists.append((_("options:\n"), entry[1]))
2135
2137
2136 addglobalopts(False)
2138 addglobalopts(False)
2137
2139
2138 def helplist(header, select=None):
2140 def helplist(header, select=None):
2139 h = {}
2141 h = {}
2140 cmds = {}
2142 cmds = {}
2141 for c, e in table.iteritems():
2143 for c, e in table.iteritems():
2142 f = c.split("|", 1)[0]
2144 f = c.split("|", 1)[0]
2143 if select and not select(f):
2145 if select and not select(f):
2144 continue
2146 continue
2145 if (not select and name != 'shortlist' and
2147 if (not select and name != 'shortlist' and
2146 e[0].__module__ != __name__):
2148 e[0].__module__ != __name__):
2147 continue
2149 continue
2148 if name == "shortlist" and not f.startswith("^"):
2150 if name == "shortlist" and not f.startswith("^"):
2149 continue
2151 continue
2150 f = f.lstrip("^")
2152 f = f.lstrip("^")
2151 if not ui.debugflag and f.startswith("debug"):
2153 if not ui.debugflag and f.startswith("debug"):
2152 continue
2154 continue
2153 doc = e[0].__doc__
2155 doc = e[0].__doc__
2154 if doc and 'DEPRECATED' in doc and not ui.verbose:
2156 if doc and 'DEPRECATED' in doc and not ui.verbose:
2155 continue
2157 continue
2156 doc = gettext(doc)
2158 doc = gettext(doc)
2157 if not doc:
2159 if not doc:
2158 doc = _("(no help text available)")
2160 doc = _("(no help text available)")
2159 h[f] = doc.splitlines()[0].rstrip()
2161 h[f] = doc.splitlines()[0].rstrip()
2160 cmds[f] = c.lstrip("^")
2162 cmds[f] = c.lstrip("^")
2161
2163
2162 if not h:
2164 if not h:
2163 ui.status(_('no commands defined\n'))
2165 ui.status(_('no commands defined\n'))
2164 return
2166 return
2165
2167
2166 ui.status(header)
2168 ui.status(header)
2167 fns = sorted(h)
2169 fns = sorted(h)
2168 m = max(map(len, fns))
2170 m = max(map(len, fns))
2169 for f in fns:
2171 for f in fns:
2170 if ui.verbose:
2172 if ui.verbose:
2171 commands = cmds[f].replace("|",", ")
2173 commands = cmds[f].replace("|",", ")
2172 ui.write(" %s:\n %s\n"%(commands, h[f]))
2174 ui.write(" %s:\n %s\n"%(commands, h[f]))
2173 else:
2175 else:
2174 ui.write('%s\n' % (util.wrap(h[f], textwidth,
2176 ui.write('%s\n' % (util.wrap(h[f], textwidth,
2175 initindent=' %-*s ' % (m, f),
2177 initindent=' %-*s ' % (m, f),
2176 hangindent=' ' * (m + 4))))
2178 hangindent=' ' * (m + 4))))
2177
2179
2178 if not ui.quiet:
2180 if not ui.quiet:
2179 addglobalopts(True)
2181 addglobalopts(True)
2180
2182
2181 def helptopic(name):
2183 def helptopic(name):
2182 for names, header, doc in help.helptable:
2184 for names, header, doc in help.helptable:
2183 if name in names:
2185 if name in names:
2184 break
2186 break
2185 else:
2187 else:
2186 raise error.UnknownCommand(name)
2188 raise error.UnknownCommand(name)
2187
2189
2188 # description
2190 # description
2189 if not doc:
2191 if not doc:
2190 doc = _("(no help text available)")
2192 doc = _("(no help text available)")
2191 if hasattr(doc, '__call__'):
2193 if hasattr(doc, '__call__'):
2192 doc = doc()
2194 doc = doc()
2193
2195
2194 ui.write("%s\n\n" % header)
2196 ui.write("%s\n\n" % header)
2195 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
2197 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
2196
2198
2197 def helpext(name):
2199 def helpext(name):
2198 try:
2200 try:
2199 mod = extensions.find(name)
2201 mod = extensions.find(name)
2200 doc = gettext(mod.__doc__) or _('no help text available')
2202 doc = gettext(mod.__doc__) or _('no help text available')
2201 except KeyError:
2203 except KeyError:
2202 mod = None
2204 mod = None
2203 doc = extensions.disabledext(name)
2205 doc = extensions.disabledext(name)
2204 if not doc:
2206 if not doc:
2205 raise error.UnknownCommand(name)
2207 raise error.UnknownCommand(name)
2206
2208
2207 if '\n' not in doc:
2209 if '\n' not in doc:
2208 head, tail = doc, ""
2210 head, tail = doc, ""
2209 else:
2211 else:
2210 head, tail = doc.split('\n', 1)
2212 head, tail = doc.split('\n', 1)
2211 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
2213 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
2212 if tail:
2214 if tail:
2213 ui.write(minirst.format(tail, textwidth))
2215 ui.write(minirst.format(tail, textwidth))
2214 ui.status('\n\n')
2216 ui.status('\n\n')
2215
2217
2216 if mod:
2218 if mod:
2217 try:
2219 try:
2218 ct = mod.cmdtable
2220 ct = mod.cmdtable
2219 except AttributeError:
2221 except AttributeError:
2220 ct = {}
2222 ct = {}
2221 modcmds = set([c.split('|', 1)[0] for c in ct])
2223 modcmds = set([c.split('|', 1)[0] for c in ct])
2222 helplist(_('list of commands:\n\n'), modcmds.__contains__)
2224 helplist(_('list of commands:\n\n'), modcmds.__contains__)
2223 else:
2225 else:
2224 ui.write(_('use "hg help extensions" for information on enabling '
2226 ui.write(_('use "hg help extensions" for information on enabling '
2225 'extensions\n'))
2227 'extensions\n'))
2226
2228
2227 def helpextcmd(name):
2229 def helpextcmd(name):
2228 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
2230 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
2229 doc = gettext(mod.__doc__).splitlines()[0]
2231 doc = gettext(mod.__doc__).splitlines()[0]
2230
2232
2231 msg = help.listexts(_("'%s' is provided by the following "
2233 msg = help.listexts(_("'%s' is provided by the following "
2232 "extension:") % cmd, {ext: doc}, len(ext),
2234 "extension:") % cmd, {ext: doc}, len(ext),
2233 indent=4)
2235 indent=4)
2234 ui.write(minirst.format(msg, textwidth))
2236 ui.write(minirst.format(msg, textwidth))
2235 ui.write('\n\n')
2237 ui.write('\n\n')
2236 ui.write(_('use "hg help extensions" for information on enabling '
2238 ui.write(_('use "hg help extensions" for information on enabling '
2237 'extensions\n'))
2239 'extensions\n'))
2238
2240
2239 help.addtopichook('revsets', revset.makedoc)
2241 help.addtopichook('revsets', revset.makedoc)
2240 help.addtopichook('templates', templatekw.makedoc)
2242 help.addtopichook('templates', templatekw.makedoc)
2241 help.addtopichook('templates', templatefilters.makedoc)
2243 help.addtopichook('templates', templatefilters.makedoc)
2242
2244
2243 if name and name != 'shortlist':
2245 if name and name != 'shortlist':
2244 i = None
2246 i = None
2245 if unknowncmd:
2247 if unknowncmd:
2246 queries = (helpextcmd,)
2248 queries = (helpextcmd,)
2247 else:
2249 else:
2248 queries = (helptopic, helpcmd, helpext, helpextcmd)
2250 queries = (helptopic, helpcmd, helpext, helpextcmd)
2249 for f in queries:
2251 for f in queries:
2250 try:
2252 try:
2251 f(name)
2253 f(name)
2252 i = None
2254 i = None
2253 break
2255 break
2254 except error.UnknownCommand, inst:
2256 except error.UnknownCommand, inst:
2255 i = inst
2257 i = inst
2256 if i:
2258 if i:
2257 raise i
2259 raise i
2258
2260
2259 else:
2261 else:
2260 # program name
2262 # program name
2261 if ui.verbose or with_version:
2263 if ui.verbose or with_version:
2262 version_(ui)
2264 version_(ui)
2263 else:
2265 else:
2264 ui.status(_("Mercurial Distributed SCM\n"))
2266 ui.status(_("Mercurial Distributed SCM\n"))
2265 ui.status('\n')
2267 ui.status('\n')
2266
2268
2267 # list of commands
2269 # list of commands
2268 if name == "shortlist":
2270 if name == "shortlist":
2269 header = _('basic commands:\n\n')
2271 header = _('basic commands:\n\n')
2270 else:
2272 else:
2271 header = _('list of commands:\n\n')
2273 header = _('list of commands:\n\n')
2272
2274
2273 helplist(header)
2275 helplist(header)
2274 if name != 'shortlist':
2276 if name != 'shortlist':
2275 exts, maxlength = extensions.enabled()
2277 exts, maxlength = extensions.enabled()
2276 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2278 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2277 if text:
2279 if text:
2278 ui.write("\n%s\n" % minirst.format(text, textwidth))
2280 ui.write("\n%s\n" % minirst.format(text, textwidth))
2279
2281
2280 # list all option lists
2282 # list all option lists
2281 opt_output = []
2283 opt_output = []
2282 multioccur = False
2284 multioccur = False
2283 for title, options in option_lists:
2285 for title, options in option_lists:
2284 opt_output.append(("\n%s" % title, None))
2286 opt_output.append(("\n%s" % title, None))
2285 for option in options:
2287 for option in options:
2286 if len(option) == 5:
2288 if len(option) == 5:
2287 shortopt, longopt, default, desc, optlabel = option
2289 shortopt, longopt, default, desc, optlabel = option
2288 else:
2290 else:
2289 shortopt, longopt, default, desc = option
2291 shortopt, longopt, default, desc = option
2290 optlabel = _("VALUE") # default label
2292 optlabel = _("VALUE") # default label
2291
2293
2292 if _("DEPRECATED") in desc and not ui.verbose:
2294 if _("DEPRECATED") in desc and not ui.verbose:
2293 continue
2295 continue
2294 if isinstance(default, list):
2296 if isinstance(default, list):
2295 numqualifier = " %s [+]" % optlabel
2297 numqualifier = " %s [+]" % optlabel
2296 multioccur = True
2298 multioccur = True
2297 elif (default is not None) and not isinstance(default, bool):
2299 elif (default is not None) and not isinstance(default, bool):
2298 numqualifier = " %s" % optlabel
2300 numqualifier = " %s" % optlabel
2299 else:
2301 else:
2300 numqualifier = ""
2302 numqualifier = ""
2301 opt_output.append(("%2s%s" %
2303 opt_output.append(("%2s%s" %
2302 (shortopt and "-%s" % shortopt,
2304 (shortopt and "-%s" % shortopt,
2303 longopt and " --%s%s" %
2305 longopt and " --%s%s" %
2304 (longopt, numqualifier)),
2306 (longopt, numqualifier)),
2305 "%s%s" % (desc,
2307 "%s%s" % (desc,
2306 default
2308 default
2307 and _(" (default: %s)") % default
2309 and _(" (default: %s)") % default
2308 or "")))
2310 or "")))
2309 if multioccur:
2311 if multioccur:
2310 msg = _("\n[+] marked option can be specified multiple times")
2312 msg = _("\n[+] marked option can be specified multiple times")
2311 if ui.verbose and name != 'shortlist':
2313 if ui.verbose and name != 'shortlist':
2312 opt_output.append((msg, None))
2314 opt_output.append((msg, None))
2313 else:
2315 else:
2314 opt_output.insert(-1, (msg, None))
2316 opt_output.insert(-1, (msg, None))
2315
2317
2316 if not name:
2318 if not name:
2317 ui.write(_("\nadditional help topics:\n\n"))
2319 ui.write(_("\nadditional help topics:\n\n"))
2318 topics = []
2320 topics = []
2319 for names, header, doc in help.helptable:
2321 for names, header, doc in help.helptable:
2320 topics.append((sorted(names, key=len, reverse=True)[0], header))
2322 topics.append((sorted(names, key=len, reverse=True)[0], header))
2321 topics_len = max([len(s[0]) for s in topics])
2323 topics_len = max([len(s[0]) for s in topics])
2322 for t, desc in topics:
2324 for t, desc in topics:
2323 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2325 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2324
2326
2325 if opt_output:
2327 if opt_output:
2326 colwidth = encoding.colwidth
2328 colwidth = encoding.colwidth
2327 # normalize: (opt or message, desc or None, width of opt)
2329 # normalize: (opt or message, desc or None, width of opt)
2328 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2330 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2329 for opt, desc in opt_output]
2331 for opt, desc in opt_output]
2330 hanging = max([e[2] for e in entries])
2332 hanging = max([e[2] for e in entries])
2331 for opt, desc, width in entries:
2333 for opt, desc, width in entries:
2332 if desc:
2334 if desc:
2333 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2335 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2334 hangindent = ' ' * (hanging + 3)
2336 hangindent = ' ' * (hanging + 3)
2335 ui.write('%s\n' % (util.wrap(desc, textwidth,
2337 ui.write('%s\n' % (util.wrap(desc, textwidth,
2336 initindent=initindent,
2338 initindent=initindent,
2337 hangindent=hangindent)))
2339 hangindent=hangindent)))
2338 else:
2340 else:
2339 ui.write("%s\n" % opt)
2341 ui.write("%s\n" % opt)
2340
2342
2341 def identify(ui, repo, source=None, rev=None,
2343 def identify(ui, repo, source=None, rev=None,
2342 num=None, id=None, branch=None, tags=None, bookmarks=None):
2344 num=None, id=None, branch=None, tags=None, bookmarks=None):
2343 """identify the working copy or specified revision
2345 """identify the working copy or specified revision
2344
2346
2345 With no revision, print a summary of the current state of the
2347 With no revision, print a summary of the current state of the
2346 repository.
2348 repository.
2347
2349
2348 Specifying a path to a repository root or Mercurial bundle will
2350 Specifying a path to a repository root or Mercurial bundle will
2349 cause lookup to operate on that repository/bundle.
2351 cause lookup to operate on that repository/bundle.
2350
2352
2351 This summary identifies the repository state using one or two
2353 This summary identifies the repository state using one or two
2352 parent hash identifiers, followed by a "+" if there are
2354 parent hash identifiers, followed by a "+" if there are
2353 uncommitted changes in the working directory, a list of tags for
2355 uncommitted changes in the working directory, a list of tags for
2354 this revision and a branch name for non-default branches.
2356 this revision and a branch name for non-default branches.
2355
2357
2356 Returns 0 if successful.
2358 Returns 0 if successful.
2357 """
2359 """
2358
2360
2359 if not repo and not source:
2361 if not repo and not source:
2360 raise util.Abort(_("there is no Mercurial repository here "
2362 raise util.Abort(_("there is no Mercurial repository here "
2361 "(.hg not found)"))
2363 "(.hg not found)"))
2362
2364
2363 hexfunc = ui.debugflag and hex or short
2365 hexfunc = ui.debugflag and hex or short
2364 default = not (num or id or branch or tags or bookmarks)
2366 default = not (num or id or branch or tags or bookmarks)
2365 output = []
2367 output = []
2366
2368
2367 revs = []
2369 revs = []
2368 bms = []
2370 bms = []
2369 if source:
2371 if source:
2370 source, branches = hg.parseurl(ui.expandpath(source))
2372 source, branches = hg.parseurl(ui.expandpath(source))
2371 repo = hg.repository(ui, source)
2373 repo = hg.repository(ui, source)
2372 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2374 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2373
2375
2374 if not repo.local():
2376 if not repo.local():
2375 if not rev and revs:
2377 if not rev and revs:
2376 rev = revs[0]
2378 rev = revs[0]
2377 if not rev:
2379 if not rev:
2378 rev = "tip"
2380 rev = "tip"
2379 if num or branch or tags:
2381 if num or branch or tags:
2380 raise util.Abort(
2382 raise util.Abort(
2381 _("can't query remote revision number, branch, or tags"))
2383 _("can't query remote revision number, branch, or tags"))
2382
2384
2383 remoterev = repo.lookup(rev)
2385 remoterev = repo.lookup(rev)
2384 if default or id:
2386 if default or id:
2385 output = [hexfunc(remoterev)]
2387 output = [hexfunc(remoterev)]
2386
2388
2387 if 'bookmarks' in repo.listkeys('namespaces'):
2389 if 'bookmarks' in repo.listkeys('namespaces'):
2388 hexremoterev = hex(remoterev)
2390 hexremoterev = hex(remoterev)
2389 bms = [bm for bm, bmrev in repo.listkeys('bookmarks').iteritems()
2391 bms = [bm for bm, bmrev in repo.listkeys('bookmarks').iteritems()
2390 if bmrev == hexremoterev]
2392 if bmrev == hexremoterev]
2391
2393
2392 elif not rev:
2394 elif not rev:
2393 ctx = repo[None]
2395 ctx = repo[None]
2394 parents = ctx.parents()
2396 parents = ctx.parents()
2395 changed = False
2397 changed = False
2396 if default or id or num:
2398 if default or id or num:
2397 changed = util.any(repo.status())
2399 changed = util.any(repo.status())
2398 if default or id:
2400 if default or id:
2399 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2401 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2400 (changed) and "+" or "")]
2402 (changed) and "+" or "")]
2401 if num:
2403 if num:
2402 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
2404 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
2403 (changed) and "+" or ""))
2405 (changed) and "+" or ""))
2404 else:
2406 else:
2405 ctx = cmdutil.revsingle(repo, rev)
2407 ctx = cmdutil.revsingle(repo, rev)
2406 if default or id:
2408 if default or id:
2407 output = [hexfunc(ctx.node())]
2409 output = [hexfunc(ctx.node())]
2408 if num:
2410 if num:
2409 output.append(str(ctx.rev()))
2411 output.append(str(ctx.rev()))
2410
2412
2411 if repo.local():
2413 if repo.local():
2412 bms = ctx.bookmarks()
2414 bms = ctx.bookmarks()
2413
2415
2414 if repo.local() and default and not ui.quiet:
2416 if repo.local() and default and not ui.quiet:
2415 b = ctx.branch()
2417 b = ctx.branch()
2416 if b != 'default':
2418 if b != 'default':
2417 output.append("(%s)" % b)
2419 output.append("(%s)" % b)
2418
2420
2419 # multiple tags for a single parent separated by '/'
2421 # multiple tags for a single parent separated by '/'
2420 t = "/".join(ctx.tags())
2422 t = "/".join(ctx.tags())
2421 if t:
2423 if t:
2422 output.append(t)
2424 output.append(t)
2423
2425
2424 if default and not ui.quiet:
2426 if default and not ui.quiet:
2425 # multiple bookmarks for a single parent separated by '/'
2427 # multiple bookmarks for a single parent separated by '/'
2426 bm = '/'.join(bms)
2428 bm = '/'.join(bms)
2427 if bm:
2429 if bm:
2428 output.append(bm)
2430 output.append(bm)
2429
2431
2430 if branch:
2432 if branch:
2431 output.append(ctx.branch())
2433 output.append(ctx.branch())
2432
2434
2433 if tags:
2435 if tags:
2434 output.extend(ctx.tags())
2436 output.extend(ctx.tags())
2435
2437
2436 if bookmarks:
2438 if bookmarks:
2437 output.extend(bms)
2439 output.extend(bms)
2438
2440
2439 ui.write("%s\n" % ' '.join(output))
2441 ui.write("%s\n" % ' '.join(output))
2440
2442
2441 def import_(ui, repo, patch1, *patches, **opts):
2443 def import_(ui, repo, patch1, *patches, **opts):
2442 """import an ordered set of patches
2444 """import an ordered set of patches
2443
2445
2444 Import a list of patches and commit them individually (unless
2446 Import a list of patches and commit them individually (unless
2445 --no-commit is specified).
2447 --no-commit is specified).
2446
2448
2447 If there are outstanding changes in the working directory, import
2449 If there are outstanding changes in the working directory, import
2448 will abort unless given the -f/--force flag.
2450 will abort unless given the -f/--force flag.
2449
2451
2450 You can import a patch straight from a mail message. Even patches
2452 You can import a patch straight from a mail message. Even patches
2451 as attachments work (to use the body part, it must have type
2453 as attachments work (to use the body part, it must have type
2452 text/plain or text/x-patch). From and Subject headers of email
2454 text/plain or text/x-patch). From and Subject headers of email
2453 message are used as default committer and commit message. All
2455 message are used as default committer and commit message. All
2454 text/plain body parts before first diff are added to commit
2456 text/plain body parts before first diff are added to commit
2455 message.
2457 message.
2456
2458
2457 If the imported patch was generated by :hg:`export`, user and
2459 If the imported patch was generated by :hg:`export`, user and
2458 description from patch override values from message headers and
2460 description from patch override values from message headers and
2459 body. Values given on command line with -m/--message and -u/--user
2461 body. Values given on command line with -m/--message and -u/--user
2460 override these.
2462 override these.
2461
2463
2462 If --exact is specified, import will set the working directory to
2464 If --exact is specified, import will set the working directory to
2463 the parent of each patch before applying it, and will abort if the
2465 the parent of each patch before applying it, and will abort if the
2464 resulting changeset has a different ID than the one recorded in
2466 resulting changeset has a different ID than the one recorded in
2465 the patch. This may happen due to character set problems or other
2467 the patch. This may happen due to character set problems or other
2466 deficiencies in the text patch format.
2468 deficiencies in the text patch format.
2467
2469
2468 With -s/--similarity, hg will attempt to discover renames and
2470 With -s/--similarity, hg will attempt to discover renames and
2469 copies in the patch in the same way as 'addremove'.
2471 copies in the patch in the same way as 'addremove'.
2470
2472
2471 To read a patch from standard input, use "-" as the patch name. If
2473 To read a patch from standard input, use "-" as the patch name. If
2472 a URL is specified, the patch will be downloaded from it.
2474 a URL is specified, the patch will be downloaded from it.
2473 See :hg:`help dates` for a list of formats valid for -d/--date.
2475 See :hg:`help dates` for a list of formats valid for -d/--date.
2474
2476
2475 Returns 0 on success.
2477 Returns 0 on success.
2476 """
2478 """
2477 patches = (patch1,) + patches
2479 patches = (patch1,) + patches
2478
2480
2479 date = opts.get('date')
2481 date = opts.get('date')
2480 if date:
2482 if date:
2481 opts['date'] = util.parsedate(date)
2483 opts['date'] = util.parsedate(date)
2482
2484
2483 try:
2485 try:
2484 sim = float(opts.get('similarity') or 0)
2486 sim = float(opts.get('similarity') or 0)
2485 except ValueError:
2487 except ValueError:
2486 raise util.Abort(_('similarity must be a number'))
2488 raise util.Abort(_('similarity must be a number'))
2487 if sim < 0 or sim > 100:
2489 if sim < 0 or sim > 100:
2488 raise util.Abort(_('similarity must be between 0 and 100'))
2490 raise util.Abort(_('similarity must be between 0 and 100'))
2489
2491
2490 if opts.get('exact') or not opts.get('force'):
2492 if opts.get('exact') or not opts.get('force'):
2491 cmdutil.bail_if_changed(repo)
2493 cmdutil.bail_if_changed(repo)
2492
2494
2493 d = opts["base"]
2495 d = opts["base"]
2494 strip = opts["strip"]
2496 strip = opts["strip"]
2495 wlock = lock = None
2497 wlock = lock = None
2496 msgs = []
2498 msgs = []
2497
2499
2498 def tryone(ui, hunk):
2500 def tryone(ui, hunk):
2499 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2501 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2500 patch.extract(ui, hunk)
2502 patch.extract(ui, hunk)
2501
2503
2502 if not tmpname:
2504 if not tmpname:
2503 return None
2505 return None
2504 commitid = _('to working directory')
2506 commitid = _('to working directory')
2505
2507
2506 try:
2508 try:
2507 cmdline_message = cmdutil.logmessage(opts)
2509 cmdline_message = cmdutil.logmessage(opts)
2508 if cmdline_message:
2510 if cmdline_message:
2509 # pickup the cmdline msg
2511 # pickup the cmdline msg
2510 message = cmdline_message
2512 message = cmdline_message
2511 elif message:
2513 elif message:
2512 # pickup the patch msg
2514 # pickup the patch msg
2513 message = message.strip()
2515 message = message.strip()
2514 else:
2516 else:
2515 # launch the editor
2517 # launch the editor
2516 message = None
2518 message = None
2517 ui.debug('message:\n%s\n' % message)
2519 ui.debug('message:\n%s\n' % message)
2518
2520
2519 wp = repo.parents()
2521 wp = repo.parents()
2520 if opts.get('exact'):
2522 if opts.get('exact'):
2521 if not nodeid or not p1:
2523 if not nodeid or not p1:
2522 raise util.Abort(_('not a Mercurial patch'))
2524 raise util.Abort(_('not a Mercurial patch'))
2523 p1 = repo.lookup(p1)
2525 p1 = repo.lookup(p1)
2524 p2 = repo.lookup(p2 or hex(nullid))
2526 p2 = repo.lookup(p2 or hex(nullid))
2525
2527
2526 if p1 != wp[0].node():
2528 if p1 != wp[0].node():
2527 hg.clean(repo, p1)
2529 hg.clean(repo, p1)
2528 repo.dirstate.setparents(p1, p2)
2530 repo.dirstate.setparents(p1, p2)
2529 elif p2:
2531 elif p2:
2530 try:
2532 try:
2531 p1 = repo.lookup(p1)
2533 p1 = repo.lookup(p1)
2532 p2 = repo.lookup(p2)
2534 p2 = repo.lookup(p2)
2533 if p1 == wp[0].node():
2535 if p1 == wp[0].node():
2534 repo.dirstate.setparents(p1, p2)
2536 repo.dirstate.setparents(p1, p2)
2535 except error.RepoError:
2537 except error.RepoError:
2536 pass
2538 pass
2537 if opts.get('exact') or opts.get('import_branch'):
2539 if opts.get('exact') or opts.get('import_branch'):
2538 repo.dirstate.setbranch(branch or 'default')
2540 repo.dirstate.setbranch(branch or 'default')
2539
2541
2540 files = {}
2542 files = {}
2541 try:
2543 try:
2542 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2544 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2543 files=files, eolmode=None)
2545 files=files, eolmode=None)
2544 finally:
2546 finally:
2545 files = cmdutil.updatedir(ui, repo, files,
2547 files = cmdutil.updatedir(ui, repo, files,
2546 similarity=sim / 100.0)
2548 similarity=sim / 100.0)
2547 if opts.get('no_commit'):
2549 if opts.get('no_commit'):
2548 if message:
2550 if message:
2549 msgs.append(message)
2551 msgs.append(message)
2550 else:
2552 else:
2551 if opts.get('exact'):
2553 if opts.get('exact'):
2552 m = None
2554 m = None
2553 else:
2555 else:
2554 m = cmdutil.matchfiles(repo, files or [])
2556 m = cmdutil.matchfiles(repo, files or [])
2555 n = repo.commit(message, opts.get('user') or user,
2557 n = repo.commit(message, opts.get('user') or user,
2556 opts.get('date') or date, match=m,
2558 opts.get('date') or date, match=m,
2557 editor=cmdutil.commiteditor)
2559 editor=cmdutil.commiteditor)
2558 if opts.get('exact'):
2560 if opts.get('exact'):
2559 if hex(n) != nodeid:
2561 if hex(n) != nodeid:
2560 repo.rollback()
2562 repo.rollback()
2561 raise util.Abort(_('patch is damaged'
2563 raise util.Abort(_('patch is damaged'
2562 ' or loses information'))
2564 ' or loses information'))
2563 # Force a dirstate write so that the next transaction
2565 # Force a dirstate write so that the next transaction
2564 # backups an up-do-date file.
2566 # backups an up-do-date file.
2565 repo.dirstate.write()
2567 repo.dirstate.write()
2566 if n:
2568 if n:
2567 commitid = short(n)
2569 commitid = short(n)
2568
2570
2569 return commitid
2571 return commitid
2570 finally:
2572 finally:
2571 os.unlink(tmpname)
2573 os.unlink(tmpname)
2572
2574
2573 try:
2575 try:
2574 wlock = repo.wlock()
2576 wlock = repo.wlock()
2575 lock = repo.lock()
2577 lock = repo.lock()
2576 lastcommit = None
2578 lastcommit = None
2577 for p in patches:
2579 for p in patches:
2578 pf = os.path.join(d, p)
2580 pf = os.path.join(d, p)
2579
2581
2580 if pf == '-':
2582 if pf == '-':
2581 ui.status(_("applying patch from stdin\n"))
2583 ui.status(_("applying patch from stdin\n"))
2582 pf = sys.stdin
2584 pf = sys.stdin
2583 else:
2585 else:
2584 ui.status(_("applying %s\n") % p)
2586 ui.status(_("applying %s\n") % p)
2585 pf = url.open(ui, pf)
2587 pf = url.open(ui, pf)
2586
2588
2587 haspatch = False
2589 haspatch = False
2588 for hunk in patch.split(pf):
2590 for hunk in patch.split(pf):
2589 commitid = tryone(ui, hunk)
2591 commitid = tryone(ui, hunk)
2590 if commitid:
2592 if commitid:
2591 haspatch = True
2593 haspatch = True
2592 if lastcommit:
2594 if lastcommit:
2593 ui.status(_('applied %s\n') % lastcommit)
2595 ui.status(_('applied %s\n') % lastcommit)
2594 lastcommit = commitid
2596 lastcommit = commitid
2595
2597
2596 if not haspatch:
2598 if not haspatch:
2597 raise util.Abort(_('no diffs found'))
2599 raise util.Abort(_('no diffs found'))
2598
2600
2599 if msgs:
2601 if msgs:
2600 repo.opener('last-message.txt', 'wb').write('\n* * *\n'.join(msgs))
2602 repo.opener('last-message.txt', 'wb').write('\n* * *\n'.join(msgs))
2601 finally:
2603 finally:
2602 release(lock, wlock)
2604 release(lock, wlock)
2603
2605
2604 def incoming(ui, repo, source="default", **opts):
2606 def incoming(ui, repo, source="default", **opts):
2605 """show new changesets found in source
2607 """show new changesets found in source
2606
2608
2607 Show new changesets found in the specified path/URL or the default
2609 Show new changesets found in the specified path/URL or the default
2608 pull location. These are the changesets that would have been pulled
2610 pull location. These are the changesets that would have been pulled
2609 if a pull at the time you issued this command.
2611 if a pull at the time you issued this command.
2610
2612
2611 For remote repository, using --bundle avoids downloading the
2613 For remote repository, using --bundle avoids downloading the
2612 changesets twice if the incoming is followed by a pull.
2614 changesets twice if the incoming is followed by a pull.
2613
2615
2614 See pull for valid source format details.
2616 See pull for valid source format details.
2615
2617
2616 Returns 0 if there are incoming changes, 1 otherwise.
2618 Returns 0 if there are incoming changes, 1 otherwise.
2617 """
2619 """
2618 if opts.get('bundle') and opts.get('subrepos'):
2620 if opts.get('bundle') and opts.get('subrepos'):
2619 raise util.Abort(_('cannot combine --bundle and --subrepos'))
2621 raise util.Abort(_('cannot combine --bundle and --subrepos'))
2620
2622
2621 if opts.get('bookmarks'):
2623 if opts.get('bookmarks'):
2622 source, branches = hg.parseurl(ui.expandpath(source),
2624 source, branches = hg.parseurl(ui.expandpath(source),
2623 opts.get('branch'))
2625 opts.get('branch'))
2624 other = hg.repository(hg.remoteui(repo, opts), source)
2626 other = hg.repository(hg.remoteui(repo, opts), source)
2625 if 'bookmarks' not in other.listkeys('namespaces'):
2627 if 'bookmarks' not in other.listkeys('namespaces'):
2626 ui.warn(_("remote doesn't support bookmarks\n"))
2628 ui.warn(_("remote doesn't support bookmarks\n"))
2627 return 0
2629 return 0
2628 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2630 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2629 return bookmarks.diff(ui, repo, other)
2631 return bookmarks.diff(ui, repo, other)
2630
2632
2631 ret = hg.incoming(ui, repo, source, opts)
2633 ret = hg.incoming(ui, repo, source, opts)
2632 return ret
2634 return ret
2633
2635
2634 def init(ui, dest=".", **opts):
2636 def init(ui, dest=".", **opts):
2635 """create a new repository in the given directory
2637 """create a new repository in the given directory
2636
2638
2637 Initialize a new repository in the given directory. If the given
2639 Initialize a new repository in the given directory. If the given
2638 directory does not exist, it will be created.
2640 directory does not exist, it will be created.
2639
2641
2640 If no directory is given, the current directory is used.
2642 If no directory is given, the current directory is used.
2641
2643
2642 It is possible to specify an ``ssh://`` URL as the destination.
2644 It is possible to specify an ``ssh://`` URL as the destination.
2643 See :hg:`help urls` for more information.
2645 See :hg:`help urls` for more information.
2644
2646
2645 Returns 0 on success.
2647 Returns 0 on success.
2646 """
2648 """
2647 hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
2649 hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
2648
2650
2649 def locate(ui, repo, *pats, **opts):
2651 def locate(ui, repo, *pats, **opts):
2650 """locate files matching specific patterns
2652 """locate files matching specific patterns
2651
2653
2652 Print files under Mercurial control in the working directory whose
2654 Print files under Mercurial control in the working directory whose
2653 names match the given patterns.
2655 names match the given patterns.
2654
2656
2655 By default, this command searches all directories in the working
2657 By default, this command searches all directories in the working
2656 directory. To search just the current directory and its
2658 directory. To search just the current directory and its
2657 subdirectories, use "--include .".
2659 subdirectories, use "--include .".
2658
2660
2659 If no patterns are given to match, this command prints the names
2661 If no patterns are given to match, this command prints the names
2660 of all files under Mercurial control in the working directory.
2662 of all files under Mercurial control in the working directory.
2661
2663
2662 If you want to feed the output of this command into the "xargs"
2664 If you want to feed the output of this command into the "xargs"
2663 command, use the -0 option to both this command and "xargs". This
2665 command, use the -0 option to both this command and "xargs". This
2664 will avoid the problem of "xargs" treating single filenames that
2666 will avoid the problem of "xargs" treating single filenames that
2665 contain whitespace as multiple filenames.
2667 contain whitespace as multiple filenames.
2666
2668
2667 Returns 0 if a match is found, 1 otherwise.
2669 Returns 0 if a match is found, 1 otherwise.
2668 """
2670 """
2669 end = opts.get('print0') and '\0' or '\n'
2671 end = opts.get('print0') and '\0' or '\n'
2670 rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
2672 rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
2671
2673
2672 ret = 1
2674 ret = 1
2673 m = cmdutil.match(repo, pats, opts, default='relglob')
2675 m = cmdutil.match(repo, pats, opts, default='relglob')
2674 m.bad = lambda x, y: False
2676 m.bad = lambda x, y: False
2675 for abs in repo[rev].walk(m):
2677 for abs in repo[rev].walk(m):
2676 if not rev and abs not in repo.dirstate:
2678 if not rev and abs not in repo.dirstate:
2677 continue
2679 continue
2678 if opts.get('fullpath'):
2680 if opts.get('fullpath'):
2679 ui.write(repo.wjoin(abs), end)
2681 ui.write(repo.wjoin(abs), end)
2680 else:
2682 else:
2681 ui.write(((pats and m.rel(abs)) or abs), end)
2683 ui.write(((pats and m.rel(abs)) or abs), end)
2682 ret = 0
2684 ret = 0
2683
2685
2684 return ret
2686 return ret
2685
2687
2686 def log(ui, repo, *pats, **opts):
2688 def log(ui, repo, *pats, **opts):
2687 """show revision history of entire repository or files
2689 """show revision history of entire repository or files
2688
2690
2689 Print the revision history of the specified files or the entire
2691 Print the revision history of the specified files or the entire
2690 project.
2692 project.
2691
2693
2692 File history is shown without following rename or copy history of
2694 File history is shown without following rename or copy history of
2693 files. Use -f/--follow with a filename to follow history across
2695 files. Use -f/--follow with a filename to follow history across
2694 renames and copies. --follow without a filename will only show
2696 renames and copies. --follow without a filename will only show
2695 ancestors or descendants of the starting revision. --follow-first
2697 ancestors or descendants of the starting revision. --follow-first
2696 only follows the first parent of merge revisions.
2698 only follows the first parent of merge revisions.
2697
2699
2698 If no revision range is specified, the default is ``tip:0`` unless
2700 If no revision range is specified, the default is ``tip:0`` unless
2699 --follow is set, in which case the working directory parent is
2701 --follow is set, in which case the working directory parent is
2700 used as the starting revision. You can specify a revision set for
2702 used as the starting revision. You can specify a revision set for
2701 log, see :hg:`help revsets` for more information.
2703 log, see :hg:`help revsets` for more information.
2702
2704
2703 See :hg:`help dates` for a list of formats valid for -d/--date.
2705 See :hg:`help dates` for a list of formats valid for -d/--date.
2704
2706
2705 By default this command prints revision number and changeset id,
2707 By default this command prints revision number and changeset id,
2706 tags, non-trivial parents, user, date and time, and a summary for
2708 tags, non-trivial parents, user, date and time, and a summary for
2707 each commit. When the -v/--verbose switch is used, the list of
2709 each commit. When the -v/--verbose switch is used, the list of
2708 changed files and full commit message are shown.
2710 changed files and full commit message are shown.
2709
2711
2710 .. note::
2712 .. note::
2711 log -p/--patch may generate unexpected diff output for merge
2713 log -p/--patch may generate unexpected diff output for merge
2712 changesets, as it will only compare the merge changeset against
2714 changesets, as it will only compare the merge changeset against
2713 its first parent. Also, only files different from BOTH parents
2715 its first parent. Also, only files different from BOTH parents
2714 will appear in files:.
2716 will appear in files:.
2715
2717
2716 Returns 0 on success.
2718 Returns 0 on success.
2717 """
2719 """
2718
2720
2719 matchfn = cmdutil.match(repo, pats, opts)
2721 matchfn = cmdutil.match(repo, pats, opts)
2720 limit = cmdutil.loglimit(opts)
2722 limit = cmdutil.loglimit(opts)
2721 count = 0
2723 count = 0
2722
2724
2723 endrev = None
2725 endrev = None
2724 if opts.get('copies') and opts.get('rev'):
2726 if opts.get('copies') and opts.get('rev'):
2725 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2727 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2726
2728
2727 df = False
2729 df = False
2728 if opts["date"]:
2730 if opts["date"]:
2729 df = util.matchdate(opts["date"])
2731 df = util.matchdate(opts["date"])
2730
2732
2731 branches = opts.get('branch', []) + opts.get('only_branch', [])
2733 branches = opts.get('branch', []) + opts.get('only_branch', [])
2732 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2734 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2733
2735
2734 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2736 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2735 def prep(ctx, fns):
2737 def prep(ctx, fns):
2736 rev = ctx.rev()
2738 rev = ctx.rev()
2737 parents = [p for p in repo.changelog.parentrevs(rev)
2739 parents = [p for p in repo.changelog.parentrevs(rev)
2738 if p != nullrev]
2740 if p != nullrev]
2739 if opts.get('no_merges') and len(parents) == 2:
2741 if opts.get('no_merges') and len(parents) == 2:
2740 return
2742 return
2741 if opts.get('only_merges') and len(parents) != 2:
2743 if opts.get('only_merges') and len(parents) != 2:
2742 return
2744 return
2743 if opts.get('branch') and ctx.branch() not in opts['branch']:
2745 if opts.get('branch') and ctx.branch() not in opts['branch']:
2744 return
2746 return
2745 if df and not df(ctx.date()[0]):
2747 if df and not df(ctx.date()[0]):
2746 return
2748 return
2747 if opts['user'] and not [k for k in opts['user']
2749 if opts['user'] and not [k for k in opts['user']
2748 if k.lower() in ctx.user().lower()]:
2750 if k.lower() in ctx.user().lower()]:
2749 return
2751 return
2750 if opts.get('keyword'):
2752 if opts.get('keyword'):
2751 for k in [kw.lower() for kw in opts['keyword']]:
2753 for k in [kw.lower() for kw in opts['keyword']]:
2752 if (k in ctx.user().lower() or
2754 if (k in ctx.user().lower() or
2753 k in ctx.description().lower() or
2755 k in ctx.description().lower() or
2754 k in " ".join(ctx.files()).lower()):
2756 k in " ".join(ctx.files()).lower()):
2755 break
2757 break
2756 else:
2758 else:
2757 return
2759 return
2758
2760
2759 copies = None
2761 copies = None
2760 if opts.get('copies') and rev:
2762 if opts.get('copies') and rev:
2761 copies = []
2763 copies = []
2762 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2764 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2763 for fn in ctx.files():
2765 for fn in ctx.files():
2764 rename = getrenamed(fn, rev)
2766 rename = getrenamed(fn, rev)
2765 if rename:
2767 if rename:
2766 copies.append((fn, rename[0]))
2768 copies.append((fn, rename[0]))
2767
2769
2768 revmatchfn = None
2770 revmatchfn = None
2769 if opts.get('patch') or opts.get('stat'):
2771 if opts.get('patch') or opts.get('stat'):
2770 if opts.get('follow') or opts.get('follow_first'):
2772 if opts.get('follow') or opts.get('follow_first'):
2771 # note: this might be wrong when following through merges
2773 # note: this might be wrong when following through merges
2772 revmatchfn = cmdutil.match(repo, fns, default='path')
2774 revmatchfn = cmdutil.match(repo, fns, default='path')
2773 else:
2775 else:
2774 revmatchfn = matchfn
2776 revmatchfn = matchfn
2775
2777
2776 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2778 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2777
2779
2778 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2780 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2779 if count == limit:
2781 if count == limit:
2780 break
2782 break
2781 if displayer.flush(ctx.rev()):
2783 if displayer.flush(ctx.rev()):
2782 count += 1
2784 count += 1
2783 displayer.close()
2785 displayer.close()
2784
2786
2785 def manifest(ui, repo, node=None, rev=None):
2787 def manifest(ui, repo, node=None, rev=None):
2786 """output the current or given revision of the project manifest
2788 """output the current or given revision of the project manifest
2787
2789
2788 Print a list of version controlled files for the given revision.
2790 Print a list of version controlled files for the given revision.
2789 If no revision is given, the first parent of the working directory
2791 If no revision is given, the first parent of the working directory
2790 is used, or the null revision if no revision is checked out.
2792 is used, or the null revision if no revision is checked out.
2791
2793
2792 With -v, print file permissions, symlink and executable bits.
2794 With -v, print file permissions, symlink and executable bits.
2793 With --debug, print file revision hashes.
2795 With --debug, print file revision hashes.
2794
2796
2795 Returns 0 on success.
2797 Returns 0 on success.
2796 """
2798 """
2797
2799
2798 if rev and node:
2800 if rev and node:
2799 raise util.Abort(_("please specify just one revision"))
2801 raise util.Abort(_("please specify just one revision"))
2800
2802
2801 if not node:
2803 if not node:
2802 node = rev
2804 node = rev
2803
2805
2804 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2806 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2805 ctx = cmdutil.revsingle(repo, node)
2807 ctx = cmdutil.revsingle(repo, node)
2806 for f in ctx:
2808 for f in ctx:
2807 if ui.debugflag:
2809 if ui.debugflag:
2808 ui.write("%40s " % hex(ctx.manifest()[f]))
2810 ui.write("%40s " % hex(ctx.manifest()[f]))
2809 if ui.verbose:
2811 if ui.verbose:
2810 ui.write(decor[ctx.flags(f)])
2812 ui.write(decor[ctx.flags(f)])
2811 ui.write("%s\n" % f)
2813 ui.write("%s\n" % f)
2812
2814
2813 def merge(ui, repo, node=None, **opts):
2815 def merge(ui, repo, node=None, **opts):
2814 """merge working directory with another revision
2816 """merge working directory with another revision
2815
2817
2816 The current working directory is updated with all changes made in
2818 The current working directory is updated with all changes made in
2817 the requested revision since the last common predecessor revision.
2819 the requested revision since the last common predecessor revision.
2818
2820
2819 Files that changed between either parent are marked as changed for
2821 Files that changed between either parent are marked as changed for
2820 the next commit and a commit must be performed before any further
2822 the next commit and a commit must be performed before any further
2821 updates to the repository are allowed. The next commit will have
2823 updates to the repository are allowed. The next commit will have
2822 two parents.
2824 two parents.
2823
2825
2824 ``--tool`` can be used to specify the merge tool used for file
2826 ``--tool`` can be used to specify the merge tool used for file
2825 merges. It overrides the HGMERGE environment variable and your
2827 merges. It overrides the HGMERGE environment variable and your
2826 configuration files. See :hg:`help merge-tools` for options.
2828 configuration files. See :hg:`help merge-tools` for options.
2827
2829
2828 If no revision is specified, the working directory's parent is a
2830 If no revision is specified, the working directory's parent is a
2829 head revision, and the current branch contains exactly one other
2831 head revision, and the current branch contains exactly one other
2830 head, the other head is merged with by default. Otherwise, an
2832 head, the other head is merged with by default. Otherwise, an
2831 explicit revision with which to merge with must be provided.
2833 explicit revision with which to merge with must be provided.
2832
2834
2833 :hg:`resolve` must be used to resolve unresolved files.
2835 :hg:`resolve` must be used to resolve unresolved files.
2834
2836
2835 To undo an uncommitted merge, use :hg:`update --clean .` which
2837 To undo an uncommitted merge, use :hg:`update --clean .` which
2836 will check out a clean copy of the original merge parent, losing
2838 will check out a clean copy of the original merge parent, losing
2837 all changes.
2839 all changes.
2838
2840
2839 Returns 0 on success, 1 if there are unresolved files.
2841 Returns 0 on success, 1 if there are unresolved files.
2840 """
2842 """
2841
2843
2842 if opts.get('rev') and node:
2844 if opts.get('rev') and node:
2843 raise util.Abort(_("please specify just one revision"))
2845 raise util.Abort(_("please specify just one revision"))
2844 if not node:
2846 if not node:
2845 node = opts.get('rev')
2847 node = opts.get('rev')
2846
2848
2847 if not node:
2849 if not node:
2848 branch = repo[None].branch()
2850 branch = repo[None].branch()
2849 bheads = repo.branchheads(branch)
2851 bheads = repo.branchheads(branch)
2850 if len(bheads) > 2:
2852 if len(bheads) > 2:
2851 raise util.Abort(_(
2853 raise util.Abort(_(
2852 'branch \'%s\' has %d heads - '
2854 'branch \'%s\' has %d heads - '
2853 'please merge with an explicit rev\n'
2855 'please merge with an explicit rev\n'
2854 '(run \'hg heads .\' to see heads)')
2856 '(run \'hg heads .\' to see heads)')
2855 % (branch, len(bheads)))
2857 % (branch, len(bheads)))
2856
2858
2857 parent = repo.dirstate.p1()
2859 parent = repo.dirstate.p1()
2858 if len(bheads) == 1:
2860 if len(bheads) == 1:
2859 if len(repo.heads()) > 1:
2861 if len(repo.heads()) > 1:
2860 raise util.Abort(_(
2862 raise util.Abort(_(
2861 'branch \'%s\' has one head - '
2863 'branch \'%s\' has one head - '
2862 'please merge with an explicit rev\n'
2864 'please merge with an explicit rev\n'
2863 '(run \'hg heads\' to see all heads)')
2865 '(run \'hg heads\' to see all heads)')
2864 % branch)
2866 % branch)
2865 msg = _('there is nothing to merge')
2867 msg = _('there is nothing to merge')
2866 if parent != repo.lookup(repo[None].branch()):
2868 if parent != repo.lookup(repo[None].branch()):
2867 msg = _('%s - use "hg update" instead') % msg
2869 msg = _('%s - use "hg update" instead') % msg
2868 raise util.Abort(msg)
2870 raise util.Abort(msg)
2869
2871
2870 if parent not in bheads:
2872 if parent not in bheads:
2871 raise util.Abort(_('working dir not at a head rev - '
2873 raise util.Abort(_('working dir not at a head rev - '
2872 'use "hg update" or merge with an explicit rev'))
2874 'use "hg update" or merge with an explicit rev'))
2873 node = parent == bheads[0] and bheads[-1] or bheads[0]
2875 node = parent == bheads[0] and bheads[-1] or bheads[0]
2874 else:
2876 else:
2875 node = cmdutil.revsingle(repo, node).node()
2877 node = cmdutil.revsingle(repo, node).node()
2876
2878
2877 if opts.get('preview'):
2879 if opts.get('preview'):
2878 # find nodes that are ancestors of p2 but not of p1
2880 # find nodes that are ancestors of p2 but not of p1
2879 p1 = repo.lookup('.')
2881 p1 = repo.lookup('.')
2880 p2 = repo.lookup(node)
2882 p2 = repo.lookup(node)
2881 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2883 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2882
2884
2883 displayer = cmdutil.show_changeset(ui, repo, opts)
2885 displayer = cmdutil.show_changeset(ui, repo, opts)
2884 for node in nodes:
2886 for node in nodes:
2885 displayer.show(repo[node])
2887 displayer.show(repo[node])
2886 displayer.close()
2888 displayer.close()
2887 return 0
2889 return 0
2888
2890
2889 try:
2891 try:
2890 # ui.forcemerge is an internal variable, do not document
2892 # ui.forcemerge is an internal variable, do not document
2891 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2893 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2892 return hg.merge(repo, node, force=opts.get('force'))
2894 return hg.merge(repo, node, force=opts.get('force'))
2893 finally:
2895 finally:
2894 ui.setconfig('ui', 'forcemerge', '')
2896 ui.setconfig('ui', 'forcemerge', '')
2895
2897
2896 def outgoing(ui, repo, dest=None, **opts):
2898 def outgoing(ui, repo, dest=None, **opts):
2897 """show changesets not found in the destination
2899 """show changesets not found in the destination
2898
2900
2899 Show changesets not found in the specified destination repository
2901 Show changesets not found in the specified destination repository
2900 or the default push location. These are the changesets that would
2902 or the default push location. These are the changesets that would
2901 be pushed if a push was requested.
2903 be pushed if a push was requested.
2902
2904
2903 See pull for details of valid destination formats.
2905 See pull for details of valid destination formats.
2904
2906
2905 Returns 0 if there are outgoing changes, 1 otherwise.
2907 Returns 0 if there are outgoing changes, 1 otherwise.
2906 """
2908 """
2907
2909
2908 if opts.get('bookmarks'):
2910 if opts.get('bookmarks'):
2909 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2911 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2910 dest, branches = hg.parseurl(dest, opts.get('branch'))
2912 dest, branches = hg.parseurl(dest, opts.get('branch'))
2911 other = hg.repository(hg.remoteui(repo, opts), dest)
2913 other = hg.repository(hg.remoteui(repo, opts), dest)
2912 if 'bookmarks' not in other.listkeys('namespaces'):
2914 if 'bookmarks' not in other.listkeys('namespaces'):
2913 ui.warn(_("remote doesn't support bookmarks\n"))
2915 ui.warn(_("remote doesn't support bookmarks\n"))
2914 return 0
2916 return 0
2915 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2917 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2916 return bookmarks.diff(ui, other, repo)
2918 return bookmarks.diff(ui, other, repo)
2917
2919
2918 ret = hg.outgoing(ui, repo, dest, opts)
2920 ret = hg.outgoing(ui, repo, dest, opts)
2919 return ret
2921 return ret
2920
2922
2921 def parents(ui, repo, file_=None, **opts):
2923 def parents(ui, repo, file_=None, **opts):
2922 """show the parents of the working directory or revision
2924 """show the parents of the working directory or revision
2923
2925
2924 Print the working directory's parent revisions. If a revision is
2926 Print the working directory's parent revisions. If a revision is
2925 given via -r/--rev, the parent of that revision will be printed.
2927 given via -r/--rev, the parent of that revision will be printed.
2926 If a file argument is given, the revision in which the file was
2928 If a file argument is given, the revision in which the file was
2927 last changed (before the working directory revision or the
2929 last changed (before the working directory revision or the
2928 argument to --rev if given) is printed.
2930 argument to --rev if given) is printed.
2929
2931
2930 Returns 0 on success.
2932 Returns 0 on success.
2931 """
2933 """
2932
2934
2933 ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
2935 ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
2934
2936
2935 if file_:
2937 if file_:
2936 m = cmdutil.match(repo, (file_,), opts)
2938 m = cmdutil.match(repo, (file_,), opts)
2937 if m.anypats() or len(m.files()) != 1:
2939 if m.anypats() or len(m.files()) != 1:
2938 raise util.Abort(_('can only specify an explicit filename'))
2940 raise util.Abort(_('can only specify an explicit filename'))
2939 file_ = m.files()[0]
2941 file_ = m.files()[0]
2940 filenodes = []
2942 filenodes = []
2941 for cp in ctx.parents():
2943 for cp in ctx.parents():
2942 if not cp:
2944 if not cp:
2943 continue
2945 continue
2944 try:
2946 try:
2945 filenodes.append(cp.filenode(file_))
2947 filenodes.append(cp.filenode(file_))
2946 except error.LookupError:
2948 except error.LookupError:
2947 pass
2949 pass
2948 if not filenodes:
2950 if not filenodes:
2949 raise util.Abort(_("'%s' not found in manifest!") % file_)
2951 raise util.Abort(_("'%s' not found in manifest!") % file_)
2950 fl = repo.file(file_)
2952 fl = repo.file(file_)
2951 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2953 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2952 else:
2954 else:
2953 p = [cp.node() for cp in ctx.parents()]
2955 p = [cp.node() for cp in ctx.parents()]
2954
2956
2955 displayer = cmdutil.show_changeset(ui, repo, opts)
2957 displayer = cmdutil.show_changeset(ui, repo, opts)
2956 for n in p:
2958 for n in p:
2957 if n != nullid:
2959 if n != nullid:
2958 displayer.show(repo[n])
2960 displayer.show(repo[n])
2959 displayer.close()
2961 displayer.close()
2960
2962
2961 def paths(ui, repo, search=None):
2963 def paths(ui, repo, search=None):
2962 """show aliases for remote repositories
2964 """show aliases for remote repositories
2963
2965
2964 Show definition of symbolic path name NAME. If no name is given,
2966 Show definition of symbolic path name NAME. If no name is given,
2965 show definition of all available names.
2967 show definition of all available names.
2966
2968
2967 Path names are defined in the [paths] section of your
2969 Path names are defined in the [paths] section of your
2968 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
2970 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
2969 repository, ``.hg/hgrc`` is used, too.
2971 repository, ``.hg/hgrc`` is used, too.
2970
2972
2971 The path names ``default`` and ``default-push`` have a special
2973 The path names ``default`` and ``default-push`` have a special
2972 meaning. When performing a push or pull operation, they are used
2974 meaning. When performing a push or pull operation, they are used
2973 as fallbacks if no location is specified on the command-line.
2975 as fallbacks if no location is specified on the command-line.
2974 When ``default-push`` is set, it will be used for push and
2976 When ``default-push`` is set, it will be used for push and
2975 ``default`` will be used for pull; otherwise ``default`` is used
2977 ``default`` will be used for pull; otherwise ``default`` is used
2976 as the fallback for both. When cloning a repository, the clone
2978 as the fallback for both. When cloning a repository, the clone
2977 source is written as ``default`` in ``.hg/hgrc``. Note that
2979 source is written as ``default`` in ``.hg/hgrc``. Note that
2978 ``default`` and ``default-push`` apply to all inbound (e.g.
2980 ``default`` and ``default-push`` apply to all inbound (e.g.
2979 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2981 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2980 :hg:`bundle`) operations.
2982 :hg:`bundle`) operations.
2981
2983
2982 See :hg:`help urls` for more information.
2984 See :hg:`help urls` for more information.
2983
2985
2984 Returns 0 on success.
2986 Returns 0 on success.
2985 """
2987 """
2986 if search:
2988 if search:
2987 for name, path in ui.configitems("paths"):
2989 for name, path in ui.configitems("paths"):
2988 if name == search:
2990 if name == search:
2989 ui.write("%s\n" % url.hidepassword(path))
2991 ui.write("%s\n" % url.hidepassword(path))
2990 return
2992 return
2991 ui.warn(_("not found!\n"))
2993 ui.warn(_("not found!\n"))
2992 return 1
2994 return 1
2993 else:
2995 else:
2994 for name, path in ui.configitems("paths"):
2996 for name, path in ui.configitems("paths"):
2995 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2997 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2996
2998
2997 def postincoming(ui, repo, modheads, optupdate, checkout):
2999 def postincoming(ui, repo, modheads, optupdate, checkout):
2998 if modheads == 0:
3000 if modheads == 0:
2999 return
3001 return
3000 if optupdate:
3002 if optupdate:
3001 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
3003 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
3002 return hg.update(repo, checkout)
3004 return hg.update(repo, checkout)
3003 else:
3005 else:
3004 ui.status(_("not updating, since new heads added\n"))
3006 ui.status(_("not updating, since new heads added\n"))
3005 if modheads > 1:
3007 if modheads > 1:
3006 currentbranchheads = len(repo.branchheads())
3008 currentbranchheads = len(repo.branchheads())
3007 if currentbranchheads == modheads:
3009 if currentbranchheads == modheads:
3008 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
3010 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
3009 elif currentbranchheads > 1:
3011 elif currentbranchheads > 1:
3010 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
3012 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
3011 else:
3013 else:
3012 ui.status(_("(run 'hg heads' to see heads)\n"))
3014 ui.status(_("(run 'hg heads' to see heads)\n"))
3013 else:
3015 else:
3014 ui.status(_("(run 'hg update' to get a working copy)\n"))
3016 ui.status(_("(run 'hg update' to get a working copy)\n"))
3015
3017
3016 def pull(ui, repo, source="default", **opts):
3018 def pull(ui, repo, source="default", **opts):
3017 """pull changes from the specified source
3019 """pull changes from the specified source
3018
3020
3019 Pull changes from a remote repository to a local one.
3021 Pull changes from a remote repository to a local one.
3020
3022
3021 This finds all changes from the repository at the specified path
3023 This finds all changes from the repository at the specified path
3022 or URL and adds them to a local repository (the current one unless
3024 or URL and adds them to a local repository (the current one unless
3023 -R is specified). By default, this does not update the copy of the
3025 -R is specified). By default, this does not update the copy of the
3024 project in the working directory.
3026 project in the working directory.
3025
3027
3026 Use :hg:`incoming` if you want to see what would have been added
3028 Use :hg:`incoming` if you want to see what would have been added
3027 by a pull at the time you issued this command. If you then decide
3029 by a pull at the time you issued this command. If you then decide
3028 to add those changes to the repository, you should use :hg:`pull
3030 to add those changes to the repository, you should use :hg:`pull
3029 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
3031 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
3030
3032
3031 If SOURCE is omitted, the 'default' path will be used.
3033 If SOURCE is omitted, the 'default' path will be used.
3032 See :hg:`help urls` for more information.
3034 See :hg:`help urls` for more information.
3033
3035
3034 Returns 0 on success, 1 if an update had unresolved files.
3036 Returns 0 on success, 1 if an update had unresolved files.
3035 """
3037 """
3036 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
3038 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
3037 other = hg.repository(hg.remoteui(repo, opts), source)
3039 other = hg.repository(hg.remoteui(repo, opts), source)
3038 ui.status(_('pulling from %s\n') % url.hidepassword(source))
3040 ui.status(_('pulling from %s\n') % url.hidepassword(source))
3039 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3041 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3040
3042
3041 if opts.get('bookmark'):
3043 if opts.get('bookmark'):
3042 if not revs:
3044 if not revs:
3043 revs = []
3045 revs = []
3044 rb = other.listkeys('bookmarks')
3046 rb = other.listkeys('bookmarks')
3045 for b in opts['bookmark']:
3047 for b in opts['bookmark']:
3046 if b not in rb:
3048 if b not in rb:
3047 raise util.Abort(_('remote bookmark %s not found!') % b)
3049 raise util.Abort(_('remote bookmark %s not found!') % b)
3048 revs.append(rb[b])
3050 revs.append(rb[b])
3049
3051
3050 if revs:
3052 if revs:
3051 try:
3053 try:
3052 revs = [other.lookup(rev) for rev in revs]
3054 revs = [other.lookup(rev) for rev in revs]
3053 except error.CapabilityError:
3055 except error.CapabilityError:
3054 err = _("other repository doesn't support revision lookup, "
3056 err = _("other repository doesn't support revision lookup, "
3055 "so a rev cannot be specified.")
3057 "so a rev cannot be specified.")
3056 raise util.Abort(err)
3058 raise util.Abort(err)
3057
3059
3058 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
3060 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
3059 bookmarks.updatefromremote(ui, repo, other)
3061 bookmarks.updatefromremote(ui, repo, other)
3060 if checkout:
3062 if checkout:
3061 checkout = str(repo.changelog.rev(other.lookup(checkout)))
3063 checkout = str(repo.changelog.rev(other.lookup(checkout)))
3062 repo._subtoppath = source
3064 repo._subtoppath = source
3063 try:
3065 try:
3064 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
3066 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
3065
3067
3066 finally:
3068 finally:
3067 del repo._subtoppath
3069 del repo._subtoppath
3068
3070
3069 # update specified bookmarks
3071 # update specified bookmarks
3070 if opts.get('bookmark'):
3072 if opts.get('bookmark'):
3071 for b in opts['bookmark']:
3073 for b in opts['bookmark']:
3072 # explicit pull overrides local bookmark if any
3074 # explicit pull overrides local bookmark if any
3073 ui.status(_("importing bookmark %s\n") % b)
3075 ui.status(_("importing bookmark %s\n") % b)
3074 repo._bookmarks[b] = repo[rb[b]].node()
3076 repo._bookmarks[b] = repo[rb[b]].node()
3075 bookmarks.write(repo)
3077 bookmarks.write(repo)
3076
3078
3077 return ret
3079 return ret
3078
3080
3079 def push(ui, repo, dest=None, **opts):
3081 def push(ui, repo, dest=None, **opts):
3080 """push changes to the specified destination
3082 """push changes to the specified destination
3081
3083
3082 Push changesets from the local repository to the specified
3084 Push changesets from the local repository to the specified
3083 destination.
3085 destination.
3084
3086
3085 This operation is symmetrical to pull: it is identical to a pull
3087 This operation is symmetrical to pull: it is identical to a pull
3086 in the destination repository from the current one.
3088 in the destination repository from the current one.
3087
3089
3088 By default, push will not allow creation of new heads at the
3090 By default, push will not allow creation of new heads at the
3089 destination, since multiple heads would make it unclear which head
3091 destination, since multiple heads would make it unclear which head
3090 to use. In this situation, it is recommended to pull and merge
3092 to use. In this situation, it is recommended to pull and merge
3091 before pushing.
3093 before pushing.
3092
3094
3093 Use --new-branch if you want to allow push to create a new named
3095 Use --new-branch if you want to allow push to create a new named
3094 branch that is not present at the destination. This allows you to
3096 branch that is not present at the destination. This allows you to
3095 only create a new branch without forcing other changes.
3097 only create a new branch without forcing other changes.
3096
3098
3097 Use -f/--force to override the default behavior and push all
3099 Use -f/--force to override the default behavior and push all
3098 changesets on all branches.
3100 changesets on all branches.
3099
3101
3100 If -r/--rev is used, the specified revision and all its ancestors
3102 If -r/--rev is used, the specified revision and all its ancestors
3101 will be pushed to the remote repository.
3103 will be pushed to the remote repository.
3102
3104
3103 Please see :hg:`help urls` for important details about ``ssh://``
3105 Please see :hg:`help urls` for important details about ``ssh://``
3104 URLs. If DESTINATION is omitted, a default path will be used.
3106 URLs. If DESTINATION is omitted, a default path will be used.
3105
3107
3106 Returns 0 if push was successful, 1 if nothing to push.
3108 Returns 0 if push was successful, 1 if nothing to push.
3107 """
3109 """
3108
3110
3109 if opts.get('bookmark'):
3111 if opts.get('bookmark'):
3110 for b in opts['bookmark']:
3112 for b in opts['bookmark']:
3111 # translate -B options to -r so changesets get pushed
3113 # translate -B options to -r so changesets get pushed
3112 if b in repo._bookmarks:
3114 if b in repo._bookmarks:
3113 opts.setdefault('rev', []).append(b)
3115 opts.setdefault('rev', []).append(b)
3114 else:
3116 else:
3115 # if we try to push a deleted bookmark, translate it to null
3117 # if we try to push a deleted bookmark, translate it to null
3116 # this lets simultaneous -r, -b options continue working
3118 # this lets simultaneous -r, -b options continue working
3117 opts.setdefault('rev', []).append("null")
3119 opts.setdefault('rev', []).append("null")
3118
3120
3119 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3121 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3120 dest, branches = hg.parseurl(dest, opts.get('branch'))
3122 dest, branches = hg.parseurl(dest, opts.get('branch'))
3121 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
3123 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
3122 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
3124 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
3123 other = hg.repository(hg.remoteui(repo, opts), dest)
3125 other = hg.repository(hg.remoteui(repo, opts), dest)
3124 if revs:
3126 if revs:
3125 revs = [repo.lookup(rev) for rev in revs]
3127 revs = [repo.lookup(rev) for rev in revs]
3126
3128
3127 repo._subtoppath = dest
3129 repo._subtoppath = dest
3128 try:
3130 try:
3129 # push subrepos depth-first for coherent ordering
3131 # push subrepos depth-first for coherent ordering
3130 c = repo['']
3132 c = repo['']
3131 subs = c.substate # only repos that are committed
3133 subs = c.substate # only repos that are committed
3132 for s in sorted(subs):
3134 for s in sorted(subs):
3133 if not c.sub(s).push(opts.get('force')):
3135 if not c.sub(s).push(opts.get('force')):
3134 return False
3136 return False
3135 finally:
3137 finally:
3136 del repo._subtoppath
3138 del repo._subtoppath
3137 result = repo.push(other, opts.get('force'), revs=revs,
3139 result = repo.push(other, opts.get('force'), revs=revs,
3138 newbranch=opts.get('new_branch'))
3140 newbranch=opts.get('new_branch'))
3139
3141
3140 result = (result == 0)
3142 result = (result == 0)
3141
3143
3142 if opts.get('bookmark'):
3144 if opts.get('bookmark'):
3143 rb = other.listkeys('bookmarks')
3145 rb = other.listkeys('bookmarks')
3144 for b in opts['bookmark']:
3146 for b in opts['bookmark']:
3145 # explicit push overrides remote bookmark if any
3147 # explicit push overrides remote bookmark if any
3146 if b in repo._bookmarks:
3148 if b in repo._bookmarks:
3147 ui.status(_("exporting bookmark %s\n") % b)
3149 ui.status(_("exporting bookmark %s\n") % b)
3148 new = repo[b].hex()
3150 new = repo[b].hex()
3149 elif b in rb:
3151 elif b in rb:
3150 ui.status(_("deleting remote bookmark %s\n") % b)
3152 ui.status(_("deleting remote bookmark %s\n") % b)
3151 new = '' # delete
3153 new = '' # delete
3152 else:
3154 else:
3153 ui.warn(_('bookmark %s does not exist on the local '
3155 ui.warn(_('bookmark %s does not exist on the local '
3154 'or remote repository!\n') % b)
3156 'or remote repository!\n') % b)
3155 return 2
3157 return 2
3156 old = rb.get(b, '')
3158 old = rb.get(b, '')
3157 r = other.pushkey('bookmarks', b, old, new)
3159 r = other.pushkey('bookmarks', b, old, new)
3158 if not r:
3160 if not r:
3159 ui.warn(_('updating bookmark %s failed!\n') % b)
3161 ui.warn(_('updating bookmark %s failed!\n') % b)
3160 if not result:
3162 if not result:
3161 result = 2
3163 result = 2
3162
3164
3163 return result
3165 return result
3164
3166
3165 def recover(ui, repo):
3167 def recover(ui, repo):
3166 """roll back an interrupted transaction
3168 """roll back an interrupted transaction
3167
3169
3168 Recover from an interrupted commit or pull.
3170 Recover from an interrupted commit or pull.
3169
3171
3170 This command tries to fix the repository status after an
3172 This command tries to fix the repository status after an
3171 interrupted operation. It should only be necessary when Mercurial
3173 interrupted operation. It should only be necessary when Mercurial
3172 suggests it.
3174 suggests it.
3173
3175
3174 Returns 0 if successful, 1 if nothing to recover or verify fails.
3176 Returns 0 if successful, 1 if nothing to recover or verify fails.
3175 """
3177 """
3176 if repo.recover():
3178 if repo.recover():
3177 return hg.verify(repo)
3179 return hg.verify(repo)
3178 return 1
3180 return 1
3179
3181
3180 def remove(ui, repo, *pats, **opts):
3182 def remove(ui, repo, *pats, **opts):
3181 """remove the specified files on the next commit
3183 """remove the specified files on the next commit
3182
3184
3183 Schedule the indicated files for removal from the repository.
3185 Schedule the indicated files for removal from the repository.
3184
3186
3185 This only removes files from the current branch, not from the
3187 This only removes files from the current branch, not from the
3186 entire project history. -A/--after can be used to remove only
3188 entire project history. -A/--after can be used to remove only
3187 files that have already been deleted, -f/--force can be used to
3189 files that have already been deleted, -f/--force can be used to
3188 force deletion, and -Af can be used to remove files from the next
3190 force deletion, and -Af can be used to remove files from the next
3189 revision without deleting them from the working directory.
3191 revision without deleting them from the working directory.
3190
3192
3191 The following table details the behavior of remove for different
3193 The following table details the behavior of remove for different
3192 file states (columns) and option combinations (rows). The file
3194 file states (columns) and option combinations (rows). The file
3193 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
3195 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
3194 reported by :hg:`status`). The actions are Warn, Remove (from
3196 reported by :hg:`status`). The actions are Warn, Remove (from
3195 branch) and Delete (from disk)::
3197 branch) and Delete (from disk)::
3196
3198
3197 A C M !
3199 A C M !
3198 none W RD W R
3200 none W RD W R
3199 -f R RD RD R
3201 -f R RD RD R
3200 -A W W W R
3202 -A W W W R
3201 -Af R R R R
3203 -Af R R R R
3202
3204
3203 This command schedules the files to be removed at the next commit.
3205 This command schedules the files to be removed at the next commit.
3204 To undo a remove before that, see :hg:`revert`.
3206 To undo a remove before that, see :hg:`revert`.
3205
3207
3206 Returns 0 on success, 1 if any warnings encountered.
3208 Returns 0 on success, 1 if any warnings encountered.
3207 """
3209 """
3208
3210
3209 ret = 0
3211 ret = 0
3210 after, force = opts.get('after'), opts.get('force')
3212 after, force = opts.get('after'), opts.get('force')
3211 if not pats and not after:
3213 if not pats and not after:
3212 raise util.Abort(_('no files specified'))
3214 raise util.Abort(_('no files specified'))
3213
3215
3214 m = cmdutil.match(repo, pats, opts)
3216 m = cmdutil.match(repo, pats, opts)
3215 s = repo.status(match=m, clean=True)
3217 s = repo.status(match=m, clean=True)
3216 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
3218 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
3217
3219
3218 for f in m.files():
3220 for f in m.files():
3219 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
3221 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
3220 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
3222 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
3221 ret = 1
3223 ret = 1
3222
3224
3223 if force:
3225 if force:
3224 remove, forget = modified + deleted + clean, added
3226 remove, forget = modified + deleted + clean, added
3225 elif after:
3227 elif after:
3226 remove, forget = deleted, []
3228 remove, forget = deleted, []
3227 for f in modified + added + clean:
3229 for f in modified + added + clean:
3228 ui.warn(_('not removing %s: file still exists (use -f'
3230 ui.warn(_('not removing %s: file still exists (use -f'
3229 ' to force removal)\n') % m.rel(f))
3231 ' to force removal)\n') % m.rel(f))
3230 ret = 1
3232 ret = 1
3231 else:
3233 else:
3232 remove, forget = deleted + clean, []
3234 remove, forget = deleted + clean, []
3233 for f in modified:
3235 for f in modified:
3234 ui.warn(_('not removing %s: file is modified (use -f'
3236 ui.warn(_('not removing %s: file is modified (use -f'
3235 ' to force removal)\n') % m.rel(f))
3237 ' to force removal)\n') % m.rel(f))
3236 ret = 1
3238 ret = 1
3237 for f in added:
3239 for f in added:
3238 ui.warn(_('not removing %s: file has been marked for add (use -f'
3240 ui.warn(_('not removing %s: file has been marked for add (use -f'
3239 ' to force removal)\n') % m.rel(f))
3241 ' to force removal)\n') % m.rel(f))
3240 ret = 1
3242 ret = 1
3241
3243
3242 for f in sorted(remove + forget):
3244 for f in sorted(remove + forget):
3243 if ui.verbose or not m.exact(f):
3245 if ui.verbose or not m.exact(f):
3244 ui.status(_('removing %s\n') % m.rel(f))
3246 ui.status(_('removing %s\n') % m.rel(f))
3245
3247
3246 repo[None].forget(forget)
3248 repo[None].forget(forget)
3247 repo[None].remove(remove, unlink=not after)
3249 repo[None].remove(remove, unlink=not after)
3248 return ret
3250 return ret
3249
3251
3250 def rename(ui, repo, *pats, **opts):
3252 def rename(ui, repo, *pats, **opts):
3251 """rename files; equivalent of copy + remove
3253 """rename files; equivalent of copy + remove
3252
3254
3253 Mark dest as copies of sources; mark sources for deletion. If dest
3255 Mark dest as copies of sources; mark sources for deletion. If dest
3254 is a directory, copies are put in that directory. If dest is a
3256 is a directory, copies are put in that directory. If dest is a
3255 file, there can only be one source.
3257 file, there can only be one source.
3256
3258
3257 By default, this command copies the contents of files as they
3259 By default, this command copies the contents of files as they
3258 exist in the working directory. If invoked with -A/--after, the
3260 exist in the working directory. If invoked with -A/--after, the
3259 operation is recorded, but no copying is performed.
3261 operation is recorded, but no copying is performed.
3260
3262
3261 This command takes effect at the next commit. To undo a rename
3263 This command takes effect at the next commit. To undo a rename
3262 before that, see :hg:`revert`.
3264 before that, see :hg:`revert`.
3263
3265
3264 Returns 0 on success, 1 if errors are encountered.
3266 Returns 0 on success, 1 if errors are encountered.
3265 """
3267 """
3266 wlock = repo.wlock(False)
3268 wlock = repo.wlock(False)
3267 try:
3269 try:
3268 return cmdutil.copy(ui, repo, pats, opts, rename=True)
3270 return cmdutil.copy(ui, repo, pats, opts, rename=True)
3269 finally:
3271 finally:
3270 wlock.release()
3272 wlock.release()
3271
3273
3272 def resolve(ui, repo, *pats, **opts):
3274 def resolve(ui, repo, *pats, **opts):
3273 """redo merges or set/view the merge status of files
3275 """redo merges or set/view the merge status of files
3274
3276
3275 Merges with unresolved conflicts are often the result of
3277 Merges with unresolved conflicts are often the result of
3276 non-interactive merging using the ``internal:merge`` configuration
3278 non-interactive merging using the ``internal:merge`` configuration
3277 setting, or a command-line merge tool like ``diff3``. The resolve
3279 setting, or a command-line merge tool like ``diff3``. The resolve
3278 command is used to manage the files involved in a merge, after
3280 command is used to manage the files involved in a merge, after
3279 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
3281 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
3280 working directory must have two parents).
3282 working directory must have two parents).
3281
3283
3282 The resolve command can be used in the following ways:
3284 The resolve command can be used in the following ways:
3283
3285
3284 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
3286 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
3285 files, discarding any previous merge attempts. Re-merging is not
3287 files, discarding any previous merge attempts. Re-merging is not
3286 performed for files already marked as resolved. Use ``--all/-a``
3288 performed for files already marked as resolved. Use ``--all/-a``
3287 to selects all unresolved files. ``--tool`` can be used to specify
3289 to selects all unresolved files. ``--tool`` can be used to specify
3288 the merge tool used for the given files. It overrides the HGMERGE
3290 the merge tool used for the given files. It overrides the HGMERGE
3289 environment variable and your configuration files.
3291 environment variable and your configuration files.
3290
3292
3291 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
3293 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
3292 (e.g. after having manually fixed-up the files). The default is
3294 (e.g. after having manually fixed-up the files). The default is
3293 to mark all unresolved files.
3295 to mark all unresolved files.
3294
3296
3295 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
3297 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
3296 default is to mark all resolved files.
3298 default is to mark all resolved files.
3297
3299
3298 - :hg:`resolve -l`: list files which had or still have conflicts.
3300 - :hg:`resolve -l`: list files which had or still have conflicts.
3299 In the printed list, ``U`` = unresolved and ``R`` = resolved.
3301 In the printed list, ``U`` = unresolved and ``R`` = resolved.
3300
3302
3301 Note that Mercurial will not let you commit files with unresolved
3303 Note that Mercurial will not let you commit files with unresolved
3302 merge conflicts. You must use :hg:`resolve -m ...` before you can
3304 merge conflicts. You must use :hg:`resolve -m ...` before you can
3303 commit after a conflicting merge.
3305 commit after a conflicting merge.
3304
3306
3305 Returns 0 on success, 1 if any files fail a resolve attempt.
3307 Returns 0 on success, 1 if any files fail a resolve attempt.
3306 """
3308 """
3307
3309
3308 all, mark, unmark, show, nostatus = \
3310 all, mark, unmark, show, nostatus = \
3309 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
3311 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
3310
3312
3311 if (show and (mark or unmark)) or (mark and unmark):
3313 if (show and (mark or unmark)) or (mark and unmark):
3312 raise util.Abort(_("too many options specified"))
3314 raise util.Abort(_("too many options specified"))
3313 if pats and all:
3315 if pats and all:
3314 raise util.Abort(_("can't specify --all and patterns"))
3316 raise util.Abort(_("can't specify --all and patterns"))
3315 if not (all or pats or show or mark or unmark):
3317 if not (all or pats or show or mark or unmark):
3316 raise util.Abort(_('no files or directories specified; '
3318 raise util.Abort(_('no files or directories specified; '
3317 'use --all to remerge all files'))
3319 'use --all to remerge all files'))
3318
3320
3319 ms = mergemod.mergestate(repo)
3321 ms = mergemod.mergestate(repo)
3320 m = cmdutil.match(repo, pats, opts)
3322 m = cmdutil.match(repo, pats, opts)
3321 ret = 0
3323 ret = 0
3322
3324
3323 for f in ms:
3325 for f in ms:
3324 if m(f):
3326 if m(f):
3325 if show:
3327 if show:
3326 if nostatus:
3328 if nostatus:
3327 ui.write("%s\n" % f)
3329 ui.write("%s\n" % f)
3328 else:
3330 else:
3329 ui.write("%s %s\n" % (ms[f].upper(), f),
3331 ui.write("%s %s\n" % (ms[f].upper(), f),
3330 label='resolve.' +
3332 label='resolve.' +
3331 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3333 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3332 elif mark:
3334 elif mark:
3333 ms.mark(f, "r")
3335 ms.mark(f, "r")
3334 elif unmark:
3336 elif unmark:
3335 ms.mark(f, "u")
3337 ms.mark(f, "u")
3336 else:
3338 else:
3337 wctx = repo[None]
3339 wctx = repo[None]
3338 mctx = wctx.parents()[-1]
3340 mctx = wctx.parents()[-1]
3339
3341
3340 # backup pre-resolve (merge uses .orig for its own purposes)
3342 # backup pre-resolve (merge uses .orig for its own purposes)
3341 a = repo.wjoin(f)
3343 a = repo.wjoin(f)
3342 util.copyfile(a, a + ".resolve")
3344 util.copyfile(a, a + ".resolve")
3343
3345
3344 try:
3346 try:
3345 # resolve file
3347 # resolve file
3346 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3348 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3347 if ms.resolve(f, wctx, mctx):
3349 if ms.resolve(f, wctx, mctx):
3348 ret = 1
3350 ret = 1
3349 finally:
3351 finally:
3350 ui.setconfig('ui', 'forcemerge', '')
3352 ui.setconfig('ui', 'forcemerge', '')
3351
3353
3352 # replace filemerge's .orig file with our resolve file
3354 # replace filemerge's .orig file with our resolve file
3353 util.rename(a + ".resolve", a + ".orig")
3355 util.rename(a + ".resolve", a + ".orig")
3354
3356
3355 ms.commit()
3357 ms.commit()
3356 return ret
3358 return ret
3357
3359
3358 def revert(ui, repo, *pats, **opts):
3360 def revert(ui, repo, *pats, **opts):
3359 """restore individual files or directories to an earlier state
3361 """restore individual files or directories to an earlier state
3360
3362
3361 .. note::
3363 .. note::
3362 This command is most likely not what you are looking for.
3364 This command is most likely not what you are looking for.
3363 Revert will partially overwrite content in the working
3365 Revert will partially overwrite content in the working
3364 directory without changing the working directory parents. Use
3366 directory without changing the working directory parents. Use
3365 :hg:`update -r rev` to check out earlier revisions, or
3367 :hg:`update -r rev` to check out earlier revisions, or
3366 :hg:`update --clean .` to undo a merge which has added another
3368 :hg:`update --clean .` to undo a merge which has added another
3367 parent.
3369 parent.
3368
3370
3369 With no revision specified, revert the named files or directories
3371 With no revision specified, revert the named files or directories
3370 to the contents they had in the parent of the working directory.
3372 to the contents they had in the parent of the working directory.
3371 This restores the contents of the affected files to an unmodified
3373 This restores the contents of the affected files to an unmodified
3372 state and unschedules adds, removes, copies, and renames. If the
3374 state and unschedules adds, removes, copies, and renames. If the
3373 working directory has two parents, you must explicitly specify a
3375 working directory has two parents, you must explicitly specify a
3374 revision.
3376 revision.
3375
3377
3376 Using the -r/--rev option, revert the given files or directories
3378 Using the -r/--rev option, revert the given files or directories
3377 to their contents as of a specific revision. This can be helpful
3379 to their contents as of a specific revision. This can be helpful
3378 to "roll back" some or all of an earlier change. See :hg:`help
3380 to "roll back" some or all of an earlier change. See :hg:`help
3379 dates` for a list of formats valid for -d/--date.
3381 dates` for a list of formats valid for -d/--date.
3380
3382
3381 Revert modifies the working directory. It does not commit any
3383 Revert modifies the working directory. It does not commit any
3382 changes, or change the parent of the working directory. If you
3384 changes, or change the parent of the working directory. If you
3383 revert to a revision other than the parent of the working
3385 revert to a revision other than the parent of the working
3384 directory, the reverted files will thus appear modified
3386 directory, the reverted files will thus appear modified
3385 afterwards.
3387 afterwards.
3386
3388
3387 If a file has been deleted, it is restored. Files scheduled for
3389 If a file has been deleted, it is restored. Files scheduled for
3388 addition are just unscheduled and left as they are. If the
3390 addition are just unscheduled and left as they are. If the
3389 executable mode of a file was changed, it is reset.
3391 executable mode of a file was changed, it is reset.
3390
3392
3391 If names are given, all files matching the names are reverted.
3393 If names are given, all files matching the names are reverted.
3392 If no arguments are given, no files are reverted.
3394 If no arguments are given, no files are reverted.
3393
3395
3394 Modified files are saved with a .orig suffix before reverting.
3396 Modified files are saved with a .orig suffix before reverting.
3395 To disable these backups, use --no-backup.
3397 To disable these backups, use --no-backup.
3396
3398
3397 Returns 0 on success.
3399 Returns 0 on success.
3398 """
3400 """
3399
3401
3400 if opts.get("date"):
3402 if opts.get("date"):
3401 if opts.get("rev"):
3403 if opts.get("rev"):
3402 raise util.Abort(_("you can't specify a revision and a date"))
3404 raise util.Abort(_("you can't specify a revision and a date"))
3403 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3405 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3404
3406
3405 parent, p2 = repo.dirstate.parents()
3407 parent, p2 = repo.dirstate.parents()
3406 if not opts.get('rev') and p2 != nullid:
3408 if not opts.get('rev') and p2 != nullid:
3407 raise util.Abort(_('uncommitted merge - '
3409 raise util.Abort(_('uncommitted merge - '
3408 'use "hg update", see "hg help revert"'))
3410 'use "hg update", see "hg help revert"'))
3409
3411
3410 if not pats and not opts.get('all'):
3412 if not pats and not opts.get('all'):
3411 raise util.Abort(_('no files or directories specified; '
3413 raise util.Abort(_('no files or directories specified; '
3412 'use --all to revert the whole repo'))
3414 'use --all to revert the whole repo'))
3413
3415
3414 ctx = cmdutil.revsingle(repo, opts.get('rev'))
3416 ctx = cmdutil.revsingle(repo, opts.get('rev'))
3415 node = ctx.node()
3417 node = ctx.node()
3416 mf = ctx.manifest()
3418 mf = ctx.manifest()
3417 if node == parent:
3419 if node == parent:
3418 pmf = mf
3420 pmf = mf
3419 else:
3421 else:
3420 pmf = None
3422 pmf = None
3421
3423
3422 # need all matching names in dirstate and manifest of target rev,
3424 # need all matching names in dirstate and manifest of target rev,
3423 # so have to walk both. do not print errors if files exist in one
3425 # so have to walk both. do not print errors if files exist in one
3424 # but not other.
3426 # but not other.
3425
3427
3426 names = {}
3428 names = {}
3427
3429
3428 wlock = repo.wlock()
3430 wlock = repo.wlock()
3429 try:
3431 try:
3430 # walk dirstate.
3432 # walk dirstate.
3431
3433
3432 m = cmdutil.match(repo, pats, opts)
3434 m = cmdutil.match(repo, pats, opts)
3433 m.bad = lambda x, y: False
3435 m.bad = lambda x, y: False
3434 for abs in repo.walk(m):
3436 for abs in repo.walk(m):
3435 names[abs] = m.rel(abs), m.exact(abs)
3437 names[abs] = m.rel(abs), m.exact(abs)
3436
3438
3437 # walk target manifest.
3439 # walk target manifest.
3438
3440
3439 def badfn(path, msg):
3441 def badfn(path, msg):
3440 if path in names:
3442 if path in names:
3441 return
3443 return
3442 path_ = path + '/'
3444 path_ = path + '/'
3443 for f in names:
3445 for f in names:
3444 if f.startswith(path_):
3446 if f.startswith(path_):
3445 return
3447 return
3446 ui.warn("%s: %s\n" % (m.rel(path), msg))
3448 ui.warn("%s: %s\n" % (m.rel(path), msg))
3447
3449
3448 m = cmdutil.match(repo, pats, opts)
3450 m = cmdutil.match(repo, pats, opts)
3449 m.bad = badfn
3451 m.bad = badfn
3450 for abs in repo[node].walk(m):
3452 for abs in repo[node].walk(m):
3451 if abs not in names:
3453 if abs not in names:
3452 names[abs] = m.rel(abs), m.exact(abs)
3454 names[abs] = m.rel(abs), m.exact(abs)
3453
3455
3454 m = cmdutil.matchfiles(repo, names)
3456 m = cmdutil.matchfiles(repo, names)
3455 changes = repo.status(match=m)[:4]
3457 changes = repo.status(match=m)[:4]
3456 modified, added, removed, deleted = map(set, changes)
3458 modified, added, removed, deleted = map(set, changes)
3457
3459
3458 # if f is a rename, also revert the source
3460 # if f is a rename, also revert the source
3459 cwd = repo.getcwd()
3461 cwd = repo.getcwd()
3460 for f in added:
3462 for f in added:
3461 src = repo.dirstate.copied(f)
3463 src = repo.dirstate.copied(f)
3462 if src and src not in names and repo.dirstate[src] == 'r':
3464 if src and src not in names and repo.dirstate[src] == 'r':
3463 removed.add(src)
3465 removed.add(src)
3464 names[src] = (repo.pathto(src, cwd), True)
3466 names[src] = (repo.pathto(src, cwd), True)
3465
3467
3466 def removeforget(abs):
3468 def removeforget(abs):
3467 if repo.dirstate[abs] == 'a':
3469 if repo.dirstate[abs] == 'a':
3468 return _('forgetting %s\n')
3470 return _('forgetting %s\n')
3469 return _('removing %s\n')
3471 return _('removing %s\n')
3470
3472
3471 revert = ([], _('reverting %s\n'))
3473 revert = ([], _('reverting %s\n'))
3472 add = ([], _('adding %s\n'))
3474 add = ([], _('adding %s\n'))
3473 remove = ([], removeforget)
3475 remove = ([], removeforget)
3474 undelete = ([], _('undeleting %s\n'))
3476 undelete = ([], _('undeleting %s\n'))
3475
3477
3476 disptable = (
3478 disptable = (
3477 # dispatch table:
3479 # dispatch table:
3478 # file state
3480 # file state
3479 # action if in target manifest
3481 # action if in target manifest
3480 # action if not in target manifest
3482 # action if not in target manifest
3481 # make backup if in target manifest
3483 # make backup if in target manifest
3482 # make backup if not in target manifest
3484 # make backup if not in target manifest
3483 (modified, revert, remove, True, True),
3485 (modified, revert, remove, True, True),
3484 (added, revert, remove, True, False),
3486 (added, revert, remove, True, False),
3485 (removed, undelete, None, False, False),
3487 (removed, undelete, None, False, False),
3486 (deleted, revert, remove, False, False),
3488 (deleted, revert, remove, False, False),
3487 )
3489 )
3488
3490
3489 for abs, (rel, exact) in sorted(names.items()):
3491 for abs, (rel, exact) in sorted(names.items()):
3490 mfentry = mf.get(abs)
3492 mfentry = mf.get(abs)
3491 target = repo.wjoin(abs)
3493 target = repo.wjoin(abs)
3492 def handle(xlist, dobackup):
3494 def handle(xlist, dobackup):
3493 xlist[0].append(abs)
3495 xlist[0].append(abs)
3494 if (dobackup and not opts.get('no_backup') and
3496 if (dobackup and not opts.get('no_backup') and
3495 os.path.lexists(target)):
3497 os.path.lexists(target)):
3496 bakname = "%s.orig" % rel
3498 bakname = "%s.orig" % rel
3497 ui.note(_('saving current version of %s as %s\n') %
3499 ui.note(_('saving current version of %s as %s\n') %
3498 (rel, bakname))
3500 (rel, bakname))
3499 if not opts.get('dry_run'):
3501 if not opts.get('dry_run'):
3500 util.rename(target, bakname)
3502 util.rename(target, bakname)
3501 if ui.verbose or not exact:
3503 if ui.verbose or not exact:
3502 msg = xlist[1]
3504 msg = xlist[1]
3503 if not isinstance(msg, basestring):
3505 if not isinstance(msg, basestring):
3504 msg = msg(abs)
3506 msg = msg(abs)
3505 ui.status(msg % rel)
3507 ui.status(msg % rel)
3506 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3508 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3507 if abs not in table:
3509 if abs not in table:
3508 continue
3510 continue
3509 # file has changed in dirstate
3511 # file has changed in dirstate
3510 if mfentry:
3512 if mfentry:
3511 handle(hitlist, backuphit)
3513 handle(hitlist, backuphit)
3512 elif misslist is not None:
3514 elif misslist is not None:
3513 handle(misslist, backupmiss)
3515 handle(misslist, backupmiss)
3514 break
3516 break
3515 else:
3517 else:
3516 if abs not in repo.dirstate:
3518 if abs not in repo.dirstate:
3517 if mfentry:
3519 if mfentry:
3518 handle(add, True)
3520 handle(add, True)
3519 elif exact:
3521 elif exact:
3520 ui.warn(_('file not managed: %s\n') % rel)
3522 ui.warn(_('file not managed: %s\n') % rel)
3521 continue
3523 continue
3522 # file has not changed in dirstate
3524 # file has not changed in dirstate
3523 if node == parent:
3525 if node == parent:
3524 if exact:
3526 if exact:
3525 ui.warn(_('no changes needed to %s\n') % rel)
3527 ui.warn(_('no changes needed to %s\n') % rel)
3526 continue
3528 continue
3527 if pmf is None:
3529 if pmf is None:
3528 # only need parent manifest in this unlikely case,
3530 # only need parent manifest in this unlikely case,
3529 # so do not read by default
3531 # so do not read by default
3530 pmf = repo[parent].manifest()
3532 pmf = repo[parent].manifest()
3531 if abs in pmf:
3533 if abs in pmf:
3532 if mfentry:
3534 if mfentry:
3533 # if version of file is same in parent and target
3535 # if version of file is same in parent and target
3534 # manifests, do nothing
3536 # manifests, do nothing
3535 if (pmf[abs] != mfentry or
3537 if (pmf[abs] != mfentry or
3536 pmf.flags(abs) != mf.flags(abs)):
3538 pmf.flags(abs) != mf.flags(abs)):
3537 handle(revert, False)
3539 handle(revert, False)
3538 else:
3540 else:
3539 handle(remove, False)
3541 handle(remove, False)
3540
3542
3541 if not opts.get('dry_run'):
3543 if not opts.get('dry_run'):
3542 def checkout(f):
3544 def checkout(f):
3543 fc = ctx[f]
3545 fc = ctx[f]
3544 repo.wwrite(f, fc.data(), fc.flags())
3546 repo.wwrite(f, fc.data(), fc.flags())
3545
3547
3546 audit_path = util.path_auditor(repo.root)
3548 audit_path = util.path_auditor(repo.root)
3547 for f in remove[0]:
3549 for f in remove[0]:
3548 if repo.dirstate[f] == 'a':
3550 if repo.dirstate[f] == 'a':
3549 repo.dirstate.forget(f)
3551 repo.dirstate.forget(f)
3550 continue
3552 continue
3551 audit_path(f)
3553 audit_path(f)
3552 try:
3554 try:
3553 util.unlinkpath(repo.wjoin(f))
3555 util.unlinkpath(repo.wjoin(f))
3554 except OSError:
3556 except OSError:
3555 pass
3557 pass
3556 repo.dirstate.remove(f)
3558 repo.dirstate.remove(f)
3557
3559
3558 normal = None
3560 normal = None
3559 if node == parent:
3561 if node == parent:
3560 # We're reverting to our parent. If possible, we'd like status
3562 # We're reverting to our parent. If possible, we'd like status
3561 # to report the file as clean. We have to use normallookup for
3563 # to report the file as clean. We have to use normallookup for
3562 # merges to avoid losing information about merged/dirty files.
3564 # merges to avoid losing information about merged/dirty files.
3563 if p2 != nullid:
3565 if p2 != nullid:
3564 normal = repo.dirstate.normallookup
3566 normal = repo.dirstate.normallookup
3565 else:
3567 else:
3566 normal = repo.dirstate.normal
3568 normal = repo.dirstate.normal
3567 for f in revert[0]:
3569 for f in revert[0]:
3568 checkout(f)
3570 checkout(f)
3569 if normal:
3571 if normal:
3570 normal(f)
3572 normal(f)
3571
3573
3572 for f in add[0]:
3574 for f in add[0]:
3573 checkout(f)
3575 checkout(f)
3574 repo.dirstate.add(f)
3576 repo.dirstate.add(f)
3575
3577
3576 normal = repo.dirstate.normallookup
3578 normal = repo.dirstate.normallookup
3577 if node == parent and p2 == nullid:
3579 if node == parent and p2 == nullid:
3578 normal = repo.dirstate.normal
3580 normal = repo.dirstate.normal
3579 for f in undelete[0]:
3581 for f in undelete[0]:
3580 checkout(f)
3582 checkout(f)
3581 normal(f)
3583 normal(f)
3582
3584
3583 finally:
3585 finally:
3584 wlock.release()
3586 wlock.release()
3585
3587
3586 def rollback(ui, repo, **opts):
3588 def rollback(ui, repo, **opts):
3587 """roll back the last transaction (dangerous)
3589 """roll back the last transaction (dangerous)
3588
3590
3589 This command should be used with care. There is only one level of
3591 This command should be used with care. There is only one level of
3590 rollback, and there is no way to undo a rollback. It will also
3592 rollback, and there is no way to undo a rollback. It will also
3591 restore the dirstate at the time of the last transaction, losing
3593 restore the dirstate at the time of the last transaction, losing
3592 any dirstate changes since that time. This command does not alter
3594 any dirstate changes since that time. This command does not alter
3593 the working directory.
3595 the working directory.
3594
3596
3595 Transactions are used to encapsulate the effects of all commands
3597 Transactions are used to encapsulate the effects of all commands
3596 that create new changesets or propagate existing changesets into a
3598 that create new changesets or propagate existing changesets into a
3597 repository. For example, the following commands are transactional,
3599 repository. For example, the following commands are transactional,
3598 and their effects can be rolled back:
3600 and their effects can be rolled back:
3599
3601
3600 - commit
3602 - commit
3601 - import
3603 - import
3602 - pull
3604 - pull
3603 - push (with this repository as the destination)
3605 - push (with this repository as the destination)
3604 - unbundle
3606 - unbundle
3605
3607
3606 This command is not intended for use on public repositories. Once
3608 This command is not intended for use on public repositories. Once
3607 changes are visible for pull by other users, rolling a transaction
3609 changes are visible for pull by other users, rolling a transaction
3608 back locally is ineffective (someone else may already have pulled
3610 back locally is ineffective (someone else may already have pulled
3609 the changes). Furthermore, a race is possible with readers of the
3611 the changes). Furthermore, a race is possible with readers of the
3610 repository; for example an in-progress pull from the repository
3612 repository; for example an in-progress pull from the repository
3611 may fail if a rollback is performed.
3613 may fail if a rollback is performed.
3612
3614
3613 Returns 0 on success, 1 if no rollback data is available.
3615 Returns 0 on success, 1 if no rollback data is available.
3614 """
3616 """
3615 return repo.rollback(opts.get('dry_run'))
3617 return repo.rollback(opts.get('dry_run'))
3616
3618
3617 def root(ui, repo):
3619 def root(ui, repo):
3618 """print the root (top) of the current working directory
3620 """print the root (top) of the current working directory
3619
3621
3620 Print the root directory of the current repository.
3622 Print the root directory of the current repository.
3621
3623
3622 Returns 0 on success.
3624 Returns 0 on success.
3623 """
3625 """
3624 ui.write(repo.root + "\n")
3626 ui.write(repo.root + "\n")
3625
3627
3626 def serve(ui, repo, **opts):
3628 def serve(ui, repo, **opts):
3627 """start stand-alone webserver
3629 """start stand-alone webserver
3628
3630
3629 Start a local HTTP repository browser and pull server. You can use
3631 Start a local HTTP repository browser and pull server. You can use
3630 this for ad-hoc sharing and browsing of repositories. It is
3632 this for ad-hoc sharing and browsing of repositories. It is
3631 recommended to use a real web server to serve a repository for
3633 recommended to use a real web server to serve a repository for
3632 longer periods of time.
3634 longer periods of time.
3633
3635
3634 Please note that the server does not implement access control.
3636 Please note that the server does not implement access control.
3635 This means that, by default, anybody can read from the server and
3637 This means that, by default, anybody can read from the server and
3636 nobody can write to it by default. Set the ``web.allow_push``
3638 nobody can write to it by default. Set the ``web.allow_push``
3637 option to ``*`` to allow everybody to push to the server. You
3639 option to ``*`` to allow everybody to push to the server. You
3638 should use a real web server if you need to authenticate users.
3640 should use a real web server if you need to authenticate users.
3639
3641
3640 By default, the server logs accesses to stdout and errors to
3642 By default, the server logs accesses to stdout and errors to
3641 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3643 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3642 files.
3644 files.
3643
3645
3644 To have the server choose a free port number to listen on, specify
3646 To have the server choose a free port number to listen on, specify
3645 a port number of 0; in this case, the server will print the port
3647 a port number of 0; in this case, the server will print the port
3646 number it uses.
3648 number it uses.
3647
3649
3648 Returns 0 on success.
3650 Returns 0 on success.
3649 """
3651 """
3650
3652
3651 if opts["stdio"]:
3653 if opts["stdio"]:
3652 if repo is None:
3654 if repo is None:
3653 raise error.RepoError(_("There is no Mercurial repository here"
3655 raise error.RepoError(_("There is no Mercurial repository here"
3654 " (.hg not found)"))
3656 " (.hg not found)"))
3655 s = sshserver.sshserver(ui, repo)
3657 s = sshserver.sshserver(ui, repo)
3656 s.serve_forever()
3658 s.serve_forever()
3657
3659
3658 # this way we can check if something was given in the command-line
3660 # this way we can check if something was given in the command-line
3659 if opts.get('port'):
3661 if opts.get('port'):
3660 opts['port'] = util.getport(opts.get('port'))
3662 opts['port'] = util.getport(opts.get('port'))
3661
3663
3662 baseui = repo and repo.baseui or ui
3664 baseui = repo and repo.baseui or ui
3663 optlist = ("name templates style address port prefix ipv6"
3665 optlist = ("name templates style address port prefix ipv6"
3664 " accesslog errorlog certificate encoding")
3666 " accesslog errorlog certificate encoding")
3665 for o in optlist.split():
3667 for o in optlist.split():
3666 val = opts.get(o, '')
3668 val = opts.get(o, '')
3667 if val in (None, ''): # should check against default options instead
3669 if val in (None, ''): # should check against default options instead
3668 continue
3670 continue
3669 baseui.setconfig("web", o, val)
3671 baseui.setconfig("web", o, val)
3670 if repo and repo.ui != baseui:
3672 if repo and repo.ui != baseui:
3671 repo.ui.setconfig("web", o, val)
3673 repo.ui.setconfig("web", o, val)
3672
3674
3673 o = opts.get('web_conf') or opts.get('webdir_conf')
3675 o = opts.get('web_conf') or opts.get('webdir_conf')
3674 if not o:
3676 if not o:
3675 if not repo:
3677 if not repo:
3676 raise error.RepoError(_("There is no Mercurial repository"
3678 raise error.RepoError(_("There is no Mercurial repository"
3677 " here (.hg not found)"))
3679 " here (.hg not found)"))
3678 o = repo.root
3680 o = repo.root
3679
3681
3680 app = hgweb.hgweb(o, baseui=ui)
3682 app = hgweb.hgweb(o, baseui=ui)
3681
3683
3682 class service(object):
3684 class service(object):
3683 def init(self):
3685 def init(self):
3684 util.set_signal_handler()
3686 util.set_signal_handler()
3685 self.httpd = hgweb.server.create_server(ui, app)
3687 self.httpd = hgweb.server.create_server(ui, app)
3686
3688
3687 if opts['port'] and not ui.verbose:
3689 if opts['port'] and not ui.verbose:
3688 return
3690 return
3689
3691
3690 if self.httpd.prefix:
3692 if self.httpd.prefix:
3691 prefix = self.httpd.prefix.strip('/') + '/'
3693 prefix = self.httpd.prefix.strip('/') + '/'
3692 else:
3694 else:
3693 prefix = ''
3695 prefix = ''
3694
3696
3695 port = ':%d' % self.httpd.port
3697 port = ':%d' % self.httpd.port
3696 if port == ':80':
3698 if port == ':80':
3697 port = ''
3699 port = ''
3698
3700
3699 bindaddr = self.httpd.addr
3701 bindaddr = self.httpd.addr
3700 if bindaddr == '0.0.0.0':
3702 if bindaddr == '0.0.0.0':
3701 bindaddr = '*'
3703 bindaddr = '*'
3702 elif ':' in bindaddr: # IPv6
3704 elif ':' in bindaddr: # IPv6
3703 bindaddr = '[%s]' % bindaddr
3705 bindaddr = '[%s]' % bindaddr
3704
3706
3705 fqaddr = self.httpd.fqaddr
3707 fqaddr = self.httpd.fqaddr
3706 if ':' in fqaddr:
3708 if ':' in fqaddr:
3707 fqaddr = '[%s]' % fqaddr
3709 fqaddr = '[%s]' % fqaddr
3708 if opts['port']:
3710 if opts['port']:
3709 write = ui.status
3711 write = ui.status
3710 else:
3712 else:
3711 write = ui.write
3713 write = ui.write
3712 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3714 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3713 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3715 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3714
3716
3715 def run(self):
3717 def run(self):
3716 self.httpd.serve_forever()
3718 self.httpd.serve_forever()
3717
3719
3718 service = service()
3720 service = service()
3719
3721
3720 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3722 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3721
3723
3722 def status(ui, repo, *pats, **opts):
3724 def status(ui, repo, *pats, **opts):
3723 """show changed files in the working directory
3725 """show changed files in the working directory
3724
3726
3725 Show status of files in the repository. If names are given, only
3727 Show status of files in the repository. If names are given, only
3726 files that match are shown. Files that are clean or ignored or
3728 files that match are shown. Files that are clean or ignored or
3727 the source of a copy/move operation, are not listed unless
3729 the source of a copy/move operation, are not listed unless
3728 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3730 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3729 Unless options described with "show only ..." are given, the
3731 Unless options described with "show only ..." are given, the
3730 options -mardu are used.
3732 options -mardu are used.
3731
3733
3732 Option -q/--quiet hides untracked (unknown and ignored) files
3734 Option -q/--quiet hides untracked (unknown and ignored) files
3733 unless explicitly requested with -u/--unknown or -i/--ignored.
3735 unless explicitly requested with -u/--unknown or -i/--ignored.
3734
3736
3735 .. note::
3737 .. note::
3736 status may appear to disagree with diff if permissions have
3738 status may appear to disagree with diff if permissions have
3737 changed or a merge has occurred. The standard diff format does
3739 changed or a merge has occurred. The standard diff format does
3738 not report permission changes and diff only reports changes
3740 not report permission changes and diff only reports changes
3739 relative to one merge parent.
3741 relative to one merge parent.
3740
3742
3741 If one revision is given, it is used as the base revision.
3743 If one revision is given, it is used as the base revision.
3742 If two revisions are given, the differences between them are
3744 If two revisions are given, the differences between them are
3743 shown. The --change option can also be used as a shortcut to list
3745 shown. The --change option can also be used as a shortcut to list
3744 the changed files of a revision from its first parent.
3746 the changed files of a revision from its first parent.
3745
3747
3746 The codes used to show the status of files are::
3748 The codes used to show the status of files are::
3747
3749
3748 M = modified
3750 M = modified
3749 A = added
3751 A = added
3750 R = removed
3752 R = removed
3751 C = clean
3753 C = clean
3752 ! = missing (deleted by non-hg command, but still tracked)
3754 ! = missing (deleted by non-hg command, but still tracked)
3753 ? = not tracked
3755 ? = not tracked
3754 I = ignored
3756 I = ignored
3755 = origin of the previous file listed as A (added)
3757 = origin of the previous file listed as A (added)
3756
3758
3757 Returns 0 on success.
3759 Returns 0 on success.
3758 """
3760 """
3759
3761
3760 revs = opts.get('rev')
3762 revs = opts.get('rev')
3761 change = opts.get('change')
3763 change = opts.get('change')
3762
3764
3763 if revs and change:
3765 if revs and change:
3764 msg = _('cannot specify --rev and --change at the same time')
3766 msg = _('cannot specify --rev and --change at the same time')
3765 raise util.Abort(msg)
3767 raise util.Abort(msg)
3766 elif change:
3768 elif change:
3767 node2 = repo.lookup(change)
3769 node2 = repo.lookup(change)
3768 node1 = repo[node2].p1().node()
3770 node1 = repo[node2].p1().node()
3769 else:
3771 else:
3770 node1, node2 = cmdutil.revpair(repo, revs)
3772 node1, node2 = cmdutil.revpair(repo, revs)
3771
3773
3772 cwd = (pats and repo.getcwd()) or ''
3774 cwd = (pats and repo.getcwd()) or ''
3773 end = opts.get('print0') and '\0' or '\n'
3775 end = opts.get('print0') and '\0' or '\n'
3774 copy = {}
3776 copy = {}
3775 states = 'modified added removed deleted unknown ignored clean'.split()
3777 states = 'modified added removed deleted unknown ignored clean'.split()
3776 show = [k for k in states if opts.get(k)]
3778 show = [k for k in states if opts.get(k)]
3777 if opts.get('all'):
3779 if opts.get('all'):
3778 show += ui.quiet and (states[:4] + ['clean']) or states
3780 show += ui.quiet and (states[:4] + ['clean']) or states
3779 if not show:
3781 if not show:
3780 show = ui.quiet and states[:4] or states[:5]
3782 show = ui.quiet and states[:4] or states[:5]
3781
3783
3782 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3784 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3783 'ignored' in show, 'clean' in show, 'unknown' in show,
3785 'ignored' in show, 'clean' in show, 'unknown' in show,
3784 opts.get('subrepos'))
3786 opts.get('subrepos'))
3785 changestates = zip(states, 'MAR!?IC', stat)
3787 changestates = zip(states, 'MAR!?IC', stat)
3786
3788
3787 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3789 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3788 ctxn = repo[nullid]
3790 ctxn = repo[nullid]
3789 ctx1 = repo[node1]
3791 ctx1 = repo[node1]
3790 ctx2 = repo[node2]
3792 ctx2 = repo[node2]
3791 added = stat[1]
3793 added = stat[1]
3792 if node2 is None:
3794 if node2 is None:
3793 added = stat[0] + stat[1] # merged?
3795 added = stat[0] + stat[1] # merged?
3794
3796
3795 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3797 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3796 if k in added:
3798 if k in added:
3797 copy[k] = v
3799 copy[k] = v
3798 elif v in added:
3800 elif v in added:
3799 copy[v] = k
3801 copy[v] = k
3800
3802
3801 for state, char, files in changestates:
3803 for state, char, files in changestates:
3802 if state in show:
3804 if state in show:
3803 format = "%s %%s%s" % (char, end)
3805 format = "%s %%s%s" % (char, end)
3804 if opts.get('no_status'):
3806 if opts.get('no_status'):
3805 format = "%%s%s" % end
3807 format = "%%s%s" % end
3806
3808
3807 for f in files:
3809 for f in files:
3808 ui.write(format % repo.pathto(f, cwd),
3810 ui.write(format % repo.pathto(f, cwd),
3809 label='status.' + state)
3811 label='status.' + state)
3810 if f in copy:
3812 if f in copy:
3811 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3813 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3812 label='status.copied')
3814 label='status.copied')
3813
3815
3814 def summary(ui, repo, **opts):
3816 def summary(ui, repo, **opts):
3815 """summarize working directory state
3817 """summarize working directory state
3816
3818
3817 This generates a brief summary of the working directory state,
3819 This generates a brief summary of the working directory state,
3818 including parents, branch, commit status, and available updates.
3820 including parents, branch, commit status, and available updates.
3819
3821
3820 With the --remote option, this will check the default paths for
3822 With the --remote option, this will check the default paths for
3821 incoming and outgoing changes. This can be time-consuming.
3823 incoming and outgoing changes. This can be time-consuming.
3822
3824
3823 Returns 0 on success.
3825 Returns 0 on success.
3824 """
3826 """
3825
3827
3826 ctx = repo[None]
3828 ctx = repo[None]
3827 parents = ctx.parents()
3829 parents = ctx.parents()
3828 pnode = parents[0].node()
3830 pnode = parents[0].node()
3829
3831
3830 for p in parents:
3832 for p in parents:
3831 # label with log.changeset (instead of log.parent) since this
3833 # label with log.changeset (instead of log.parent) since this
3832 # shows a working directory parent *changeset*:
3834 # shows a working directory parent *changeset*:
3833 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3835 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3834 label='log.changeset')
3836 label='log.changeset')
3835 ui.write(' '.join(p.tags()), label='log.tag')
3837 ui.write(' '.join(p.tags()), label='log.tag')
3836 if p.bookmarks():
3838 if p.bookmarks():
3837 ui.write(' ' + ' '.join(p.bookmarks()), label='log.bookmark')
3839 ui.write(' ' + ' '.join(p.bookmarks()), label='log.bookmark')
3838 if p.rev() == -1:
3840 if p.rev() == -1:
3839 if not len(repo):
3841 if not len(repo):
3840 ui.write(_(' (empty repository)'))
3842 ui.write(_(' (empty repository)'))
3841 else:
3843 else:
3842 ui.write(_(' (no revision checked out)'))
3844 ui.write(_(' (no revision checked out)'))
3843 ui.write('\n')
3845 ui.write('\n')
3844 if p.description():
3846 if p.description():
3845 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3847 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3846 label='log.summary')
3848 label='log.summary')
3847
3849
3848 branch = ctx.branch()
3850 branch = ctx.branch()
3849 bheads = repo.branchheads(branch)
3851 bheads = repo.branchheads(branch)
3850 m = _('branch: %s\n') % branch
3852 m = _('branch: %s\n') % branch
3851 if branch != 'default':
3853 if branch != 'default':
3852 ui.write(m, label='log.branch')
3854 ui.write(m, label='log.branch')
3853 else:
3855 else:
3854 ui.status(m, label='log.branch')
3856 ui.status(m, label='log.branch')
3855
3857
3856 st = list(repo.status(unknown=True))[:6]
3858 st = list(repo.status(unknown=True))[:6]
3857
3859
3858 c = repo.dirstate.copies()
3860 c = repo.dirstate.copies()
3859 copied, renamed = [], []
3861 copied, renamed = [], []
3860 for d, s in c.iteritems():
3862 for d, s in c.iteritems():
3861 if s in st[2]:
3863 if s in st[2]:
3862 st[2].remove(s)
3864 st[2].remove(s)
3863 renamed.append(d)
3865 renamed.append(d)
3864 else:
3866 else:
3865 copied.append(d)
3867 copied.append(d)
3866 if d in st[1]:
3868 if d in st[1]:
3867 st[1].remove(d)
3869 st[1].remove(d)
3868 st.insert(3, renamed)
3870 st.insert(3, renamed)
3869 st.insert(4, copied)
3871 st.insert(4, copied)
3870
3872
3871 ms = mergemod.mergestate(repo)
3873 ms = mergemod.mergestate(repo)
3872 st.append([f for f in ms if ms[f] == 'u'])
3874 st.append([f for f in ms if ms[f] == 'u'])
3873
3875
3874 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3876 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3875 st.append(subs)
3877 st.append(subs)
3876
3878
3877 labels = [ui.label(_('%d modified'), 'status.modified'),
3879 labels = [ui.label(_('%d modified'), 'status.modified'),
3878 ui.label(_('%d added'), 'status.added'),
3880 ui.label(_('%d added'), 'status.added'),
3879 ui.label(_('%d removed'), 'status.removed'),
3881 ui.label(_('%d removed'), 'status.removed'),
3880 ui.label(_('%d renamed'), 'status.copied'),
3882 ui.label(_('%d renamed'), 'status.copied'),
3881 ui.label(_('%d copied'), 'status.copied'),
3883 ui.label(_('%d copied'), 'status.copied'),
3882 ui.label(_('%d deleted'), 'status.deleted'),
3884 ui.label(_('%d deleted'), 'status.deleted'),
3883 ui.label(_('%d unknown'), 'status.unknown'),
3885 ui.label(_('%d unknown'), 'status.unknown'),
3884 ui.label(_('%d ignored'), 'status.ignored'),
3886 ui.label(_('%d ignored'), 'status.ignored'),
3885 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3887 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3886 ui.label(_('%d subrepos'), 'status.modified')]
3888 ui.label(_('%d subrepos'), 'status.modified')]
3887 t = []
3889 t = []
3888 for s, l in zip(st, labels):
3890 for s, l in zip(st, labels):
3889 if s:
3891 if s:
3890 t.append(l % len(s))
3892 t.append(l % len(s))
3891
3893
3892 t = ', '.join(t)
3894 t = ', '.join(t)
3893 cleanworkdir = False
3895 cleanworkdir = False
3894
3896
3895 if len(parents) > 1:
3897 if len(parents) > 1:
3896 t += _(' (merge)')
3898 t += _(' (merge)')
3897 elif branch != parents[0].branch():
3899 elif branch != parents[0].branch():
3898 t += _(' (new branch)')
3900 t += _(' (new branch)')
3899 elif (parents[0].extra().get('close') and
3901 elif (parents[0].extra().get('close') and
3900 pnode in repo.branchheads(branch, closed=True)):
3902 pnode in repo.branchheads(branch, closed=True)):
3901 t += _(' (head closed)')
3903 t += _(' (head closed)')
3902 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3904 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3903 t += _(' (clean)')
3905 t += _(' (clean)')
3904 cleanworkdir = True
3906 cleanworkdir = True
3905 elif pnode not in bheads:
3907 elif pnode not in bheads:
3906 t += _(' (new branch head)')
3908 t += _(' (new branch head)')
3907
3909
3908 if cleanworkdir:
3910 if cleanworkdir:
3909 ui.status(_('commit: %s\n') % t.strip())
3911 ui.status(_('commit: %s\n') % t.strip())
3910 else:
3912 else:
3911 ui.write(_('commit: %s\n') % t.strip())
3913 ui.write(_('commit: %s\n') % t.strip())
3912
3914
3913 # all ancestors of branch heads - all ancestors of parent = new csets
3915 # all ancestors of branch heads - all ancestors of parent = new csets
3914 new = [0] * len(repo)
3916 new = [0] * len(repo)
3915 cl = repo.changelog
3917 cl = repo.changelog
3916 for a in [cl.rev(n) for n in bheads]:
3918 for a in [cl.rev(n) for n in bheads]:
3917 new[a] = 1
3919 new[a] = 1
3918 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3920 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3919 new[a] = 1
3921 new[a] = 1
3920 for a in [p.rev() for p in parents]:
3922 for a in [p.rev() for p in parents]:
3921 if a >= 0:
3923 if a >= 0:
3922 new[a] = 0
3924 new[a] = 0
3923 for a in cl.ancestors(*[p.rev() for p in parents]):
3925 for a in cl.ancestors(*[p.rev() for p in parents]):
3924 new[a] = 0
3926 new[a] = 0
3925 new = sum(new)
3927 new = sum(new)
3926
3928
3927 if new == 0:
3929 if new == 0:
3928 ui.status(_('update: (current)\n'))
3930 ui.status(_('update: (current)\n'))
3929 elif pnode not in bheads:
3931 elif pnode not in bheads:
3930 ui.write(_('update: %d new changesets (update)\n') % new)
3932 ui.write(_('update: %d new changesets (update)\n') % new)
3931 else:
3933 else:
3932 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3934 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3933 (new, len(bheads)))
3935 (new, len(bheads)))
3934
3936
3935 if opts.get('remote'):
3937 if opts.get('remote'):
3936 t = []
3938 t = []
3937 source, branches = hg.parseurl(ui.expandpath('default'))
3939 source, branches = hg.parseurl(ui.expandpath('default'))
3938 other = hg.repository(hg.remoteui(repo, {}), source)
3940 other = hg.repository(hg.remoteui(repo, {}), source)
3939 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3941 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3940 ui.debug('comparing with %s\n' % url.hidepassword(source))
3942 ui.debug('comparing with %s\n' % url.hidepassword(source))
3941 repo.ui.pushbuffer()
3943 repo.ui.pushbuffer()
3942 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3944 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3943 repo.ui.popbuffer()
3945 repo.ui.popbuffer()
3944 if incoming:
3946 if incoming:
3945 t.append(_('1 or more incoming'))
3947 t.append(_('1 or more incoming'))
3946
3948
3947 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3949 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3948 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3950 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3949 other = hg.repository(hg.remoteui(repo, {}), dest)
3951 other = hg.repository(hg.remoteui(repo, {}), dest)
3950 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3952 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3951 repo.ui.pushbuffer()
3953 repo.ui.pushbuffer()
3952 o = discovery.findoutgoing(repo, other)
3954 o = discovery.findoutgoing(repo, other)
3953 repo.ui.popbuffer()
3955 repo.ui.popbuffer()
3954 o = repo.changelog.nodesbetween(o, None)[0]
3956 o = repo.changelog.nodesbetween(o, None)[0]
3955 if o:
3957 if o:
3956 t.append(_('%d outgoing') % len(o))
3958 t.append(_('%d outgoing') % len(o))
3957 if 'bookmarks' in other.listkeys('namespaces'):
3959 if 'bookmarks' in other.listkeys('namespaces'):
3958 lmarks = repo.listkeys('bookmarks')
3960 lmarks = repo.listkeys('bookmarks')
3959 rmarks = other.listkeys('bookmarks')
3961 rmarks = other.listkeys('bookmarks')
3960 diff = set(rmarks) - set(lmarks)
3962 diff = set(rmarks) - set(lmarks)
3961 if len(diff) > 0:
3963 if len(diff) > 0:
3962 t.append(_('%d incoming bookmarks') % len(diff))
3964 t.append(_('%d incoming bookmarks') % len(diff))
3963 diff = set(lmarks) - set(rmarks)
3965 diff = set(lmarks) - set(rmarks)
3964 if len(diff) > 0:
3966 if len(diff) > 0:
3965 t.append(_('%d outgoing bookmarks') % len(diff))
3967 t.append(_('%d outgoing bookmarks') % len(diff))
3966
3968
3967 if t:
3969 if t:
3968 ui.write(_('remote: %s\n') % (', '.join(t)))
3970 ui.write(_('remote: %s\n') % (', '.join(t)))
3969 else:
3971 else:
3970 ui.status(_('remote: (synced)\n'))
3972 ui.status(_('remote: (synced)\n'))
3971
3973
3972 def tag(ui, repo, name1, *names, **opts):
3974 def tag(ui, repo, name1, *names, **opts):
3973 """add one or more tags for the current or given revision
3975 """add one or more tags for the current or given revision
3974
3976
3975 Name a particular revision using <name>.
3977 Name a particular revision using <name>.
3976
3978
3977 Tags are used to name particular revisions of the repository and are
3979 Tags are used to name particular revisions of the repository and are
3978 very useful to compare different revisions, to go back to significant
3980 very useful to compare different revisions, to go back to significant
3979 earlier versions or to mark branch points as releases, etc. Changing
3981 earlier versions or to mark branch points as releases, etc. Changing
3980 an existing tag is normally disallowed; use -f/--force to override.
3982 an existing tag is normally disallowed; use -f/--force to override.
3981
3983
3982 If no revision is given, the parent of the working directory is
3984 If no revision is given, the parent of the working directory is
3983 used, or tip if no revision is checked out.
3985 used, or tip if no revision is checked out.
3984
3986
3985 To facilitate version control, distribution, and merging of tags,
3987 To facilitate version control, distribution, and merging of tags,
3986 they are stored as a file named ".hgtags" which is managed similarly
3988 they are stored as a file named ".hgtags" which is managed similarly
3987 to other project files and can be hand-edited if necessary. This
3989 to other project files and can be hand-edited if necessary. This
3988 also means that tagging creates a new commit. The file
3990 also means that tagging creates a new commit. The file
3989 ".hg/localtags" is used for local tags (not shared among
3991 ".hg/localtags" is used for local tags (not shared among
3990 repositories).
3992 repositories).
3991
3993
3992 Tag commits are usually made at the head of a branch. If the parent
3994 Tag commits are usually made at the head of a branch. If the parent
3993 of the working directory is not a branch head, :hg:`tag` aborts; use
3995 of the working directory is not a branch head, :hg:`tag` aborts; use
3994 -f/--force to force the tag commit to be based on a non-head
3996 -f/--force to force the tag commit to be based on a non-head
3995 changeset.
3997 changeset.
3996
3998
3997 See :hg:`help dates` for a list of formats valid for -d/--date.
3999 See :hg:`help dates` for a list of formats valid for -d/--date.
3998
4000
3999 Since tag names have priority over branch names during revision
4001 Since tag names have priority over branch names during revision
4000 lookup, using an existing branch name as a tag name is discouraged.
4002 lookup, using an existing branch name as a tag name is discouraged.
4001
4003
4002 Returns 0 on success.
4004 Returns 0 on success.
4003 """
4005 """
4004
4006
4005 rev_ = "."
4007 rev_ = "."
4006 names = [t.strip() for t in (name1,) + names]
4008 names = [t.strip() for t in (name1,) + names]
4007 if len(names) != len(set(names)):
4009 if len(names) != len(set(names)):
4008 raise util.Abort(_('tag names must be unique'))
4010 raise util.Abort(_('tag names must be unique'))
4009 for n in names:
4011 for n in names:
4010 if n in ['tip', '.', 'null']:
4012 if n in ['tip', '.', 'null']:
4011 raise util.Abort(_('the name \'%s\' is reserved') % n)
4013 raise util.Abort(_('the name \'%s\' is reserved') % n)
4012 if not n:
4014 if not n:
4013 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
4015 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
4014 if opts.get('rev') and opts.get('remove'):
4016 if opts.get('rev') and opts.get('remove'):
4015 raise util.Abort(_("--rev and --remove are incompatible"))
4017 raise util.Abort(_("--rev and --remove are incompatible"))
4016 if opts.get('rev'):
4018 if opts.get('rev'):
4017 rev_ = opts['rev']
4019 rev_ = opts['rev']
4018 message = opts.get('message')
4020 message = opts.get('message')
4019 if opts.get('remove'):
4021 if opts.get('remove'):
4020 expectedtype = opts.get('local') and 'local' or 'global'
4022 expectedtype = opts.get('local') and 'local' or 'global'
4021 for n in names:
4023 for n in names:
4022 if not repo.tagtype(n):
4024 if not repo.tagtype(n):
4023 raise util.Abort(_('tag \'%s\' does not exist') % n)
4025 raise util.Abort(_('tag \'%s\' does not exist') % n)
4024 if repo.tagtype(n) != expectedtype:
4026 if repo.tagtype(n) != expectedtype:
4025 if expectedtype == 'global':
4027 if expectedtype == 'global':
4026 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
4028 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
4027 else:
4029 else:
4028 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
4030 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
4029 rev_ = nullid
4031 rev_ = nullid
4030 if not message:
4032 if not message:
4031 # we don't translate commit messages
4033 # we don't translate commit messages
4032 message = 'Removed tag %s' % ', '.join(names)
4034 message = 'Removed tag %s' % ', '.join(names)
4033 elif not opts.get('force'):
4035 elif not opts.get('force'):
4034 for n in names:
4036 for n in names:
4035 if n in repo.tags():
4037 if n in repo.tags():
4036 raise util.Abort(_('tag \'%s\' already exists '
4038 raise util.Abort(_('tag \'%s\' already exists '
4037 '(use -f to force)') % n)
4039 '(use -f to force)') % n)
4038 if not opts.get('local'):
4040 if not opts.get('local'):
4039 p1, p2 = repo.dirstate.parents()
4041 p1, p2 = repo.dirstate.parents()
4040 if p2 != nullid:
4042 if p2 != nullid:
4041 raise util.Abort(_('uncommitted merge'))
4043 raise util.Abort(_('uncommitted merge'))
4042 bheads = repo.branchheads()
4044 bheads = repo.branchheads()
4043 if not opts.get('force') and bheads and p1 not in bheads:
4045 if not opts.get('force') and bheads and p1 not in bheads:
4044 raise util.Abort(_('not at a branch head (use -f to force)'))
4046 raise util.Abort(_('not at a branch head (use -f to force)'))
4045 r = cmdutil.revsingle(repo, rev_).node()
4047 r = cmdutil.revsingle(repo, rev_).node()
4046
4048
4047 if not message:
4049 if not message:
4048 # we don't translate commit messages
4050 # we don't translate commit messages
4049 message = ('Added tag %s for changeset %s' %
4051 message = ('Added tag %s for changeset %s' %
4050 (', '.join(names), short(r)))
4052 (', '.join(names), short(r)))
4051
4053
4052 date = opts.get('date')
4054 date = opts.get('date')
4053 if date:
4055 if date:
4054 date = util.parsedate(date)
4056 date = util.parsedate(date)
4055
4057
4056 if opts.get('edit'):
4058 if opts.get('edit'):
4057 message = ui.edit(message, ui.username())
4059 message = ui.edit(message, ui.username())
4058
4060
4059 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
4061 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
4060
4062
4061 def tags(ui, repo):
4063 def tags(ui, repo):
4062 """list repository tags
4064 """list repository tags
4063
4065
4064 This lists both regular and local tags. When the -v/--verbose
4066 This lists both regular and local tags. When the -v/--verbose
4065 switch is used, a third column "local" is printed for local tags.
4067 switch is used, a third column "local" is printed for local tags.
4066
4068
4067 Returns 0 on success.
4069 Returns 0 on success.
4068 """
4070 """
4069
4071
4070 hexfunc = ui.debugflag and hex or short
4072 hexfunc = ui.debugflag and hex or short
4071 tagtype = ""
4073 tagtype = ""
4072
4074
4073 for t, n in reversed(repo.tagslist()):
4075 for t, n in reversed(repo.tagslist()):
4074 if ui.quiet:
4076 if ui.quiet:
4075 ui.write("%s\n" % t)
4077 ui.write("%s\n" % t)
4076 continue
4078 continue
4077
4079
4078 hn = hexfunc(n)
4080 hn = hexfunc(n)
4079 r = "%5d:%s" % (repo.changelog.rev(n), hn)
4081 r = "%5d:%s" % (repo.changelog.rev(n), hn)
4080 spaces = " " * (30 - encoding.colwidth(t))
4082 spaces = " " * (30 - encoding.colwidth(t))
4081
4083
4082 if ui.verbose:
4084 if ui.verbose:
4083 if repo.tagtype(t) == 'local':
4085 if repo.tagtype(t) == 'local':
4084 tagtype = " local"
4086 tagtype = " local"
4085 else:
4087 else:
4086 tagtype = ""
4088 tagtype = ""
4087 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
4089 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
4088
4090
4089 def tip(ui, repo, **opts):
4091 def tip(ui, repo, **opts):
4090 """show the tip revision
4092 """show the tip revision
4091
4093
4092 The tip revision (usually just called the tip) is the changeset
4094 The tip revision (usually just called the tip) is the changeset
4093 most recently added to the repository (and therefore the most
4095 most recently added to the repository (and therefore the most
4094 recently changed head).
4096 recently changed head).
4095
4097
4096 If you have just made a commit, that commit will be the tip. If
4098 If you have just made a commit, that commit will be the tip. If
4097 you have just pulled changes from another repository, the tip of
4099 you have just pulled changes from another repository, the tip of
4098 that repository becomes the current tip. The "tip" tag is special
4100 that repository becomes the current tip. The "tip" tag is special
4099 and cannot be renamed or assigned to a different changeset.
4101 and cannot be renamed or assigned to a different changeset.
4100
4102
4101 Returns 0 on success.
4103 Returns 0 on success.
4102 """
4104 """
4103 displayer = cmdutil.show_changeset(ui, repo, opts)
4105 displayer = cmdutil.show_changeset(ui, repo, opts)
4104 displayer.show(repo[len(repo) - 1])
4106 displayer.show(repo[len(repo) - 1])
4105 displayer.close()
4107 displayer.close()
4106
4108
4107 def unbundle(ui, repo, fname1, *fnames, **opts):
4109 def unbundle(ui, repo, fname1, *fnames, **opts):
4108 """apply one or more changegroup files
4110 """apply one or more changegroup files
4109
4111
4110 Apply one or more compressed changegroup files generated by the
4112 Apply one or more compressed changegroup files generated by the
4111 bundle command.
4113 bundle command.
4112
4114
4113 Returns 0 on success, 1 if an update has unresolved files.
4115 Returns 0 on success, 1 if an update has unresolved files.
4114 """
4116 """
4115 fnames = (fname1,) + fnames
4117 fnames = (fname1,) + fnames
4116
4118
4117 lock = repo.lock()
4119 lock = repo.lock()
4118 wc = repo['.']
4120 wc = repo['.']
4119 try:
4121 try:
4120 for fname in fnames:
4122 for fname in fnames:
4121 f = url.open(ui, fname)
4123 f = url.open(ui, fname)
4122 gen = changegroup.readbundle(f, fname)
4124 gen = changegroup.readbundle(f, fname)
4123 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
4125 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
4124 lock=lock)
4126 lock=lock)
4125 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
4127 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
4126 finally:
4128 finally:
4127 lock.release()
4129 lock.release()
4128 return postincoming(ui, repo, modheads, opts.get('update'), None)
4130 return postincoming(ui, repo, modheads, opts.get('update'), None)
4129
4131
4130 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
4132 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
4131 """update working directory (or switch revisions)
4133 """update working directory (or switch revisions)
4132
4134
4133 Update the repository's working directory to the specified
4135 Update the repository's working directory to the specified
4134 changeset. If no changeset is specified, update to the tip of the
4136 changeset. If no changeset is specified, update to the tip of the
4135 current named branch.
4137 current named branch.
4136
4138
4137 If the changeset is not a descendant of the working directory's
4139 If the changeset is not a descendant of the working directory's
4138 parent, the update is aborted. With the -c/--check option, the
4140 parent, the update is aborted. With the -c/--check option, the
4139 working directory is checked for uncommitted changes; if none are
4141 working directory is checked for uncommitted changes; if none are
4140 found, the working directory is updated to the specified
4142 found, the working directory is updated to the specified
4141 changeset.
4143 changeset.
4142
4144
4143 The following rules apply when the working directory contains
4145 The following rules apply when the working directory contains
4144 uncommitted changes:
4146 uncommitted changes:
4145
4147
4146 1. If neither -c/--check nor -C/--clean is specified, and if
4148 1. If neither -c/--check nor -C/--clean is specified, and if
4147 the requested changeset is an ancestor or descendant of
4149 the requested changeset is an ancestor or descendant of
4148 the working directory's parent, the uncommitted changes
4150 the working directory's parent, the uncommitted changes
4149 are merged into the requested changeset and the merged
4151 are merged into the requested changeset and the merged
4150 result is left uncommitted. If the requested changeset is
4152 result is left uncommitted. If the requested changeset is
4151 not an ancestor or descendant (that is, it is on another
4153 not an ancestor or descendant (that is, it is on another
4152 branch), the update is aborted and the uncommitted changes
4154 branch), the update is aborted and the uncommitted changes
4153 are preserved.
4155 are preserved.
4154
4156
4155 2. With the -c/--check option, the update is aborted and the
4157 2. With the -c/--check option, the update is aborted and the
4156 uncommitted changes are preserved.
4158 uncommitted changes are preserved.
4157
4159
4158 3. With the -C/--clean option, uncommitted changes are discarded and
4160 3. With the -C/--clean option, uncommitted changes are discarded and
4159 the working directory is updated to the requested changeset.
4161 the working directory is updated to the requested changeset.
4160
4162
4161 Use null as the changeset to remove the working directory (like
4163 Use null as the changeset to remove the working directory (like
4162 :hg:`clone -U`).
4164 :hg:`clone -U`).
4163
4165
4164 If you want to update just one file to an older changeset, use
4166 If you want to update just one file to an older changeset, use
4165 :hg:`revert`.
4167 :hg:`revert`.
4166
4168
4167 See :hg:`help dates` for a list of formats valid for -d/--date.
4169 See :hg:`help dates` for a list of formats valid for -d/--date.
4168
4170
4169 Returns 0 on success, 1 if there are unresolved files.
4171 Returns 0 on success, 1 if there are unresolved files.
4170 """
4172 """
4171 if rev and node:
4173 if rev and node:
4172 raise util.Abort(_("please specify just one revision"))
4174 raise util.Abort(_("please specify just one revision"))
4173
4175
4174 if rev is None or rev == '':
4176 if rev is None or rev == '':
4175 rev = node
4177 rev = node
4176
4178
4177 # if we defined a bookmark, we have to remember the original bookmark name
4179 # if we defined a bookmark, we have to remember the original bookmark name
4178 brev = rev
4180 brev = rev
4179 rev = cmdutil.revsingle(repo, rev, rev).rev()
4181 rev = cmdutil.revsingle(repo, rev, rev).rev()
4180
4182
4181 if check and clean:
4183 if check and clean:
4182 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
4184 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
4183
4185
4184 if check:
4186 if check:
4185 # we could use dirty() but we can ignore merge and branch trivia
4187 # we could use dirty() but we can ignore merge and branch trivia
4186 c = repo[None]
4188 c = repo[None]
4187 if c.modified() or c.added() or c.removed():
4189 if c.modified() or c.added() or c.removed():
4188 raise util.Abort(_("uncommitted local changes"))
4190 raise util.Abort(_("uncommitted local changes"))
4189
4191
4190 if date:
4192 if date:
4191 if rev:
4193 if rev:
4192 raise util.Abort(_("you can't specify a revision and a date"))
4194 raise util.Abort(_("you can't specify a revision and a date"))
4193 rev = cmdutil.finddate(ui, repo, date)
4195 rev = cmdutil.finddate(ui, repo, date)
4194
4196
4195 if clean or check:
4197 if clean or check:
4196 ret = hg.clean(repo, rev)
4198 ret = hg.clean(repo, rev)
4197 else:
4199 else:
4198 ret = hg.update(repo, rev)
4200 ret = hg.update(repo, rev)
4199
4201
4200 if brev in repo._bookmarks:
4202 if brev in repo._bookmarks:
4201 bookmarks.setcurrent(repo, brev)
4203 bookmarks.setcurrent(repo, brev)
4202
4204
4203 return ret
4205 return ret
4204
4206
4205 def verify(ui, repo):
4207 def verify(ui, repo):
4206 """verify the integrity of the repository
4208 """verify the integrity of the repository
4207
4209
4208 Verify the integrity of the current repository.
4210 Verify the integrity of the current repository.
4209
4211
4210 This will perform an extensive check of the repository's
4212 This will perform an extensive check of the repository's
4211 integrity, validating the hashes and checksums of each entry in
4213 integrity, validating the hashes and checksums of each entry in
4212 the changelog, manifest, and tracked files, as well as the
4214 the changelog, manifest, and tracked files, as well as the
4213 integrity of their crosslinks and indices.
4215 integrity of their crosslinks and indices.
4214
4216
4215 Returns 0 on success, 1 if errors are encountered.
4217 Returns 0 on success, 1 if errors are encountered.
4216 """
4218 """
4217 return hg.verify(repo)
4219 return hg.verify(repo)
4218
4220
4219 def version_(ui):
4221 def version_(ui):
4220 """output version and copyright information"""
4222 """output version and copyright information"""
4221 ui.write(_("Mercurial Distributed SCM (version %s)\n")
4223 ui.write(_("Mercurial Distributed SCM (version %s)\n")
4222 % util.version())
4224 % util.version())
4223 ui.status(_(
4225 ui.status(_(
4224 "(see http://mercurial.selenic.com for more information)\n"
4226 "(see http://mercurial.selenic.com for more information)\n"
4225 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
4227 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
4226 "This is free software; see the source for copying conditions. "
4228 "This is free software; see the source for copying conditions. "
4227 "There is NO\nwarranty; "
4229 "There is NO\nwarranty; "
4228 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
4230 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
4229 ))
4231 ))
4230
4232
4231 # Command options and aliases are listed here, alphabetically
4233 # Command options and aliases are listed here, alphabetically
4232
4234
4233 globalopts = [
4235 globalopts = [
4234 ('R', 'repository', '',
4236 ('R', 'repository', '',
4235 _('repository root directory or name of overlay bundle file'),
4237 _('repository root directory or name of overlay bundle file'),
4236 _('REPO')),
4238 _('REPO')),
4237 ('', 'cwd', '',
4239 ('', 'cwd', '',
4238 _('change working directory'), _('DIR')),
4240 _('change working directory'), _('DIR')),
4239 ('y', 'noninteractive', None,
4241 ('y', 'noninteractive', None,
4240 _('do not prompt, assume \'yes\' for any required answers')),
4242 _('do not prompt, assume \'yes\' for any required answers')),
4241 ('q', 'quiet', None, _('suppress output')),
4243 ('q', 'quiet', None, _('suppress output')),
4242 ('v', 'verbose', None, _('enable additional output')),
4244 ('v', 'verbose', None, _('enable additional output')),
4243 ('', 'config', [],
4245 ('', 'config', [],
4244 _('set/override config option (use \'section.name=value\')'),
4246 _('set/override config option (use \'section.name=value\')'),
4245 _('CONFIG')),
4247 _('CONFIG')),
4246 ('', 'debug', None, _('enable debugging output')),
4248 ('', 'debug', None, _('enable debugging output')),
4247 ('', 'debugger', None, _('start debugger')),
4249 ('', 'debugger', None, _('start debugger')),
4248 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
4250 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
4249 _('ENCODE')),
4251 _('ENCODE')),
4250 ('', 'encodingmode', encoding.encodingmode,
4252 ('', 'encodingmode', encoding.encodingmode,
4251 _('set the charset encoding mode'), _('MODE')),
4253 _('set the charset encoding mode'), _('MODE')),
4252 ('', 'traceback', None, _('always print a traceback on exception')),
4254 ('', 'traceback', None, _('always print a traceback on exception')),
4253 ('', 'time', None, _('time how long the command takes')),
4255 ('', 'time', None, _('time how long the command takes')),
4254 ('', 'profile', None, _('print command execution profile')),
4256 ('', 'profile', None, _('print command execution profile')),
4255 ('', 'version', None, _('output version information and exit')),
4257 ('', 'version', None, _('output version information and exit')),
4256 ('h', 'help', None, _('display help and exit')),
4258 ('h', 'help', None, _('display help and exit')),
4257 ]
4259 ]
4258
4260
4259 dryrunopts = [('n', 'dry-run', None,
4261 dryrunopts = [('n', 'dry-run', None,
4260 _('do not perform actions, just print output'))]
4262 _('do not perform actions, just print output'))]
4261
4263
4262 remoteopts = [
4264 remoteopts = [
4263 ('e', 'ssh', '',
4265 ('e', 'ssh', '',
4264 _('specify ssh command to use'), _('CMD')),
4266 _('specify ssh command to use'), _('CMD')),
4265 ('', 'remotecmd', '',
4267 ('', 'remotecmd', '',
4266 _('specify hg command to run on the remote side'), _('CMD')),
4268 _('specify hg command to run on the remote side'), _('CMD')),
4267 ('', 'insecure', None,
4269 ('', 'insecure', None,
4268 _('do not verify server certificate (ignoring web.cacerts config)')),
4270 _('do not verify server certificate (ignoring web.cacerts config)')),
4269 ]
4271 ]
4270
4272
4271 walkopts = [
4273 walkopts = [
4272 ('I', 'include', [],
4274 ('I', 'include', [],
4273 _('include names matching the given patterns'), _('PATTERN')),
4275 _('include names matching the given patterns'), _('PATTERN')),
4274 ('X', 'exclude', [],
4276 ('X', 'exclude', [],
4275 _('exclude names matching the given patterns'), _('PATTERN')),
4277 _('exclude names matching the given patterns'), _('PATTERN')),
4276 ]
4278 ]
4277
4279
4278 commitopts = [
4280 commitopts = [
4279 ('m', 'message', '',
4281 ('m', 'message', '',
4280 _('use text as commit message'), _('TEXT')),
4282 _('use text as commit message'), _('TEXT')),
4281 ('l', 'logfile', '',
4283 ('l', 'logfile', '',
4282 _('read commit message from file'), _('FILE')),
4284 _('read commit message from file'), _('FILE')),
4283 ]
4285 ]
4284
4286
4285 commitopts2 = [
4287 commitopts2 = [
4286 ('d', 'date', '',
4288 ('d', 'date', '',
4287 _('record datecode as commit date'), _('DATE')),
4289 _('record datecode as commit date'), _('DATE')),
4288 ('u', 'user', '',
4290 ('u', 'user', '',
4289 _('record the specified user as committer'), _('USER')),
4291 _('record the specified user as committer'), _('USER')),
4290 ]
4292 ]
4291
4293
4292 templateopts = [
4294 templateopts = [
4293 ('', 'style', '',
4295 ('', 'style', '',
4294 _('display using template map file'), _('STYLE')),
4296 _('display using template map file'), _('STYLE')),
4295 ('', 'template', '',
4297 ('', 'template', '',
4296 _('display with template'), _('TEMPLATE')),
4298 _('display with template'), _('TEMPLATE')),
4297 ]
4299 ]
4298
4300
4299 logopts = [
4301 logopts = [
4300 ('p', 'patch', None, _('show patch')),
4302 ('p', 'patch', None, _('show patch')),
4301 ('g', 'git', None, _('use git extended diff format')),
4303 ('g', 'git', None, _('use git extended diff format')),
4302 ('l', 'limit', '',
4304 ('l', 'limit', '',
4303 _('limit number of changes displayed'), _('NUM')),
4305 _('limit number of changes displayed'), _('NUM')),
4304 ('M', 'no-merges', None, _('do not show merges')),
4306 ('M', 'no-merges', None, _('do not show merges')),
4305 ('', 'stat', None, _('output diffstat-style summary of changes')),
4307 ('', 'stat', None, _('output diffstat-style summary of changes')),
4306 ] + templateopts
4308 ] + templateopts
4307
4309
4308 diffopts = [
4310 diffopts = [
4309 ('a', 'text', None, _('treat all files as text')),
4311 ('a', 'text', None, _('treat all files as text')),
4310 ('g', 'git', None, _('use git extended diff format')),
4312 ('g', 'git', None, _('use git extended diff format')),
4311 ('', 'nodates', None, _('omit dates from diff headers'))
4313 ('', 'nodates', None, _('omit dates from diff headers'))
4312 ]
4314 ]
4313
4315
4314 diffopts2 = [
4316 diffopts2 = [
4315 ('p', 'show-function', None, _('show which function each change is in')),
4317 ('p', 'show-function', None, _('show which function each change is in')),
4316 ('', 'reverse', None, _('produce a diff that undoes the changes')),
4318 ('', 'reverse', None, _('produce a diff that undoes the changes')),
4317 ('w', 'ignore-all-space', None,
4319 ('w', 'ignore-all-space', None,
4318 _('ignore white space when comparing lines')),
4320 _('ignore white space when comparing lines')),
4319 ('b', 'ignore-space-change', None,
4321 ('b', 'ignore-space-change', None,
4320 _('ignore changes in the amount of white space')),
4322 _('ignore changes in the amount of white space')),
4321 ('B', 'ignore-blank-lines', None,
4323 ('B', 'ignore-blank-lines', None,
4322 _('ignore changes whose lines are all blank')),
4324 _('ignore changes whose lines are all blank')),
4323 ('U', 'unified', '',
4325 ('U', 'unified', '',
4324 _('number of lines of context to show'), _('NUM')),
4326 _('number of lines of context to show'), _('NUM')),
4325 ('', 'stat', None, _('output diffstat-style summary of changes')),
4327 ('', 'stat', None, _('output diffstat-style summary of changes')),
4326 ]
4328 ]
4327
4329
4328 similarityopts = [
4330 similarityopts = [
4329 ('s', 'similarity', '',
4331 ('s', 'similarity', '',
4330 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
4332 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
4331 ]
4333 ]
4332
4334
4333 subrepoopts = [
4335 subrepoopts = [
4334 ('S', 'subrepos', None,
4336 ('S', 'subrepos', None,
4335 _('recurse into subrepositories'))
4337 _('recurse into subrepositories'))
4336 ]
4338 ]
4337
4339
4338 table = {
4340 table = {
4339 "^add": (add, walkopts + subrepoopts + dryrunopts,
4341 "^add": (add, walkopts + subrepoopts + dryrunopts,
4340 _('[OPTION]... [FILE]...')),
4342 _('[OPTION]... [FILE]...')),
4341 "addremove":
4343 "addremove":
4342 (addremove, similarityopts + walkopts + dryrunopts,
4344 (addremove, similarityopts + walkopts + dryrunopts,
4343 _('[OPTION]... [FILE]...')),
4345 _('[OPTION]... [FILE]...')),
4344 "^annotate|blame":
4346 "^annotate|blame":
4345 (annotate,
4347 (annotate,
4346 [('r', 'rev', '',
4348 [('r', 'rev', '',
4347 _('annotate the specified revision'), _('REV')),
4349 _('annotate the specified revision'), _('REV')),
4348 ('', 'follow', None,
4350 ('', 'follow', None,
4349 _('follow copies/renames and list the filename (DEPRECATED)')),
4351 _('follow copies/renames and list the filename (DEPRECATED)')),
4350 ('', 'no-follow', None, _("don't follow copies and renames")),
4352 ('', 'no-follow', None, _("don't follow copies and renames")),
4351 ('a', 'text', None, _('treat all files as text')),
4353 ('a', 'text', None, _('treat all files as text')),
4352 ('u', 'user', None, _('list the author (long with -v)')),
4354 ('u', 'user', None, _('list the author (long with -v)')),
4353 ('f', 'file', None, _('list the filename')),
4355 ('f', 'file', None, _('list the filename')),
4354 ('d', 'date', None, _('list the date (short with -q)')),
4356 ('d', 'date', None, _('list the date (short with -q)')),
4355 ('n', 'number', None, _('list the revision number (default)')),
4357 ('n', 'number', None, _('list the revision number (default)')),
4356 ('c', 'changeset', None, _('list the changeset')),
4358 ('c', 'changeset', None, _('list the changeset')),
4357 ('l', 'line-number', None,
4359 ('l', 'line-number', None,
4358 _('show line number at the first appearance'))
4360 _('show line number at the first appearance'))
4359 ] + walkopts,
4361 ] + walkopts,
4360 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
4362 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
4361 "archive":
4363 "archive":
4362 (archive,
4364 (archive,
4363 [('', 'no-decode', None, _('do not pass files through decoders')),
4365 [('', 'no-decode', None, _('do not pass files through decoders')),
4364 ('p', 'prefix', '',
4366 ('p', 'prefix', '',
4365 _('directory prefix for files in archive'), _('PREFIX')),
4367 _('directory prefix for files in archive'), _('PREFIX')),
4366 ('r', 'rev', '',
4368 ('r', 'rev', '',
4367 _('revision to distribute'), _('REV')),
4369 _('revision to distribute'), _('REV')),
4368 ('t', 'type', '',
4370 ('t', 'type', '',
4369 _('type of distribution to create'), _('TYPE')),
4371 _('type of distribution to create'), _('TYPE')),
4370 ] + subrepoopts + walkopts,
4372 ] + subrepoopts + walkopts,
4371 _('[OPTION]... DEST')),
4373 _('[OPTION]... DEST')),
4372 "backout":
4374 "backout":
4373 (backout,
4375 (backout,
4374 [('', 'merge', None,
4376 [('', 'merge', None,
4375 _('merge with old dirstate parent after backout')),
4377 _('merge with old dirstate parent after backout')),
4376 ('', 'parent', '',
4378 ('', 'parent', '',
4377 _('parent to choose when backing out merge'), _('REV')),
4379 _('parent to choose when backing out merge'), _('REV')),
4378 ('t', 'tool', '',
4380 ('t', 'tool', '',
4379 _('specify merge tool')),
4381 _('specify merge tool')),
4380 ('r', 'rev', '',
4382 ('r', 'rev', '',
4381 _('revision to backout'), _('REV')),
4383 _('revision to backout'), _('REV')),
4382 ] + walkopts + commitopts + commitopts2,
4384 ] + walkopts + commitopts + commitopts2,
4383 _('[OPTION]... [-r] REV')),
4385 _('[OPTION]... [-r] REV')),
4384 "bisect":
4386 "bisect":
4385 (bisect,
4387 (bisect,
4386 [('r', 'reset', False, _('reset bisect state')),
4388 [('r', 'reset', False, _('reset bisect state')),
4387 ('g', 'good', False, _('mark changeset good')),
4389 ('g', 'good', False, _('mark changeset good')),
4388 ('b', 'bad', False, _('mark changeset bad')),
4390 ('b', 'bad', False, _('mark changeset bad')),
4389 ('s', 'skip', False, _('skip testing changeset')),
4391 ('s', 'skip', False, _('skip testing changeset')),
4390 ('e', 'extend', False, _('extend the bisect range')),
4392 ('e', 'extend', False, _('extend the bisect range')),
4391 ('c', 'command', '',
4393 ('c', 'command', '',
4392 _('use command to check changeset state'), _('CMD')),
4394 _('use command to check changeset state'), _('CMD')),
4393 ('U', 'noupdate', False, _('do not update to target'))],
4395 ('U', 'noupdate', False, _('do not update to target'))],
4394 _("[-gbsr] [-U] [-c CMD] [REV]")),
4396 _("[-gbsr] [-U] [-c CMD] [REV]")),
4395 "bookmarks":
4397 "bookmarks":
4396 (bookmark,
4398 (bookmark,
4397 [('f', 'force', False, _('force')),
4399 [('f', 'force', False, _('force')),
4398 ('r', 'rev', '', _('revision'), _('REV')),
4400 ('r', 'rev', '', _('revision'), _('REV')),
4399 ('d', 'delete', False, _('delete a given bookmark')),
4401 ('d', 'delete', False, _('delete a given bookmark')),
4400 ('m', 'rename', '', _('rename a given bookmark'), _('NAME'))],
4402 ('m', 'rename', '', _('rename a given bookmark'), _('NAME'))],
4401 _('hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]')),
4403 _('hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]')),
4402 "branch":
4404 "branch":
4403 (branch,
4405 (branch,
4404 [('f', 'force', None,
4406 [('f', 'force', None,
4405 _('set branch name even if it shadows an existing branch')),
4407 _('set branch name even if it shadows an existing branch')),
4406 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4408 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4407 _('[-fC] [NAME]')),
4409 _('[-fC] [NAME]')),
4408 "branches":
4410 "branches":
4409 (branches,
4411 (branches,
4410 [('a', 'active', False,
4412 [('a', 'active', False,
4411 _('show only branches that have unmerged heads')),
4413 _('show only branches that have unmerged heads')),
4412 ('c', 'closed', False,
4414 ('c', 'closed', False,
4413 _('show normal and closed branches'))],
4415 _('show normal and closed branches'))],
4414 _('[-ac]')),
4416 _('[-ac]')),
4415 "bundle":
4417 "bundle":
4416 (bundle,
4418 (bundle,
4417 [('f', 'force', None,
4419 [('f', 'force', None,
4418 _('run even when the destination is unrelated')),
4420 _('run even when the destination is unrelated')),
4419 ('r', 'rev', [],
4421 ('r', 'rev', [],
4420 _('a changeset intended to be added to the destination'),
4422 _('a changeset intended to be added to the destination'),
4421 _('REV')),
4423 _('REV')),
4422 ('b', 'branch', [],
4424 ('b', 'branch', [],
4423 _('a specific branch you would like to bundle'),
4425 _('a specific branch you would like to bundle'),
4424 _('BRANCH')),
4426 _('BRANCH')),
4425 ('', 'base', [],
4427 ('', 'base', [],
4426 _('a base changeset assumed to be available at the destination'),
4428 _('a base changeset assumed to be available at the destination'),
4427 _('REV')),
4429 _('REV')),
4428 ('a', 'all', None, _('bundle all changesets in the repository')),
4430 ('a', 'all', None, _('bundle all changesets in the repository')),
4429 ('t', 'type', 'bzip2',
4431 ('t', 'type', 'bzip2',
4430 _('bundle compression type to use'), _('TYPE')),
4432 _('bundle compression type to use'), _('TYPE')),
4431 ] + remoteopts,
4433 ] + remoteopts,
4432 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4434 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4433 "cat":
4435 "cat":
4434 (cat,
4436 (cat,
4435 [('o', 'output', '',
4437 [('o', 'output', '',
4436 _('print output to file with formatted name'), _('FORMAT')),
4438 _('print output to file with formatted name'), _('FORMAT')),
4437 ('r', 'rev', '',
4439 ('r', 'rev', '',
4438 _('print the given revision'), _('REV')),
4440 _('print the given revision'), _('REV')),
4439 ('', 'decode', None, _('apply any matching decode filter')),
4441 ('', 'decode', None, _('apply any matching decode filter')),
4440 ] + walkopts,
4442 ] + walkopts,
4441 _('[OPTION]... FILE...')),
4443 _('[OPTION]... FILE...')),
4442 "^clone":
4444 "^clone":
4443 (clone,
4445 (clone,
4444 [('U', 'noupdate', None,
4446 [('U', 'noupdate', None,
4445 _('the clone will include an empty working copy (only a repository)')),
4447 _('the clone will include an empty working copy (only a repository)')),
4446 ('u', 'updaterev', '',
4448 ('u', 'updaterev', '',
4447 _('revision, tag or branch to check out'), _('REV')),
4449 _('revision, tag or branch to check out'), _('REV')),
4448 ('r', 'rev', [],
4450 ('r', 'rev', [],
4449 _('include the specified changeset'), _('REV')),
4451 _('include the specified changeset'), _('REV')),
4450 ('b', 'branch', [],
4452 ('b', 'branch', [],
4451 _('clone only the specified branch'), _('BRANCH')),
4453 _('clone only the specified branch'), _('BRANCH')),
4452 ('', 'pull', None, _('use pull protocol to copy metadata')),
4454 ('', 'pull', None, _('use pull protocol to copy metadata')),
4453 ('', 'uncompressed', None,
4455 ('', 'uncompressed', None,
4454 _('use uncompressed transfer (fast over LAN)')),
4456 _('use uncompressed transfer (fast over LAN)')),
4455 ] + remoteopts,
4457 ] + remoteopts,
4456 _('[OPTION]... SOURCE [DEST]')),
4458 _('[OPTION]... SOURCE [DEST]')),
4457 "^commit|ci":
4459 "^commit|ci":
4458 (commit,
4460 (commit,
4459 [('A', 'addremove', None,
4461 [('A', 'addremove', None,
4460 _('mark new/missing files as added/removed before committing')),
4462 _('mark new/missing files as added/removed before committing')),
4461 ('', 'close-branch', None,
4463 ('', 'close-branch', None,
4462 _('mark a branch as closed, hiding it from the branch list')),
4464 _('mark a branch as closed, hiding it from the branch list')),
4463 ] + walkopts + commitopts + commitopts2,
4465 ] + walkopts + commitopts + commitopts2,
4464 _('[OPTION]... [FILE]...')),
4466 _('[OPTION]... [FILE]...')),
4465 "copy|cp":
4467 "copy|cp":
4466 (copy,
4468 (copy,
4467 [('A', 'after', None, _('record a copy that has already occurred')),
4469 [('A', 'after', None, _('record a copy that has already occurred')),
4468 ('f', 'force', None,
4470 ('f', 'force', None,
4469 _('forcibly copy over an existing managed file')),
4471 _('forcibly copy over an existing managed file')),
4470 ] + walkopts + dryrunopts,
4472 ] + walkopts + dryrunopts,
4471 _('[OPTION]... [SOURCE]... DEST')),
4473 _('[OPTION]... [SOURCE]... DEST')),
4472 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4474 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4473 "debugbuilddag":
4475 "debugbuilddag":
4474 (debugbuilddag,
4476 (debugbuilddag,
4475 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4477 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4476 ('a', 'appended-file', None, _('add single file all revs append to')),
4478 ('a', 'appended-file', None, _('add single file all revs append to')),
4477 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4479 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4478 ('n', 'new-file', None, _('add new file at each rev')),
4480 ('n', 'new-file', None, _('add new file at each rev')),
4479 ],
4481 ],
4480 _('[OPTION]... TEXT')),
4482 _('[OPTION]... TEXT')),
4481 "debugbundle":
4483 "debugbundle":
4482 (debugbundle,
4484 (debugbundle,
4483 [('a', 'all', None, _('show all details')),
4485 [('a', 'all', None, _('show all details')),
4484 ],
4486 ],
4485 _('FILE')),
4487 _('FILE')),
4486 "debugcheckstate": (debugcheckstate, [], ''),
4488 "debugcheckstate": (debugcheckstate, [], ''),
4487 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4489 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4488 "debugcomplete":
4490 "debugcomplete":
4489 (debugcomplete,
4491 (debugcomplete,
4490 [('o', 'options', None, _('show the command options'))],
4492 [('o', 'options', None, _('show the command options'))],
4491 _('[-o] CMD')),
4493 _('[-o] CMD')),
4492 "debugdag":
4494 "debugdag":
4493 (debugdag,
4495 (debugdag,
4494 [('t', 'tags', None, _('use tags as labels')),
4496 [('t', 'tags', None, _('use tags as labels')),
4495 ('b', 'branches', None, _('annotate with branch names')),
4497 ('b', 'branches', None, _('annotate with branch names')),
4496 ('', 'dots', None, _('use dots for runs')),
4498 ('', 'dots', None, _('use dots for runs')),
4497 ('s', 'spaces', None, _('separate elements by spaces')),
4499 ('s', 'spaces', None, _('separate elements by spaces')),
4498 ],
4500 ],
4499 _('[OPTION]... [FILE [REV]...]')),
4501 _('[OPTION]... [FILE [REV]...]')),
4500 "debugdate":
4502 "debugdate":
4501 (debugdate,
4503 (debugdate,
4502 [('e', 'extended', None, _('try extended date formats'))],
4504 [('e', 'extended', None, _('try extended date formats'))],
4503 _('[-e] DATE [RANGE]')),
4505 _('[-e] DATE [RANGE]')),
4504 "debugdata": (debugdata, [], _('FILE REV')),
4506 "debugdata": (debugdata, [], _('FILE REV')),
4505 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4507 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4506 "debuggetbundle":
4508 "debuggetbundle":
4507 (debuggetbundle,
4509 (debuggetbundle,
4508 [('H', 'head', [], _('id of head node'), _('ID')),
4510 [('H', 'head', [], _('id of head node'), _('ID')),
4509 ('C', 'common', [], _('id of common node'), _('ID')),
4511 ('C', 'common', [], _('id of common node'), _('ID')),
4510 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
4512 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
4511 ],
4513 ],
4512 _('REPO FILE [-H|-C ID]...')),
4514 _('REPO FILE [-H|-C ID]...')),
4513 "debugignore": (debugignore, [], ''),
4515 "debugignore": (debugignore, [], ''),
4514 "debugindex": (debugindex,
4516 "debugindex": (debugindex,
4515 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
4517 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
4516 _('FILE')),
4518 _('FILE')),
4517 "debugindexdot": (debugindexdot, [], _('FILE')),
4519 "debugindexdot": (debugindexdot, [], _('FILE')),
4518 "debuginstall": (debuginstall, [], ''),
4520 "debuginstall": (debuginstall, [], ''),
4519 "debugknown": (debugknown, [], _('REPO ID...')),
4521 "debugknown": (debugknown, [], _('REPO ID...')),
4520 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4522 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4521 "debugrebuildstate":
4523 "debugrebuildstate":
4522 (debugrebuildstate,
4524 (debugrebuildstate,
4523 [('r', 'rev', '',
4525 [('r', 'rev', '',
4524 _('revision to rebuild to'), _('REV'))],
4526 _('revision to rebuild to'), _('REV'))],
4525 _('[-r REV] [REV]')),
4527 _('[-r REV] [REV]')),
4526 "debugrename":
4528 "debugrename":
4527 (debugrename,
4529 (debugrename,
4528 [('r', 'rev', '',
4530 [('r', 'rev', '',
4529 _('revision to debug'), _('REV'))],
4531 _('revision to debug'), _('REV'))],
4530 _('[-r REV] FILE')),
4532 _('[-r REV] FILE')),
4531 "debugrevspec":
4533 "debugrevspec":
4532 (debugrevspec, [], ('REVSPEC')),
4534 (debugrevspec, [], ('REVSPEC')),
4533 "debugsetparents":
4535 "debugsetparents":
4534 (debugsetparents, [], _('REV1 [REV2]')),
4536 (debugsetparents, [], _('REV1 [REV2]')),
4535 "debugstate":
4537 "debugstate":
4536 (debugstate,
4538 (debugstate,
4537 [('', 'nodates', None, _('do not display the saved mtime')),
4539 [('', 'nodates', None, _('do not display the saved mtime')),
4538 ('', 'datesort', None, _('sort by saved mtime'))],
4540 ('', 'datesort', None, _('sort by saved mtime'))],
4539 _('[OPTION]...')),
4541 _('[OPTION]...')),
4540 "debugsub":
4542 "debugsub":
4541 (debugsub,
4543 (debugsub,
4542 [('r', 'rev', '',
4544 [('r', 'rev', '',
4543 _('revision to check'), _('REV'))],
4545 _('revision to check'), _('REV'))],
4544 _('[-r REV] [REV]')),
4546 _('[-r REV] [REV]')),
4545 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4547 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4546 "debugwireargs":
4548 "debugwireargs":
4547 (debugwireargs,
4549 (debugwireargs,
4548 [('', 'three', '', 'three'),
4550 [('', 'three', '', 'three'),
4549 ('', 'four', '', 'four'),
4551 ('', 'four', '', 'four'),
4550 ] + remoteopts,
4552 ] + remoteopts,
4551 _('REPO [OPTIONS]... [ONE [TWO]]')),
4553 _('REPO [OPTIONS]... [ONE [TWO]]')),
4552 "^diff":
4554 "^diff":
4553 (diff,
4555 (diff,
4554 [('r', 'rev', [],
4556 [('r', 'rev', [],
4555 _('revision'), _('REV')),
4557 _('revision'), _('REV')),
4556 ('c', 'change', '',
4558 ('c', 'change', '',
4557 _('change made by revision'), _('REV'))
4559 _('change made by revision'), _('REV'))
4558 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4560 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4559 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4561 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4560 "^export":
4562 "^export":
4561 (export,
4563 (export,
4562 [('o', 'output', '',
4564 [('o', 'output', '',
4563 _('print output to file with formatted name'), _('FORMAT')),
4565 _('print output to file with formatted name'), _('FORMAT')),
4564 ('', 'switch-parent', None, _('diff against the second parent')),
4566 ('', 'switch-parent', None, _('diff against the second parent')),
4565 ('r', 'rev', [],
4567 ('r', 'rev', [],
4566 _('revisions to export'), _('REV')),
4568 _('revisions to export'), _('REV')),
4567 ] + diffopts,
4569 ] + diffopts,
4568 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4570 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4569 "^forget":
4571 "^forget":
4570 (forget,
4572 (forget,
4571 [] + walkopts,
4573 [] + walkopts,
4572 _('[OPTION]... FILE...')),
4574 _('[OPTION]... FILE...')),
4573 "grep":
4575 "grep":
4574 (grep,
4576 (grep,
4575 [('0', 'print0', None, _('end fields with NUL')),
4577 [('0', 'print0', None, _('end fields with NUL')),
4576 ('', 'all', None, _('print all revisions that match')),
4578 ('', 'all', None, _('print all revisions that match')),
4577 ('a', 'text', None, _('treat all files as text')),
4579 ('a', 'text', None, _('treat all files as text')),
4578 ('f', 'follow', None,
4580 ('f', 'follow', None,
4579 _('follow changeset history,'
4581 _('follow changeset history,'
4580 ' or file history across copies and renames')),
4582 ' or file history across copies and renames')),
4581 ('i', 'ignore-case', None, _('ignore case when matching')),
4583 ('i', 'ignore-case', None, _('ignore case when matching')),
4582 ('l', 'files-with-matches', None,
4584 ('l', 'files-with-matches', None,
4583 _('print only filenames and revisions that match')),
4585 _('print only filenames and revisions that match')),
4584 ('n', 'line-number', None, _('print matching line numbers')),
4586 ('n', 'line-number', None, _('print matching line numbers')),
4585 ('r', 'rev', [],
4587 ('r', 'rev', [],
4586 _('only search files changed within revision range'), _('REV')),
4588 _('only search files changed within revision range'), _('REV')),
4587 ('u', 'user', None, _('list the author (long with -v)')),
4589 ('u', 'user', None, _('list the author (long with -v)')),
4588 ('d', 'date', None, _('list the date (short with -q)')),
4590 ('d', 'date', None, _('list the date (short with -q)')),
4589 ] + walkopts,
4591 ] + walkopts,
4590 _('[OPTION]... PATTERN [FILE]...')),
4592 _('[OPTION]... PATTERN [FILE]...')),
4591 "heads":
4593 "heads":
4592 (heads,
4594 (heads,
4593 [('r', 'rev', '',
4595 [('r', 'rev', '',
4594 _('show only heads which are descendants of STARTREV'),
4596 _('show only heads which are descendants of STARTREV'),
4595 _('STARTREV')),
4597 _('STARTREV')),
4596 ('t', 'topo', False, _('show topological heads only')),
4598 ('t', 'topo', False, _('show topological heads only')),
4597 ('a', 'active', False,
4599 ('a', 'active', False,
4598 _('show active branchheads only (DEPRECATED)')),
4600 _('show active branchheads only (DEPRECATED)')),
4599 ('c', 'closed', False,
4601 ('c', 'closed', False,
4600 _('show normal and closed branch heads')),
4602 _('show normal and closed branch heads')),
4601 ] + templateopts,
4603 ] + templateopts,
4602 _('[-ac] [-r STARTREV] [REV]...')),
4604 _('[-ac] [-r STARTREV] [REV]...')),
4603 "help": (help_, [], _('[TOPIC]')),
4605 "help": (help_, [], _('[TOPIC]')),
4604 "identify|id":
4606 "identify|id":
4605 (identify,
4607 (identify,
4606 [('r', 'rev', '',
4608 [('r', 'rev', '',
4607 _('identify the specified revision'), _('REV')),
4609 _('identify the specified revision'), _('REV')),
4608 ('n', 'num', None, _('show local revision number')),
4610 ('n', 'num', None, _('show local revision number')),
4609 ('i', 'id', None, _('show global revision id')),
4611 ('i', 'id', None, _('show global revision id')),
4610 ('b', 'branch', None, _('show branch')),
4612 ('b', 'branch', None, _('show branch')),
4611 ('t', 'tags', None, _('show tags')),
4613 ('t', 'tags', None, _('show tags')),
4612 ('B', 'bookmarks', None, _('show bookmarks'))],
4614 ('B', 'bookmarks', None, _('show bookmarks'))],
4613 _('[-nibtB] [-r REV] [SOURCE]')),
4615 _('[-nibtB] [-r REV] [SOURCE]')),
4614 "import|patch":
4616 "import|patch":
4615 (import_,
4617 (import_,
4616 [('p', 'strip', 1,
4618 [('p', 'strip', 1,
4617 _('directory strip option for patch. This has the same '
4619 _('directory strip option for patch. This has the same '
4618 'meaning as the corresponding patch option'),
4620 'meaning as the corresponding patch option'),
4619 _('NUM')),
4621 _('NUM')),
4620 ('b', 'base', '',
4622 ('b', 'base', '',
4621 _('base path'), _('PATH')),
4623 _('base path'), _('PATH')),
4622 ('f', 'force', None,
4624 ('f', 'force', None,
4623 _('skip check for outstanding uncommitted changes')),
4625 _('skip check for outstanding uncommitted changes')),
4624 ('', 'no-commit', None,
4626 ('', 'no-commit', None,
4625 _("don't commit, just update the working directory")),
4627 _("don't commit, just update the working directory")),
4626 ('', 'exact', None,
4628 ('', 'exact', None,
4627 _('apply patch to the nodes from which it was generated')),
4629 _('apply patch to the nodes from which it was generated')),
4628 ('', 'import-branch', None,
4630 ('', 'import-branch', None,
4629 _('use any branch information in patch (implied by --exact)'))] +
4631 _('use any branch information in patch (implied by --exact)'))] +
4630 commitopts + commitopts2 + similarityopts,
4632 commitopts + commitopts2 + similarityopts,
4631 _('[OPTION]... PATCH...')),
4633 _('[OPTION]... PATCH...')),
4632 "incoming|in":
4634 "incoming|in":
4633 (incoming,
4635 (incoming,
4634 [('f', 'force', None,
4636 [('f', 'force', None,
4635 _('run even if remote repository is unrelated')),
4637 _('run even if remote repository is unrelated')),
4636 ('n', 'newest-first', None, _('show newest record first')),
4638 ('n', 'newest-first', None, _('show newest record first')),
4637 ('', 'bundle', '',
4639 ('', 'bundle', '',
4638 _('file to store the bundles into'), _('FILE')),
4640 _('file to store the bundles into'), _('FILE')),
4639 ('r', 'rev', [],
4641 ('r', 'rev', [],
4640 _('a remote changeset intended to be added'), _('REV')),
4642 _('a remote changeset intended to be added'), _('REV')),
4641 ('B', 'bookmarks', False, _("compare bookmarks")),
4643 ('B', 'bookmarks', False, _("compare bookmarks")),
4642 ('b', 'branch', [],
4644 ('b', 'branch', [],
4643 _('a specific branch you would like to pull'), _('BRANCH')),
4645 _('a specific branch you would like to pull'), _('BRANCH')),
4644 ] + logopts + remoteopts + subrepoopts,
4646 ] + logopts + remoteopts + subrepoopts,
4645 _('[-p] [-n] [-M] [-f] [-r REV]...'
4647 _('[-p] [-n] [-M] [-f] [-r REV]...'
4646 ' [--bundle FILENAME] [SOURCE]')),
4648 ' [--bundle FILENAME] [SOURCE]')),
4647 "^init":
4649 "^init":
4648 (init,
4650 (init,
4649 remoteopts,
4651 remoteopts,
4650 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4652 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4651 "locate":
4653 "locate":
4652 (locate,
4654 (locate,
4653 [('r', 'rev', '',
4655 [('r', 'rev', '',
4654 _('search the repository as it is in REV'), _('REV')),
4656 _('search the repository as it is in REV'), _('REV')),
4655 ('0', 'print0', None,
4657 ('0', 'print0', None,
4656 _('end filenames with NUL, for use with xargs')),
4658 _('end filenames with NUL, for use with xargs')),
4657 ('f', 'fullpath', None,
4659 ('f', 'fullpath', None,
4658 _('print complete paths from the filesystem root')),
4660 _('print complete paths from the filesystem root')),
4659 ] + walkopts,
4661 ] + walkopts,
4660 _('[OPTION]... [PATTERN]...')),
4662 _('[OPTION]... [PATTERN]...')),
4661 "^log|history":
4663 "^log|history":
4662 (log,
4664 (log,
4663 [('f', 'follow', None,
4665 [('f', 'follow', None,
4664 _('follow changeset history,'
4666 _('follow changeset history,'
4665 ' or file history across copies and renames')),
4667 ' or file history across copies and renames')),
4666 ('', 'follow-first', None,
4668 ('', 'follow-first', None,
4667 _('only follow the first parent of merge changesets')),
4669 _('only follow the first parent of merge changesets')),
4668 ('d', 'date', '',
4670 ('d', 'date', '',
4669 _('show revisions matching date spec'), _('DATE')),
4671 _('show revisions matching date spec'), _('DATE')),
4670 ('C', 'copies', None, _('show copied files')),
4672 ('C', 'copies', None, _('show copied files')),
4671 ('k', 'keyword', [],
4673 ('k', 'keyword', [],
4672 _('do case-insensitive search for a given text'), _('TEXT')),
4674 _('do case-insensitive search for a given text'), _('TEXT')),
4673 ('r', 'rev', [],
4675 ('r', 'rev', [],
4674 _('show the specified revision or range'), _('REV')),
4676 _('show the specified revision or range'), _('REV')),
4675 ('', 'removed', None, _('include revisions where files were removed')),
4677 ('', 'removed', None, _('include revisions where files were removed')),
4676 ('m', 'only-merges', None, _('show only merges')),
4678 ('m', 'only-merges', None, _('show only merges')),
4677 ('u', 'user', [],
4679 ('u', 'user', [],
4678 _('revisions committed by user'), _('USER')),
4680 _('revisions committed by user'), _('USER')),
4679 ('', 'only-branch', [],
4681 ('', 'only-branch', [],
4680 _('show only changesets within the given named branch (DEPRECATED)'),
4682 _('show only changesets within the given named branch (DEPRECATED)'),
4681 _('BRANCH')),
4683 _('BRANCH')),
4682 ('b', 'branch', [],
4684 ('b', 'branch', [],
4683 _('show changesets within the given named branch'), _('BRANCH')),
4685 _('show changesets within the given named branch'), _('BRANCH')),
4684 ('P', 'prune', [],
4686 ('P', 'prune', [],
4685 _('do not display revision or any of its ancestors'), _('REV')),
4687 _('do not display revision or any of its ancestors'), _('REV')),
4686 ] + logopts + walkopts,
4688 ] + logopts + walkopts,
4687 _('[OPTION]... [FILE]')),
4689 _('[OPTION]... [FILE]')),
4688 "manifest":
4690 "manifest":
4689 (manifest,
4691 (manifest,
4690 [('r', 'rev', '',
4692 [('r', 'rev', '',
4691 _('revision to display'), _('REV'))],
4693 _('revision to display'), _('REV'))],
4692 _('[-r REV]')),
4694 _('[-r REV]')),
4693 "^merge":
4695 "^merge":
4694 (merge,
4696 (merge,
4695 [('f', 'force', None, _('force a merge with outstanding changes')),
4697 [('f', 'force', None, _('force a merge with outstanding changes')),
4696 ('t', 'tool', '', _('specify merge tool')),
4698 ('t', 'tool', '', _('specify merge tool')),
4697 ('r', 'rev', '',
4699 ('r', 'rev', '',
4698 _('revision to merge'), _('REV')),
4700 _('revision to merge'), _('REV')),
4699 ('P', 'preview', None,
4701 ('P', 'preview', None,
4700 _('review revisions to merge (no merge is performed)'))],
4702 _('review revisions to merge (no merge is performed)'))],
4701 _('[-P] [-f] [[-r] REV]')),
4703 _('[-P] [-f] [[-r] REV]')),
4702 "outgoing|out":
4704 "outgoing|out":
4703 (outgoing,
4705 (outgoing,
4704 [('f', 'force', None,
4706 [('f', 'force', None,
4705 _('run even when the destination is unrelated')),
4707 _('run even when the destination is unrelated')),
4706 ('r', 'rev', [],
4708 ('r', 'rev', [],
4707 _('a changeset intended to be included in the destination'),
4709 _('a changeset intended to be included in the destination'),
4708 _('REV')),
4710 _('REV')),
4709 ('n', 'newest-first', None, _('show newest record first')),
4711 ('n', 'newest-first', None, _('show newest record first')),
4710 ('B', 'bookmarks', False, _("compare bookmarks")),
4712 ('B', 'bookmarks', False, _("compare bookmarks")),
4711 ('b', 'branch', [],
4713 ('b', 'branch', [],
4712 _('a specific branch you would like to push'), _('BRANCH')),
4714 _('a specific branch you would like to push'), _('BRANCH')),
4713 ] + logopts + remoteopts + subrepoopts,
4715 ] + logopts + remoteopts + subrepoopts,
4714 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4716 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4715 "parents":
4717 "parents":
4716 (parents,
4718 (parents,
4717 [('r', 'rev', '',
4719 [('r', 'rev', '',
4718 _('show parents of the specified revision'), _('REV')),
4720 _('show parents of the specified revision'), _('REV')),
4719 ] + templateopts,
4721 ] + templateopts,
4720 _('[-r REV] [FILE]')),
4722 _('[-r REV] [FILE]')),
4721 "paths": (paths, [], _('[NAME]')),
4723 "paths": (paths, [], _('[NAME]')),
4722 "^pull":
4724 "^pull":
4723 (pull,
4725 (pull,
4724 [('u', 'update', None,
4726 [('u', 'update', None,
4725 _('update to new branch head if changesets were pulled')),
4727 _('update to new branch head if changesets were pulled')),
4726 ('f', 'force', None,
4728 ('f', 'force', None,
4727 _('run even when remote repository is unrelated')),
4729 _('run even when remote repository is unrelated')),
4728 ('r', 'rev', [],
4730 ('r', 'rev', [],
4729 _('a remote changeset intended to be added'), _('REV')),
4731 _('a remote changeset intended to be added'), _('REV')),
4730 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4732 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4731 ('b', 'branch', [],
4733 ('b', 'branch', [],
4732 _('a specific branch you would like to pull'), _('BRANCH')),
4734 _('a specific branch you would like to pull'), _('BRANCH')),
4733 ] + remoteopts,
4735 ] + remoteopts,
4734 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4736 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4735 "^push":
4737 "^push":
4736 (push,
4738 (push,
4737 [('f', 'force', None, _('force push')),
4739 [('f', 'force', None, _('force push')),
4738 ('r', 'rev', [],
4740 ('r', 'rev', [],
4739 _('a changeset intended to be included in the destination'),
4741 _('a changeset intended to be included in the destination'),
4740 _('REV')),
4742 _('REV')),
4741 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4743 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4742 ('b', 'branch', [],
4744 ('b', 'branch', [],
4743 _('a specific branch you would like to push'), _('BRANCH')),
4745 _('a specific branch you would like to push'), _('BRANCH')),
4744 ('', 'new-branch', False, _('allow pushing a new branch')),
4746 ('', 'new-branch', False, _('allow pushing a new branch')),
4745 ] + remoteopts,
4747 ] + remoteopts,
4746 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4748 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4747 "recover": (recover, []),
4749 "recover": (recover, []),
4748 "^remove|rm":
4750 "^remove|rm":
4749 (remove,
4751 (remove,
4750 [('A', 'after', None, _('record delete for missing files')),
4752 [('A', 'after', None, _('record delete for missing files')),
4751 ('f', 'force', None,
4753 ('f', 'force', None,
4752 _('remove (and delete) file even if added or modified')),
4754 _('remove (and delete) file even if added or modified')),
4753 ] + walkopts,
4755 ] + walkopts,
4754 _('[OPTION]... FILE...')),
4756 _('[OPTION]... FILE...')),
4755 "rename|move|mv":
4757 "rename|move|mv":
4756 (rename,
4758 (rename,
4757 [('A', 'after', None, _('record a rename that has already occurred')),
4759 [('A', 'after', None, _('record a rename that has already occurred')),
4758 ('f', 'force', None,
4760 ('f', 'force', None,
4759 _('forcibly copy over an existing managed file')),
4761 _('forcibly copy over an existing managed file')),
4760 ] + walkopts + dryrunopts,
4762 ] + walkopts + dryrunopts,
4761 _('[OPTION]... SOURCE... DEST')),
4763 _('[OPTION]... SOURCE... DEST')),
4762 "resolve":
4764 "resolve":
4763 (resolve,
4765 (resolve,
4764 [('a', 'all', None, _('select all unresolved files')),
4766 [('a', 'all', None, _('select all unresolved files')),
4765 ('l', 'list', None, _('list state of files needing merge')),
4767 ('l', 'list', None, _('list state of files needing merge')),
4766 ('m', 'mark', None, _('mark files as resolved')),
4768 ('m', 'mark', None, _('mark files as resolved')),
4767 ('u', 'unmark', None, _('mark files as unresolved')),
4769 ('u', 'unmark', None, _('mark files as unresolved')),
4768 ('t', 'tool', '', _('specify merge tool')),
4770 ('t', 'tool', '', _('specify merge tool')),
4769 ('n', 'no-status', None, _('hide status prefix'))]
4771 ('n', 'no-status', None, _('hide status prefix'))]
4770 + walkopts,
4772 + walkopts,
4771 _('[OPTION]... [FILE]...')),
4773 _('[OPTION]... [FILE]...')),
4772 "revert":
4774 "revert":
4773 (revert,
4775 (revert,
4774 [('a', 'all', None, _('revert all changes when no arguments given')),
4776 [('a', 'all', None, _('revert all changes when no arguments given')),
4775 ('d', 'date', '',
4777 ('d', 'date', '',
4776 _('tipmost revision matching date'), _('DATE')),
4778 _('tipmost revision matching date'), _('DATE')),
4777 ('r', 'rev', '',
4779 ('r', 'rev', '',
4778 _('revert to the specified revision'), _('REV')),
4780 _('revert to the specified revision'), _('REV')),
4779 ('', 'no-backup', None, _('do not save backup copies of files')),
4781 ('', 'no-backup', None, _('do not save backup copies of files')),
4780 ] + walkopts + dryrunopts,
4782 ] + walkopts + dryrunopts,
4781 _('[OPTION]... [-r REV] [NAME]...')),
4783 _('[OPTION]... [-r REV] [NAME]...')),
4782 "rollback": (rollback, dryrunopts),
4784 "rollback": (rollback, dryrunopts),
4783 "root": (root, []),
4785 "root": (root, []),
4784 "^serve":
4786 "^serve":
4785 (serve,
4787 (serve,
4786 [('A', 'accesslog', '',
4788 [('A', 'accesslog', '',
4787 _('name of access log file to write to'), _('FILE')),
4789 _('name of access log file to write to'), _('FILE')),
4788 ('d', 'daemon', None, _('run server in background')),
4790 ('d', 'daemon', None, _('run server in background')),
4789 ('', 'daemon-pipefds', '',
4791 ('', 'daemon-pipefds', '',
4790 _('used internally by daemon mode'), _('NUM')),
4792 _('used internally by daemon mode'), _('NUM')),
4791 ('E', 'errorlog', '',
4793 ('E', 'errorlog', '',
4792 _('name of error log file to write to'), _('FILE')),
4794 _('name of error log file to write to'), _('FILE')),
4793 # use string type, then we can check if something was passed
4795 # use string type, then we can check if something was passed
4794 ('p', 'port', '',
4796 ('p', 'port', '',
4795 _('port to listen on (default: 8000)'), _('PORT')),
4797 _('port to listen on (default: 8000)'), _('PORT')),
4796 ('a', 'address', '',
4798 ('a', 'address', '',
4797 _('address to listen on (default: all interfaces)'), _('ADDR')),
4799 _('address to listen on (default: all interfaces)'), _('ADDR')),
4798 ('', 'prefix', '',
4800 ('', 'prefix', '',
4799 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4801 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4800 ('n', 'name', '',
4802 ('n', 'name', '',
4801 _('name to show in web pages (default: working directory)'),
4803 _('name to show in web pages (default: working directory)'),
4802 _('NAME')),
4804 _('NAME')),
4803 ('', 'web-conf', '',
4805 ('', 'web-conf', '',
4804 _('name of the hgweb config file (see "hg help hgweb")'),
4806 _('name of the hgweb config file (see "hg help hgweb")'),
4805 _('FILE')),
4807 _('FILE')),
4806 ('', 'webdir-conf', '',
4808 ('', 'webdir-conf', '',
4807 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4809 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4808 ('', 'pid-file', '',
4810 ('', 'pid-file', '',
4809 _('name of file to write process ID to'), _('FILE')),
4811 _('name of file to write process ID to'), _('FILE')),
4810 ('', 'stdio', None, _('for remote clients')),
4812 ('', 'stdio', None, _('for remote clients')),
4811 ('t', 'templates', '',
4813 ('t', 'templates', '',
4812 _('web templates to use'), _('TEMPLATE')),
4814 _('web templates to use'), _('TEMPLATE')),
4813 ('', 'style', '',
4815 ('', 'style', '',
4814 _('template style to use'), _('STYLE')),
4816 _('template style to use'), _('STYLE')),
4815 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4817 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4816 ('', 'certificate', '',
4818 ('', 'certificate', '',
4817 _('SSL certificate file'), _('FILE'))],
4819 _('SSL certificate file'), _('FILE'))],
4818 _('[OPTION]...')),
4820 _('[OPTION]...')),
4819 "showconfig|debugconfig":
4821 "showconfig|debugconfig":
4820 (showconfig,
4822 (showconfig,
4821 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4823 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4822 _('[-u] [NAME]...')),
4824 _('[-u] [NAME]...')),
4823 "^summary|sum":
4825 "^summary|sum":
4824 (summary,
4826 (summary,
4825 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4827 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4826 "^status|st":
4828 "^status|st":
4827 (status,
4829 (status,
4828 [('A', 'all', None, _('show status of all files')),
4830 [('A', 'all', None, _('show status of all files')),
4829 ('m', 'modified', None, _('show only modified files')),
4831 ('m', 'modified', None, _('show only modified files')),
4830 ('a', 'added', None, _('show only added files')),
4832 ('a', 'added', None, _('show only added files')),
4831 ('r', 'removed', None, _('show only removed files')),
4833 ('r', 'removed', None, _('show only removed files')),
4832 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4834 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4833 ('c', 'clean', None, _('show only files without changes')),
4835 ('c', 'clean', None, _('show only files without changes')),
4834 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4836 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4835 ('i', 'ignored', None, _('show only ignored files')),
4837 ('i', 'ignored', None, _('show only ignored files')),
4836 ('n', 'no-status', None, _('hide status prefix')),
4838 ('n', 'no-status', None, _('hide status prefix')),
4837 ('C', 'copies', None, _('show source of copied files')),
4839 ('C', 'copies', None, _('show source of copied files')),
4838 ('0', 'print0', None,
4840 ('0', 'print0', None,
4839 _('end filenames with NUL, for use with xargs')),
4841 _('end filenames with NUL, for use with xargs')),
4840 ('', 'rev', [],
4842 ('', 'rev', [],
4841 _('show difference from revision'), _('REV')),
4843 _('show difference from revision'), _('REV')),
4842 ('', 'change', '',
4844 ('', 'change', '',
4843 _('list the changed files of a revision'), _('REV')),
4845 _('list the changed files of a revision'), _('REV')),
4844 ] + walkopts + subrepoopts,
4846 ] + walkopts + subrepoopts,
4845 _('[OPTION]... [FILE]...')),
4847 _('[OPTION]... [FILE]...')),
4846 "tag":
4848 "tag":
4847 (tag,
4849 (tag,
4848 [('f', 'force', None, _('force tag')),
4850 [('f', 'force', None, _('force tag')),
4849 ('l', 'local', None, _('make the tag local')),
4851 ('l', 'local', None, _('make the tag local')),
4850 ('r', 'rev', '',
4852 ('r', 'rev', '',
4851 _('revision to tag'), _('REV')),
4853 _('revision to tag'), _('REV')),
4852 ('', 'remove', None, _('remove a tag')),
4854 ('', 'remove', None, _('remove a tag')),
4853 # -l/--local is already there, commitopts cannot be used
4855 # -l/--local is already there, commitopts cannot be used
4854 ('e', 'edit', None, _('edit commit message')),
4856 ('e', 'edit', None, _('edit commit message')),
4855 ('m', 'message', '',
4857 ('m', 'message', '',
4856 _('use <text> as commit message'), _('TEXT')),
4858 _('use <text> as commit message'), _('TEXT')),
4857 ] + commitopts2,
4859 ] + commitopts2,
4858 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4860 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4859 "tags": (tags, [], ''),
4861 "tags": (tags, [], ''),
4860 "tip":
4862 "tip":
4861 (tip,
4863 (tip,
4862 [('p', 'patch', None, _('show patch')),
4864 [('p', 'patch', None, _('show patch')),
4863 ('g', 'git', None, _('use git extended diff format')),
4865 ('g', 'git', None, _('use git extended diff format')),
4864 ] + templateopts,
4866 ] + templateopts,
4865 _('[-p] [-g]')),
4867 _('[-p] [-g]')),
4866 "unbundle":
4868 "unbundle":
4867 (unbundle,
4869 (unbundle,
4868 [('u', 'update', None,
4870 [('u', 'update', None,
4869 _('update to new branch head if changesets were unbundled'))],
4871 _('update to new branch head if changesets were unbundled'))],
4870 _('[-u] FILE...')),
4872 _('[-u] FILE...')),
4871 "^update|up|checkout|co":
4873 "^update|up|checkout|co":
4872 (update,
4874 (update,
4873 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4875 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4874 ('c', 'check', None,
4876 ('c', 'check', None,
4875 _('update across branches if no uncommitted changes')),
4877 _('update across branches if no uncommitted changes')),
4876 ('d', 'date', '',
4878 ('d', 'date', '',
4877 _('tipmost revision matching date'), _('DATE')),
4879 _('tipmost revision matching date'), _('DATE')),
4878 ('r', 'rev', '',
4880 ('r', 'rev', '',
4879 _('revision'), _('REV'))],
4881 _('revision'), _('REV'))],
4880 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4882 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4881 "verify": (verify, []),
4883 "verify": (verify, []),
4882 "version": (version_, []),
4884 "version": (version_, []),
4883 }
4885 }
4884
4886
4885 norepo = ("clone init version help debugcommands debugcomplete"
4887 norepo = ("clone init version help debugcommands debugcomplete"
4886 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
4888 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
4887 " debugknown debuggetbundle debugbundle")
4889 " debugknown debuggetbundle debugbundle")
4888 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
4890 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
4889 " debugdata debugindex debugindexdot")
4891 " debugdata debugindex debugindexdot")
@@ -1,655 +1,655 b''
1 # dispatch.py - command dispatching for mercurial
1 # dispatch.py - command dispatching 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 i18n import _
8 from i18n import _
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
10 import util, commands, hg, fancyopts, extensions, hook, error
10 import util, commands, hg, fancyopts, extensions, hook, error
11 import cmdutil, encoding
11 import cmdutil, encoding
12 import ui as uimod
12 import ui as uimod
13
13
14 def run():
14 def run():
15 "run the command in sys.argv"
15 "run the command in sys.argv"
16 sys.exit(dispatch(sys.argv[1:]))
16 sys.exit(dispatch(sys.argv[1:]))
17
17
18 def dispatch(args):
18 def dispatch(args):
19 "run the command specified in args"
19 "run the command specified in args"
20 try:
20 try:
21 u = uimod.ui()
21 u = uimod.ui()
22 if '--traceback' in args:
22 if '--traceback' in args:
23 u.setconfig('ui', 'traceback', 'on')
23 u.setconfig('ui', 'traceback', 'on')
24 except util.Abort, inst:
24 except util.Abort, inst:
25 sys.stderr.write(_("abort: %s\n") % inst)
25 sys.stderr.write(_("abort: %s\n") % inst)
26 if inst.hint:
26 if inst.hint:
27 sys.stderr.write(_("(%s)\n") % inst.hint)
27 sys.stderr.write(_("(%s)\n") % inst.hint)
28 return -1
28 return -1
29 except error.ParseError, inst:
29 except error.ParseError, inst:
30 if len(inst.args) > 1:
30 if len(inst.args) > 1:
31 sys.stderr.write(_("hg: parse error at %s: %s\n") %
31 sys.stderr.write(_("hg: parse error at %s: %s\n") %
32 (inst.args[1], inst.args[0]))
32 (inst.args[1], inst.args[0]))
33 else:
33 else:
34 sys.stderr.write(_("hg: parse error: %s\n") % inst.args[0])
34 sys.stderr.write(_("hg: parse error: %s\n") % inst.args[0])
35 return -1
35 return -1
36 return _runcatch(u, args)
36 return _runcatch(u, args)
37
37
38 def _runcatch(ui, args):
38 def _runcatch(ui, args):
39 def catchterm(*args):
39 def catchterm(*args):
40 raise error.SignalInterrupt
40 raise error.SignalInterrupt
41
41
42 try:
42 try:
43 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
43 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
44 num = getattr(signal, name, None)
44 num = getattr(signal, name, None)
45 if num:
45 if num:
46 signal.signal(num, catchterm)
46 signal.signal(num, catchterm)
47 except ValueError:
47 except ValueError:
48 pass # happens if called in a thread
48 pass # happens if called in a thread
49
49
50 try:
50 try:
51 try:
51 try:
52 # enter the debugger before command execution
52 # enter the debugger before command execution
53 if '--debugger' in args:
53 if '--debugger' in args:
54 ui.warn(_("entering debugger - "
54 ui.warn(_("entering debugger - "
55 "type c to continue starting hg or h for help\n"))
55 "type c to continue starting hg or h for help\n"))
56 pdb.set_trace()
56 pdb.set_trace()
57 try:
57 try:
58 return _dispatch(ui, args)
58 return _dispatch(ui, args)
59 finally:
59 finally:
60 ui.flush()
60 ui.flush()
61 except:
61 except:
62 # enter the debugger when we hit an exception
62 # enter the debugger when we hit an exception
63 if '--debugger' in args:
63 if '--debugger' in args:
64 traceback.print_exc()
64 traceback.print_exc()
65 pdb.post_mortem(sys.exc_info()[2])
65 pdb.post_mortem(sys.exc_info()[2])
66 ui.traceback()
66 ui.traceback()
67 raise
67 raise
68
68
69 # Global exception handling, alphabetically
69 # Global exception handling, alphabetically
70 # Mercurial-specific first, followed by built-in and library exceptions
70 # Mercurial-specific first, followed by built-in and library exceptions
71 except error.AmbiguousCommand, inst:
71 except error.AmbiguousCommand, inst:
72 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
72 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
73 (inst.args[0], " ".join(inst.args[1])))
73 (inst.args[0], " ".join(inst.args[1])))
74 except error.ParseError, inst:
74 except error.ParseError, inst:
75 if len(inst.args) > 1:
75 if len(inst.args) > 1:
76 ui.warn(_("hg: parse error at %s: %s\n") %
76 ui.warn(_("hg: parse error at %s: %s\n") %
77 (inst.args[1], inst.args[0]))
77 (inst.args[1], inst.args[0]))
78 else:
78 else:
79 ui.warn(_("hg: parse error: %s\n") % inst.args[0])
79 ui.warn(_("hg: parse error: %s\n") % inst.args[0])
80 return -1
80 return -1
81 except error.LockHeld, inst:
81 except error.LockHeld, inst:
82 if inst.errno == errno.ETIMEDOUT:
82 if inst.errno == errno.ETIMEDOUT:
83 reason = _('timed out waiting for lock held by %s') % inst.locker
83 reason = _('timed out waiting for lock held by %s') % inst.locker
84 else:
84 else:
85 reason = _('lock held by %s') % inst.locker
85 reason = _('lock held by %s') % inst.locker
86 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
86 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
87 except error.LockUnavailable, inst:
87 except error.LockUnavailable, inst:
88 ui.warn(_("abort: could not lock %s: %s\n") %
88 ui.warn(_("abort: could not lock %s: %s\n") %
89 (inst.desc or inst.filename, inst.strerror))
89 (inst.desc or inst.filename, inst.strerror))
90 except error.CommandError, inst:
90 except error.CommandError, inst:
91 if inst.args[0]:
91 if inst.args[0]:
92 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
92 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
93 commands.help_(ui, inst.args[0])
93 commands.help_(ui, inst.args[0], full=False)
94 else:
94 else:
95 ui.warn(_("hg: %s\n") % inst.args[1])
95 ui.warn(_("hg: %s\n") % inst.args[1])
96 commands.help_(ui, 'shortlist')
96 commands.help_(ui, 'shortlist')
97 except error.RepoError, inst:
97 except error.RepoError, inst:
98 ui.warn(_("abort: %s!\n") % inst)
98 ui.warn(_("abort: %s!\n") % inst)
99 except error.ResponseError, inst:
99 except error.ResponseError, inst:
100 ui.warn(_("abort: %s") % inst.args[0])
100 ui.warn(_("abort: %s") % inst.args[0])
101 if not isinstance(inst.args[1], basestring):
101 if not isinstance(inst.args[1], basestring):
102 ui.warn(" %r\n" % (inst.args[1],))
102 ui.warn(" %r\n" % (inst.args[1],))
103 elif not inst.args[1]:
103 elif not inst.args[1]:
104 ui.warn(_(" empty string\n"))
104 ui.warn(_(" empty string\n"))
105 else:
105 else:
106 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
106 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
107 except error.RevlogError, inst:
107 except error.RevlogError, inst:
108 ui.warn(_("abort: %s!\n") % inst)
108 ui.warn(_("abort: %s!\n") % inst)
109 except error.SignalInterrupt:
109 except error.SignalInterrupt:
110 ui.warn(_("killed!\n"))
110 ui.warn(_("killed!\n"))
111 except error.UnknownCommand, inst:
111 except error.UnknownCommand, inst:
112 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
112 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
113 try:
113 try:
114 # check if the command is in a disabled extension
114 # check if the command is in a disabled extension
115 # (but don't check for extensions themselves)
115 # (but don't check for extensions themselves)
116 commands.help_(ui, inst.args[0], unknowncmd=True)
116 commands.help_(ui, inst.args[0], unknowncmd=True)
117 except error.UnknownCommand:
117 except error.UnknownCommand:
118 commands.help_(ui, 'shortlist')
118 commands.help_(ui, 'shortlist')
119 except util.Abort, inst:
119 except util.Abort, inst:
120 ui.warn(_("abort: %s\n") % inst)
120 ui.warn(_("abort: %s\n") % inst)
121 if inst.hint:
121 if inst.hint:
122 ui.warn(_("(%s)\n") % inst.hint)
122 ui.warn(_("(%s)\n") % inst.hint)
123 except ImportError, inst:
123 except ImportError, inst:
124 ui.warn(_("abort: %s!\n") % inst)
124 ui.warn(_("abort: %s!\n") % inst)
125 m = str(inst).split()[-1]
125 m = str(inst).split()[-1]
126 if m in "mpatch bdiff".split():
126 if m in "mpatch bdiff".split():
127 ui.warn(_("(did you forget to compile extensions?)\n"))
127 ui.warn(_("(did you forget to compile extensions?)\n"))
128 elif m in "zlib".split():
128 elif m in "zlib".split():
129 ui.warn(_("(is your Python install correct?)\n"))
129 ui.warn(_("(is your Python install correct?)\n"))
130 except IOError, inst:
130 except IOError, inst:
131 if hasattr(inst, "code"):
131 if hasattr(inst, "code"):
132 ui.warn(_("abort: %s\n") % inst)
132 ui.warn(_("abort: %s\n") % inst)
133 elif hasattr(inst, "reason"):
133 elif hasattr(inst, "reason"):
134 try: # usually it is in the form (errno, strerror)
134 try: # usually it is in the form (errno, strerror)
135 reason = inst.reason.args[1]
135 reason = inst.reason.args[1]
136 except: # it might be anything, for example a string
136 except: # it might be anything, for example a string
137 reason = inst.reason
137 reason = inst.reason
138 ui.warn(_("abort: error: %s\n") % reason)
138 ui.warn(_("abort: error: %s\n") % reason)
139 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
139 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
140 if ui.debugflag:
140 if ui.debugflag:
141 ui.warn(_("broken pipe\n"))
141 ui.warn(_("broken pipe\n"))
142 elif getattr(inst, "strerror", None):
142 elif getattr(inst, "strerror", None):
143 if getattr(inst, "filename", None):
143 if getattr(inst, "filename", None):
144 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
144 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
145 else:
145 else:
146 ui.warn(_("abort: %s\n") % inst.strerror)
146 ui.warn(_("abort: %s\n") % inst.strerror)
147 else:
147 else:
148 raise
148 raise
149 except OSError, inst:
149 except OSError, inst:
150 if getattr(inst, "filename", None):
150 if getattr(inst, "filename", None):
151 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
151 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
152 else:
152 else:
153 ui.warn(_("abort: %s\n") % inst.strerror)
153 ui.warn(_("abort: %s\n") % inst.strerror)
154 except KeyboardInterrupt:
154 except KeyboardInterrupt:
155 try:
155 try:
156 ui.warn(_("interrupted!\n"))
156 ui.warn(_("interrupted!\n"))
157 except IOError, inst:
157 except IOError, inst:
158 if inst.errno == errno.EPIPE:
158 if inst.errno == errno.EPIPE:
159 if ui.debugflag:
159 if ui.debugflag:
160 ui.warn(_("\nbroken pipe\n"))
160 ui.warn(_("\nbroken pipe\n"))
161 else:
161 else:
162 raise
162 raise
163 except MemoryError:
163 except MemoryError:
164 ui.warn(_("abort: out of memory\n"))
164 ui.warn(_("abort: out of memory\n"))
165 except SystemExit, inst:
165 except SystemExit, inst:
166 # Commands shouldn't sys.exit directly, but give a return code.
166 # Commands shouldn't sys.exit directly, but give a return code.
167 # Just in case catch this and and pass exit code to caller.
167 # Just in case catch this and and pass exit code to caller.
168 return inst.code
168 return inst.code
169 except socket.error, inst:
169 except socket.error, inst:
170 ui.warn(_("abort: %s\n") % inst.args[-1])
170 ui.warn(_("abort: %s\n") % inst.args[-1])
171 except:
171 except:
172 ui.warn(_("** unknown exception encountered,"
172 ui.warn(_("** unknown exception encountered,"
173 " please report by visiting\n"))
173 " please report by visiting\n"))
174 ui.warn(_("** http://mercurial.selenic.com/wiki/BugTracker\n"))
174 ui.warn(_("** http://mercurial.selenic.com/wiki/BugTracker\n"))
175 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
175 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
176 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
176 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
177 % util.version())
177 % util.version())
178 ui.warn(_("** Extensions loaded: %s\n")
178 ui.warn(_("** Extensions loaded: %s\n")
179 % ", ".join([x[0] for x in extensions.extensions()]))
179 % ", ".join([x[0] for x in extensions.extensions()]))
180 raise
180 raise
181
181
182 return -1
182 return -1
183
183
184 def aliasargs(fn):
184 def aliasargs(fn):
185 if hasattr(fn, 'args'):
185 if hasattr(fn, 'args'):
186 return fn.args
186 return fn.args
187 return []
187 return []
188
188
189 class cmdalias(object):
189 class cmdalias(object):
190 def __init__(self, name, definition, cmdtable):
190 def __init__(self, name, definition, cmdtable):
191 self.name = self.cmd = name
191 self.name = self.cmd = name
192 self.cmdname = ''
192 self.cmdname = ''
193 self.definition = definition
193 self.definition = definition
194 self.args = []
194 self.args = []
195 self.opts = []
195 self.opts = []
196 self.help = ''
196 self.help = ''
197 self.norepo = True
197 self.norepo = True
198 self.badalias = False
198 self.badalias = False
199
199
200 try:
200 try:
201 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
201 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
202 for alias, e in cmdtable.iteritems():
202 for alias, e in cmdtable.iteritems():
203 if e is entry:
203 if e is entry:
204 self.cmd = alias
204 self.cmd = alias
205 break
205 break
206 self.shadows = True
206 self.shadows = True
207 except error.UnknownCommand:
207 except error.UnknownCommand:
208 self.shadows = False
208 self.shadows = False
209
209
210 if not self.definition:
210 if not self.definition:
211 def fn(ui, *args):
211 def fn(ui, *args):
212 ui.warn(_("no definition for alias '%s'\n") % self.name)
212 ui.warn(_("no definition for alias '%s'\n") % self.name)
213 return 1
213 return 1
214 self.fn = fn
214 self.fn = fn
215 self.badalias = True
215 self.badalias = True
216
216
217 return
217 return
218
218
219 if self.definition.startswith('!'):
219 if self.definition.startswith('!'):
220 self.shell = True
220 self.shell = True
221 def fn(ui, *args):
221 def fn(ui, *args):
222 env = {'HG_ARGS': ' '.join((self.name,) + args)}
222 env = {'HG_ARGS': ' '.join((self.name,) + args)}
223 def _checkvar(m):
223 def _checkvar(m):
224 if m.groups()[0] == '$':
224 if m.groups()[0] == '$':
225 return m.group()
225 return m.group()
226 elif int(m.groups()[0]) <= len(args):
226 elif int(m.groups()[0]) <= len(args):
227 return m.group()
227 return m.group()
228 else:
228 else:
229 ui.debug(_("No argument found for substitution "
229 ui.debug(_("No argument found for substitution "
230 "of %i variable in alias '%s' definition.")
230 "of %i variable in alias '%s' definition.")
231 % (int(m.groups()[0]), self.name))
231 % (int(m.groups()[0]), self.name))
232 return ''
232 return ''
233 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
233 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
234 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
234 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
235 replace['0'] = self.name
235 replace['0'] = self.name
236 replace['@'] = ' '.join(args)
236 replace['@'] = ' '.join(args)
237 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
237 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
238 return util.system(cmd, environ=env)
238 return util.system(cmd, environ=env)
239 self.fn = fn
239 self.fn = fn
240 return
240 return
241
241
242 args = shlex.split(self.definition)
242 args = shlex.split(self.definition)
243 self.cmdname = cmd = args.pop(0)
243 self.cmdname = cmd = args.pop(0)
244 args = map(util.expandpath, args)
244 args = map(util.expandpath, args)
245
245
246 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
246 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
247 if _earlygetopt([invalidarg], args):
247 if _earlygetopt([invalidarg], args):
248 def fn(ui, *args):
248 def fn(ui, *args):
249 ui.warn(_("error in definition for alias '%s': %s may only "
249 ui.warn(_("error in definition for alias '%s': %s may only "
250 "be given on the command line\n")
250 "be given on the command line\n")
251 % (self.name, invalidarg))
251 % (self.name, invalidarg))
252 return 1
252 return 1
253
253
254 self.fn = fn
254 self.fn = fn
255 self.badalias = True
255 self.badalias = True
256 return
256 return
257
257
258 try:
258 try:
259 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
259 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
260 if len(tableentry) > 2:
260 if len(tableentry) > 2:
261 self.fn, self.opts, self.help = tableentry
261 self.fn, self.opts, self.help = tableentry
262 else:
262 else:
263 self.fn, self.opts = tableentry
263 self.fn, self.opts = tableentry
264
264
265 self.args = aliasargs(self.fn) + args
265 self.args = aliasargs(self.fn) + args
266 if cmd not in commands.norepo.split(' '):
266 if cmd not in commands.norepo.split(' '):
267 self.norepo = False
267 self.norepo = False
268 if self.help.startswith("hg " + cmd):
268 if self.help.startswith("hg " + cmd):
269 # drop prefix in old-style help lines so hg shows the alias
269 # drop prefix in old-style help lines so hg shows the alias
270 self.help = self.help[4 + len(cmd):]
270 self.help = self.help[4 + len(cmd):]
271 self.__doc__ = self.fn.__doc__
271 self.__doc__ = self.fn.__doc__
272
272
273 except error.UnknownCommand:
273 except error.UnknownCommand:
274 def fn(ui, *args):
274 def fn(ui, *args):
275 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
275 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
276 % (self.name, cmd))
276 % (self.name, cmd))
277 try:
277 try:
278 # check if the command is in a disabled extension
278 # check if the command is in a disabled extension
279 commands.help_(ui, cmd, unknowncmd=True)
279 commands.help_(ui, cmd, unknowncmd=True)
280 except error.UnknownCommand:
280 except error.UnknownCommand:
281 pass
281 pass
282 return 1
282 return 1
283 self.fn = fn
283 self.fn = fn
284 self.badalias = True
284 self.badalias = True
285 except error.AmbiguousCommand:
285 except error.AmbiguousCommand:
286 def fn(ui, *args):
286 def fn(ui, *args):
287 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
287 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
288 % (self.name, cmd))
288 % (self.name, cmd))
289 return 1
289 return 1
290 self.fn = fn
290 self.fn = fn
291 self.badalias = True
291 self.badalias = True
292
292
293 def __call__(self, ui, *args, **opts):
293 def __call__(self, ui, *args, **opts):
294 if self.shadows:
294 if self.shadows:
295 ui.debug("alias '%s' shadows command '%s'\n" %
295 ui.debug("alias '%s' shadows command '%s'\n" %
296 (self.name, self.cmdname))
296 (self.name, self.cmdname))
297
297
298 if hasattr(self, 'shell'):
298 if hasattr(self, 'shell'):
299 return self.fn(ui, *args, **opts)
299 return self.fn(ui, *args, **opts)
300 else:
300 else:
301 try:
301 try:
302 util.checksignature(self.fn)(ui, *args, **opts)
302 util.checksignature(self.fn)(ui, *args, **opts)
303 except error.SignatureError:
303 except error.SignatureError:
304 args = ' '.join([self.cmdname] + self.args)
304 args = ' '.join([self.cmdname] + self.args)
305 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
305 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
306 raise
306 raise
307
307
308 def addaliases(ui, cmdtable):
308 def addaliases(ui, cmdtable):
309 # aliases are processed after extensions have been loaded, so they
309 # aliases are processed after extensions have been loaded, so they
310 # may use extension commands. Aliases can also use other alias definitions,
310 # may use extension commands. Aliases can also use other alias definitions,
311 # but only if they have been defined prior to the current definition.
311 # but only if they have been defined prior to the current definition.
312 for alias, definition in ui.configitems('alias'):
312 for alias, definition in ui.configitems('alias'):
313 aliasdef = cmdalias(alias, definition, cmdtable)
313 aliasdef = cmdalias(alias, definition, cmdtable)
314 cmdtable[aliasdef.cmd] = (aliasdef, aliasdef.opts, aliasdef.help)
314 cmdtable[aliasdef.cmd] = (aliasdef, aliasdef.opts, aliasdef.help)
315 if aliasdef.norepo:
315 if aliasdef.norepo:
316 commands.norepo += ' %s' % alias
316 commands.norepo += ' %s' % alias
317
317
318 def _parse(ui, args):
318 def _parse(ui, args):
319 options = {}
319 options = {}
320 cmdoptions = {}
320 cmdoptions = {}
321
321
322 try:
322 try:
323 args = fancyopts.fancyopts(args, commands.globalopts, options)
323 args = fancyopts.fancyopts(args, commands.globalopts, options)
324 except fancyopts.getopt.GetoptError, inst:
324 except fancyopts.getopt.GetoptError, inst:
325 raise error.CommandError(None, inst)
325 raise error.CommandError(None, inst)
326
326
327 if args:
327 if args:
328 cmd, args = args[0], args[1:]
328 cmd, args = args[0], args[1:]
329 aliases, entry = cmdutil.findcmd(cmd, commands.table,
329 aliases, entry = cmdutil.findcmd(cmd, commands.table,
330 ui.config("ui", "strict"))
330 ui.config("ui", "strict"))
331 cmd = aliases[0]
331 cmd = aliases[0]
332 args = aliasargs(entry[0]) + args
332 args = aliasargs(entry[0]) + args
333 defaults = ui.config("defaults", cmd)
333 defaults = ui.config("defaults", cmd)
334 if defaults:
334 if defaults:
335 args = map(util.expandpath, shlex.split(defaults)) + args
335 args = map(util.expandpath, shlex.split(defaults)) + args
336 c = list(entry[1])
336 c = list(entry[1])
337 else:
337 else:
338 cmd = None
338 cmd = None
339 c = []
339 c = []
340
340
341 # combine global options into local
341 # combine global options into local
342 for o in commands.globalopts:
342 for o in commands.globalopts:
343 c.append((o[0], o[1], options[o[1]], o[3]))
343 c.append((o[0], o[1], options[o[1]], o[3]))
344
344
345 try:
345 try:
346 args = fancyopts.fancyopts(args, c, cmdoptions, True)
346 args = fancyopts.fancyopts(args, c, cmdoptions, True)
347 except fancyopts.getopt.GetoptError, inst:
347 except fancyopts.getopt.GetoptError, inst:
348 raise error.CommandError(cmd, inst)
348 raise error.CommandError(cmd, inst)
349
349
350 # separate global options back out
350 # separate global options back out
351 for o in commands.globalopts:
351 for o in commands.globalopts:
352 n = o[1]
352 n = o[1]
353 options[n] = cmdoptions[n]
353 options[n] = cmdoptions[n]
354 del cmdoptions[n]
354 del cmdoptions[n]
355
355
356 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
356 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
357
357
358 def _parseconfig(ui, config):
358 def _parseconfig(ui, config):
359 """parse the --config options from the command line"""
359 """parse the --config options from the command line"""
360 for cfg in config:
360 for cfg in config:
361 try:
361 try:
362 name, value = cfg.split('=', 1)
362 name, value = cfg.split('=', 1)
363 section, name = name.split('.', 1)
363 section, name = name.split('.', 1)
364 if not section or not name:
364 if not section or not name:
365 raise IndexError
365 raise IndexError
366 ui.setconfig(section, name, value)
366 ui.setconfig(section, name, value)
367 except (IndexError, ValueError):
367 except (IndexError, ValueError):
368 raise util.Abort(_('malformed --config option: %r '
368 raise util.Abort(_('malformed --config option: %r '
369 '(use --config section.name=value)') % cfg)
369 '(use --config section.name=value)') % cfg)
370
370
371 def _earlygetopt(aliases, args):
371 def _earlygetopt(aliases, args):
372 """Return list of values for an option (or aliases).
372 """Return list of values for an option (or aliases).
373
373
374 The values are listed in the order they appear in args.
374 The values are listed in the order they appear in args.
375 The options and values are removed from args.
375 The options and values are removed from args.
376 """
376 """
377 try:
377 try:
378 argcount = args.index("--")
378 argcount = args.index("--")
379 except ValueError:
379 except ValueError:
380 argcount = len(args)
380 argcount = len(args)
381 shortopts = [opt for opt in aliases if len(opt) == 2]
381 shortopts = [opt for opt in aliases if len(opt) == 2]
382 values = []
382 values = []
383 pos = 0
383 pos = 0
384 while pos < argcount:
384 while pos < argcount:
385 if args[pos] in aliases:
385 if args[pos] in aliases:
386 if pos + 1 >= argcount:
386 if pos + 1 >= argcount:
387 # ignore and let getopt report an error if there is no value
387 # ignore and let getopt report an error if there is no value
388 break
388 break
389 del args[pos]
389 del args[pos]
390 values.append(args.pop(pos))
390 values.append(args.pop(pos))
391 argcount -= 2
391 argcount -= 2
392 elif args[pos][:2] in shortopts:
392 elif args[pos][:2] in shortopts:
393 # short option can have no following space, e.g. hg log -Rfoo
393 # short option can have no following space, e.g. hg log -Rfoo
394 values.append(args.pop(pos)[2:])
394 values.append(args.pop(pos)[2:])
395 argcount -= 1
395 argcount -= 1
396 else:
396 else:
397 pos += 1
397 pos += 1
398 return values
398 return values
399
399
400 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
400 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
401 # run pre-hook, and abort if it fails
401 # run pre-hook, and abort if it fails
402 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
402 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
403 pats=cmdpats, opts=cmdoptions)
403 pats=cmdpats, opts=cmdoptions)
404 if ret:
404 if ret:
405 return ret
405 return ret
406 ret = _runcommand(ui, options, cmd, d)
406 ret = _runcommand(ui, options, cmd, d)
407 # run post-hook, passing command result
407 # run post-hook, passing command result
408 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
408 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
409 result=ret, pats=cmdpats, opts=cmdoptions)
409 result=ret, pats=cmdpats, opts=cmdoptions)
410 return ret
410 return ret
411
411
412 def _getlocal(ui, rpath):
412 def _getlocal(ui, rpath):
413 """Return (path, local ui object) for the given target path.
413 """Return (path, local ui object) for the given target path.
414
414
415 Takes paths in [cwd]/.hg/hgrc into account."
415 Takes paths in [cwd]/.hg/hgrc into account."
416 """
416 """
417 try:
417 try:
418 wd = os.getcwd()
418 wd = os.getcwd()
419 except OSError, e:
419 except OSError, e:
420 raise util.Abort(_("error getting current working directory: %s") %
420 raise util.Abort(_("error getting current working directory: %s") %
421 e.strerror)
421 e.strerror)
422 path = cmdutil.findrepo(wd) or ""
422 path = cmdutil.findrepo(wd) or ""
423 if not path:
423 if not path:
424 lui = ui
424 lui = ui
425 else:
425 else:
426 lui = ui.copy()
426 lui = ui.copy()
427 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
427 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
428
428
429 if rpath:
429 if rpath:
430 path = lui.expandpath(rpath[-1])
430 path = lui.expandpath(rpath[-1])
431 lui = ui.copy()
431 lui = ui.copy()
432 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
432 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
433
433
434 return path, lui
434 return path, lui
435
435
436 def _checkshellalias(ui, args):
436 def _checkshellalias(ui, args):
437 cwd = os.getcwd()
437 cwd = os.getcwd()
438 norepo = commands.norepo
438 norepo = commands.norepo
439 options = {}
439 options = {}
440
440
441 try:
441 try:
442 args = fancyopts.fancyopts(args, commands.globalopts, options)
442 args = fancyopts.fancyopts(args, commands.globalopts, options)
443 except fancyopts.getopt.GetoptError:
443 except fancyopts.getopt.GetoptError:
444 return
444 return
445
445
446 if not args:
446 if not args:
447 return
447 return
448
448
449 _parseconfig(ui, options['config'])
449 _parseconfig(ui, options['config'])
450 if options['cwd']:
450 if options['cwd']:
451 os.chdir(options['cwd'])
451 os.chdir(options['cwd'])
452
452
453 path, lui = _getlocal(ui, [options['repository']])
453 path, lui = _getlocal(ui, [options['repository']])
454
454
455 cmdtable = commands.table.copy()
455 cmdtable = commands.table.copy()
456 addaliases(lui, cmdtable)
456 addaliases(lui, cmdtable)
457
457
458 cmd = args[0]
458 cmd = args[0]
459 try:
459 try:
460 aliases, entry = cmdutil.findcmd(cmd, cmdtable, lui.config("ui", "strict"))
460 aliases, entry = cmdutil.findcmd(cmd, cmdtable, lui.config("ui", "strict"))
461 except (error.AmbiguousCommand, error.UnknownCommand):
461 except (error.AmbiguousCommand, error.UnknownCommand):
462 commands.norepo = norepo
462 commands.norepo = norepo
463 os.chdir(cwd)
463 os.chdir(cwd)
464 return
464 return
465
465
466 cmd = aliases[0]
466 cmd = aliases[0]
467 fn = entry[0]
467 fn = entry[0]
468
468
469 if cmd and hasattr(fn, 'shell'):
469 if cmd and hasattr(fn, 'shell'):
470 d = lambda: fn(ui, *args[1:])
470 d = lambda: fn(ui, *args[1:])
471 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
471 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
472
472
473 commands.norepo = norepo
473 commands.norepo = norepo
474 os.chdir(cwd)
474 os.chdir(cwd)
475
475
476 _loaded = set()
476 _loaded = set()
477 def _dispatch(ui, args):
477 def _dispatch(ui, args):
478 shellaliasfn = _checkshellalias(ui, args)
478 shellaliasfn = _checkshellalias(ui, args)
479 if shellaliasfn:
479 if shellaliasfn:
480 return shellaliasfn()
480 return shellaliasfn()
481
481
482 # read --config before doing anything else
482 # read --config before doing anything else
483 # (e.g. to change trust settings for reading .hg/hgrc)
483 # (e.g. to change trust settings for reading .hg/hgrc)
484 _parseconfig(ui, _earlygetopt(['--config'], args))
484 _parseconfig(ui, _earlygetopt(['--config'], args))
485
485
486 # check for cwd
486 # check for cwd
487 cwd = _earlygetopt(['--cwd'], args)
487 cwd = _earlygetopt(['--cwd'], args)
488 if cwd:
488 if cwd:
489 os.chdir(cwd[-1])
489 os.chdir(cwd[-1])
490
490
491 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
491 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
492 path, lui = _getlocal(ui, rpath)
492 path, lui = _getlocal(ui, rpath)
493
493
494 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
494 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
495 # reposetup. Programs like TortoiseHg will call _dispatch several
495 # reposetup. Programs like TortoiseHg will call _dispatch several
496 # times so we keep track of configured extensions in _loaded.
496 # times so we keep track of configured extensions in _loaded.
497 extensions.loadall(lui)
497 extensions.loadall(lui)
498 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
498 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
499 # Propagate any changes to lui.__class__ by extensions
499 # Propagate any changes to lui.__class__ by extensions
500 ui.__class__ = lui.__class__
500 ui.__class__ = lui.__class__
501
501
502 # (uisetup and extsetup are handled in extensions.loadall)
502 # (uisetup and extsetup are handled in extensions.loadall)
503
503
504 for name, module in exts:
504 for name, module in exts:
505 cmdtable = getattr(module, 'cmdtable', {})
505 cmdtable = getattr(module, 'cmdtable', {})
506 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
506 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
507 if overrides:
507 if overrides:
508 ui.warn(_("extension '%s' overrides commands: %s\n")
508 ui.warn(_("extension '%s' overrides commands: %s\n")
509 % (name, " ".join(overrides)))
509 % (name, " ".join(overrides)))
510 commands.table.update(cmdtable)
510 commands.table.update(cmdtable)
511 _loaded.add(name)
511 _loaded.add(name)
512
512
513 # (reposetup is handled in hg.repository)
513 # (reposetup is handled in hg.repository)
514
514
515 addaliases(lui, commands.table)
515 addaliases(lui, commands.table)
516
516
517 # check for fallback encoding
517 # check for fallback encoding
518 fallback = lui.config('ui', 'fallbackencoding')
518 fallback = lui.config('ui', 'fallbackencoding')
519 if fallback:
519 if fallback:
520 encoding.fallbackencoding = fallback
520 encoding.fallbackencoding = fallback
521
521
522 fullargs = args
522 fullargs = args
523 cmd, func, args, options, cmdoptions = _parse(lui, args)
523 cmd, func, args, options, cmdoptions = _parse(lui, args)
524
524
525 if options["config"]:
525 if options["config"]:
526 raise util.Abort(_("option --config may not be abbreviated!"))
526 raise util.Abort(_("option --config may not be abbreviated!"))
527 if options["cwd"]:
527 if options["cwd"]:
528 raise util.Abort(_("option --cwd may not be abbreviated!"))
528 raise util.Abort(_("option --cwd may not be abbreviated!"))
529 if options["repository"]:
529 if options["repository"]:
530 raise util.Abort(_(
530 raise util.Abort(_(
531 "Option -R has to be separated from other options (e.g. not -qR) "
531 "Option -R has to be separated from other options (e.g. not -qR) "
532 "and --repository may only be abbreviated as --repo!"))
532 "and --repository may only be abbreviated as --repo!"))
533
533
534 if options["encoding"]:
534 if options["encoding"]:
535 encoding.encoding = options["encoding"]
535 encoding.encoding = options["encoding"]
536 if options["encodingmode"]:
536 if options["encodingmode"]:
537 encoding.encodingmode = options["encodingmode"]
537 encoding.encodingmode = options["encodingmode"]
538 if options["time"]:
538 if options["time"]:
539 def get_times():
539 def get_times():
540 t = os.times()
540 t = os.times()
541 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
541 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
542 t = (t[0], t[1], t[2], t[3], time.clock())
542 t = (t[0], t[1], t[2], t[3], time.clock())
543 return t
543 return t
544 s = get_times()
544 s = get_times()
545 def print_time():
545 def print_time():
546 t = get_times()
546 t = get_times()
547 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
547 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
548 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
548 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
549 atexit.register(print_time)
549 atexit.register(print_time)
550
550
551 if options['verbose'] or options['debug'] or options['quiet']:
551 if options['verbose'] or options['debug'] or options['quiet']:
552 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
552 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
553 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
553 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
554 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
554 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
555 if options['traceback']:
555 if options['traceback']:
556 ui.setconfig('ui', 'traceback', 'on')
556 ui.setconfig('ui', 'traceback', 'on')
557 if options['noninteractive']:
557 if options['noninteractive']:
558 ui.setconfig('ui', 'interactive', 'off')
558 ui.setconfig('ui', 'interactive', 'off')
559
559
560 if cmdoptions.get('insecure', False):
560 if cmdoptions.get('insecure', False):
561 ui.setconfig('web', 'cacerts', '')
561 ui.setconfig('web', 'cacerts', '')
562
562
563 if options['help']:
563 if options['help']:
564 return commands.help_(ui, cmd, options['version'])
564 return commands.help_(ui, cmd, options['version'])
565 elif options['version']:
565 elif options['version']:
566 return commands.version_(ui)
566 return commands.version_(ui)
567 elif not cmd:
567 elif not cmd:
568 return commands.help_(ui, 'shortlist')
568 return commands.help_(ui, 'shortlist')
569
569
570 repo = None
570 repo = None
571 cmdpats = args[:]
571 cmdpats = args[:]
572 if cmd not in commands.norepo.split():
572 if cmd not in commands.norepo.split():
573 try:
573 try:
574 repo = hg.repository(ui, path=path)
574 repo = hg.repository(ui, path=path)
575 ui = repo.ui
575 ui = repo.ui
576 if not repo.local():
576 if not repo.local():
577 raise util.Abort(_("repository '%s' is not local") % path)
577 raise util.Abort(_("repository '%s' is not local") % path)
578 ui.setconfig("bundle", "mainreporoot", repo.root)
578 ui.setconfig("bundle", "mainreporoot", repo.root)
579 except error.RequirementError:
579 except error.RequirementError:
580 raise
580 raise
581 except error.RepoError:
581 except error.RepoError:
582 if cmd not in commands.optionalrepo.split():
582 if cmd not in commands.optionalrepo.split():
583 if args and not path: # try to infer -R from command args
583 if args and not path: # try to infer -R from command args
584 repos = map(cmdutil.findrepo, args)
584 repos = map(cmdutil.findrepo, args)
585 guess = repos[0]
585 guess = repos[0]
586 if guess and repos.count(guess) == len(repos):
586 if guess and repos.count(guess) == len(repos):
587 return _dispatch(ui, ['--repository', guess] + fullargs)
587 return _dispatch(ui, ['--repository', guess] + fullargs)
588 if not path:
588 if not path:
589 raise error.RepoError(_("There is no Mercurial repository"
589 raise error.RepoError(_("There is no Mercurial repository"
590 " here (.hg not found)"))
590 " here (.hg not found)"))
591 raise
591 raise
592 args.insert(0, repo)
592 args.insert(0, repo)
593 elif rpath:
593 elif rpath:
594 ui.warn(_("warning: --repository ignored\n"))
594 ui.warn(_("warning: --repository ignored\n"))
595
595
596 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
596 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
597 ui.log("command", msg + "\n")
597 ui.log("command", msg + "\n")
598 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
598 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
599 try:
599 try:
600 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
600 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
601 cmdpats, cmdoptions)
601 cmdpats, cmdoptions)
602 finally:
602 finally:
603 if repo:
603 if repo:
604 repo.close()
604 repo.close()
605
605
606 def _runcommand(ui, options, cmd, cmdfunc):
606 def _runcommand(ui, options, cmd, cmdfunc):
607 def checkargs():
607 def checkargs():
608 try:
608 try:
609 return cmdfunc()
609 return cmdfunc()
610 except error.SignatureError:
610 except error.SignatureError:
611 raise error.CommandError(cmd, _("invalid arguments"))
611 raise error.CommandError(cmd, _("invalid arguments"))
612
612
613 if options['profile']:
613 if options['profile']:
614 format = ui.config('profiling', 'format', default='text')
614 format = ui.config('profiling', 'format', default='text')
615
615
616 if not format in ['text', 'kcachegrind']:
616 if not format in ['text', 'kcachegrind']:
617 ui.warn(_("unrecognized profiling format '%s'"
617 ui.warn(_("unrecognized profiling format '%s'"
618 " - Ignored\n") % format)
618 " - Ignored\n") % format)
619 format = 'text'
619 format = 'text'
620
620
621 output = ui.config('profiling', 'output')
621 output = ui.config('profiling', 'output')
622
622
623 if output:
623 if output:
624 path = ui.expandpath(output)
624 path = ui.expandpath(output)
625 ostream = open(path, 'wb')
625 ostream = open(path, 'wb')
626 else:
626 else:
627 ostream = sys.stderr
627 ostream = sys.stderr
628
628
629 try:
629 try:
630 from mercurial import lsprof
630 from mercurial import lsprof
631 except ImportError:
631 except ImportError:
632 raise util.Abort(_(
632 raise util.Abort(_(
633 'lsprof not available - install from '
633 'lsprof not available - install from '
634 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
634 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
635 p = lsprof.Profiler()
635 p = lsprof.Profiler()
636 p.enable(subcalls=True)
636 p.enable(subcalls=True)
637 try:
637 try:
638 return checkargs()
638 return checkargs()
639 finally:
639 finally:
640 p.disable()
640 p.disable()
641
641
642 if format == 'kcachegrind':
642 if format == 'kcachegrind':
643 import lsprofcalltree
643 import lsprofcalltree
644 calltree = lsprofcalltree.KCacheGrind(p)
644 calltree = lsprofcalltree.KCacheGrind(p)
645 calltree.output(ostream)
645 calltree.output(ostream)
646 else:
646 else:
647 # format == 'text'
647 # format == 'text'
648 stats = lsprof.Stats(p.getstats())
648 stats = lsprof.Stats(p.getstats())
649 stats.sort()
649 stats.sort()
650 stats.pprint(top=10, file=ostream, climit=5)
650 stats.pprint(top=10, file=ostream, climit=5)
651
651
652 if output:
652 if output:
653 ostream.close()
653 ostream.close()
654 else:
654 else:
655 return checkargs()
655 return checkargs()
@@ -1,396 +1,390 b''
1 $ HGFOO=BAR; export HGFOO
1 $ HGFOO=BAR; export HGFOO
2 $ cat >> $HGRCPATH <<EOF
2 $ cat >> $HGRCPATH <<EOF
3 > [extensions]
3 > [extensions]
4 > graphlog=
4 > graphlog=
5 >
5 >
6 > [alias]
6 > [alias]
7 > myinit = init
7 > myinit = init
8 > cleanstatus = status -c
8 > cleanstatus = status -c
9 > unknown = bargle
9 > unknown = bargle
10 > ambiguous = s
10 > ambiguous = s
11 > recursive = recursive
11 > recursive = recursive
12 > nodefinition =
12 > nodefinition =
13 > no--cwd = status --cwd elsewhere
13 > no--cwd = status --cwd elsewhere
14 > no-R = status -R elsewhere
14 > no-R = status -R elsewhere
15 > no--repo = status --repo elsewhere
15 > no--repo = status --repo elsewhere
16 > no--repository = status --repository elsewhere
16 > no--repository = status --repository elsewhere
17 > mylog = log
17 > mylog = log
18 > lognull = log -r null
18 > lognull = log -r null
19 > shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
19 > shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
20 > dln = lognull --debug
20 > dln = lognull --debug
21 > nousage = rollback
21 > nousage = rollback
22 > put = export -r 0 -o "\$FOO/%R.diff"
22 > put = export -r 0 -o "\$FOO/%R.diff"
23 > blank = !echo
23 > blank = !echo
24 > self = !echo '\$0'
24 > self = !echo '\$0'
25 > echo = !echo '\$@'
25 > echo = !echo '\$@'
26 > echo1 = !echo '\$1'
26 > echo1 = !echo '\$1'
27 > echo2 = !echo '\$2'
27 > echo2 = !echo '\$2'
28 > echo13 = !echo '\$1' '\$3'
28 > echo13 = !echo '\$1' '\$3'
29 > count = !hg log -r '\$@' --template='.' | wc -c | sed -e 's/ //g'
29 > count = !hg log -r '\$@' --template='.' | wc -c | sed -e 's/ //g'
30 > mcount = !hg log \$@ --template='.' | wc -c | sed -e 's/ //g'
30 > mcount = !hg log \$@ --template='.' | wc -c | sed -e 's/ //g'
31 > rt = root
31 > rt = root
32 > tglog = glog --template "{rev}:{node|short}: '{desc}' {branches}\n"
32 > tglog = glog --template "{rev}:{node|short}: '{desc}' {branches}\n"
33 > idalias = id
33 > idalias = id
34 > idaliaslong = id
34 > idaliaslong = id
35 > idaliasshell = !echo test
35 > idaliasshell = !echo test
36 > parentsshell1 = !echo one
36 > parentsshell1 = !echo one
37 > parentsshell2 = !echo two
37 > parentsshell2 = !echo two
38 > escaped1 = !echo 'test\$\$test'
38 > escaped1 = !echo 'test\$\$test'
39 > escaped2 = !echo "HGFOO is \$\$HGFOO"
39 > escaped2 = !echo "HGFOO is \$\$HGFOO"
40 > escaped3 = !echo "\$1 is \$\$\$1"
40 > escaped3 = !echo "\$1 is \$\$\$1"
41 > escaped4 = !echo '\$\$0' '\$\$@'
41 > escaped4 = !echo '\$\$0' '\$\$@'
42 >
42 >
43 > [defaults]
43 > [defaults]
44 > mylog = -q
44 > mylog = -q
45 > lognull = -q
45 > lognull = -q
46 > log = -v
46 > log = -v
47 > EOF
47 > EOF
48
48
49
49
50 basic
50 basic
51
51
52 $ hg myinit alias
52 $ hg myinit alias
53
53
54
54
55 unknown
55 unknown
56
56
57 $ hg unknown
57 $ hg unknown
58 alias 'unknown' resolves to unknown command 'bargle'
58 alias 'unknown' resolves to unknown command 'bargle'
59 $ hg help unknown
59 $ hg help unknown
60 alias 'unknown' resolves to unknown command 'bargle'
60 alias 'unknown' resolves to unknown command 'bargle'
61
61
62
62
63 ambiguous
63 ambiguous
64
64
65 $ hg ambiguous
65 $ hg ambiguous
66 alias 'ambiguous' resolves to ambiguous command 's'
66 alias 'ambiguous' resolves to ambiguous command 's'
67 $ hg help ambiguous
67 $ hg help ambiguous
68 alias 'ambiguous' resolves to ambiguous command 's'
68 alias 'ambiguous' resolves to ambiguous command 's'
69
69
70
70
71 recursive
71 recursive
72
72
73 $ hg recursive
73 $ hg recursive
74 alias 'recursive' resolves to unknown command 'recursive'
74 alias 'recursive' resolves to unknown command 'recursive'
75 $ hg help recursive
75 $ hg help recursive
76 alias 'recursive' resolves to unknown command 'recursive'
76 alias 'recursive' resolves to unknown command 'recursive'
77
77
78
78
79 no definition
79 no definition
80
80
81 $ hg nodef
81 $ hg nodef
82 no definition for alias 'nodefinition'
82 no definition for alias 'nodefinition'
83 $ hg help nodef
83 $ hg help nodef
84 no definition for alias 'nodefinition'
84 no definition for alias 'nodefinition'
85
85
86
86
87 invalid options
87 invalid options
88
88
89 $ hg no--cwd
89 $ hg no--cwd
90 error in definition for alias 'no--cwd': --cwd may only be given on the command line
90 error in definition for alias 'no--cwd': --cwd may only be given on the command line
91 $ hg help no--cwd
91 $ hg help no--cwd
92 error in definition for alias 'no--cwd': --cwd may only be given on the command line
92 error in definition for alias 'no--cwd': --cwd may only be given on the command line
93 $ hg no-R
93 $ hg no-R
94 error in definition for alias 'no-R': -R may only be given on the command line
94 error in definition for alias 'no-R': -R may only be given on the command line
95 $ hg help no-R
95 $ hg help no-R
96 error in definition for alias 'no-R': -R may only be given on the command line
96 error in definition for alias 'no-R': -R may only be given on the command line
97 $ hg no--repo
97 $ hg no--repo
98 error in definition for alias 'no--repo': --repo may only be given on the command line
98 error in definition for alias 'no--repo': --repo may only be given on the command line
99 $ hg help no--repo
99 $ hg help no--repo
100 error in definition for alias 'no--repo': --repo may only be given on the command line
100 error in definition for alias 'no--repo': --repo may only be given on the command line
101 $ hg no--repository
101 $ hg no--repository
102 error in definition for alias 'no--repository': --repository may only be given on the command line
102 error in definition for alias 'no--repository': --repository may only be given on the command line
103 $ hg help no--repository
103 $ hg help no--repository
104 error in definition for alias 'no--repository': --repository may only be given on the command line
104 error in definition for alias 'no--repository': --repository may only be given on the command line
105
105
106 $ cd alias
106 $ cd alias
107
107
108
108
109 no usage
109 no usage
110
110
111 $ hg nousage
111 $ hg nousage
112 no rollback information available
112 no rollback information available
113
113
114 $ echo foo > foo
114 $ echo foo > foo
115 $ hg ci -Amfoo
115 $ hg ci -Amfoo
116 adding foo
116 adding foo
117
117
118
118
119 with opts
119 with opts
120
120
121 $ hg cleanst
121 $ hg cleanst
122 C foo
122 C foo
123
123
124
124
125 with opts and whitespace
125 with opts and whitespace
126
126
127 $ hg shortlog
127 $ hg shortlog
128 0 e63c23eaa88a | 1970-01-01 00:00 +0000
128 0 e63c23eaa88a | 1970-01-01 00:00 +0000
129
129
130
130
131 interaction with defaults
131 interaction with defaults
132
132
133 $ hg mylog
133 $ hg mylog
134 0:e63c23eaa88a
134 0:e63c23eaa88a
135 $ hg lognull
135 $ hg lognull
136 -1:000000000000
136 -1:000000000000
137
137
138
138
139 properly recursive
139 properly recursive
140
140
141 $ hg dln
141 $ hg dln
142 changeset: -1:0000000000000000000000000000000000000000
142 changeset: -1:0000000000000000000000000000000000000000
143 parent: -1:0000000000000000000000000000000000000000
143 parent: -1:0000000000000000000000000000000000000000
144 parent: -1:0000000000000000000000000000000000000000
144 parent: -1:0000000000000000000000000000000000000000
145 manifest: -1:0000000000000000000000000000000000000000
145 manifest: -1:0000000000000000000000000000000000000000
146 user:
146 user:
147 date: Thu Jan 01 00:00:00 1970 +0000
147 date: Thu Jan 01 00:00:00 1970 +0000
148 extra: branch=default
148 extra: branch=default
149
149
150
150
151
151
152 path expanding
152 path expanding
153
153
154 $ FOO=`pwd` hg put
154 $ FOO=`pwd` hg put
155 $ cat 0.diff
155 $ cat 0.diff
156 # HG changeset patch
156 # HG changeset patch
157 # User test
157 # User test
158 # Date 0 0
158 # Date 0 0
159 # Node ID e63c23eaa88ae77967edcf4ea194d31167c478b0
159 # Node ID e63c23eaa88ae77967edcf4ea194d31167c478b0
160 # Parent 0000000000000000000000000000000000000000
160 # Parent 0000000000000000000000000000000000000000
161 foo
161 foo
162
162
163 diff -r 000000000000 -r e63c23eaa88a foo
163 diff -r 000000000000 -r e63c23eaa88a foo
164 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
164 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
165 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
165 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
166 @@ -0,0 +1,1 @@
166 @@ -0,0 +1,1 @@
167 +foo
167 +foo
168
168
169
169
170 simple shell aliases
170 simple shell aliases
171
171
172 $ hg blank
172 $ hg blank
173
173
174 $ hg blank foo
174 $ hg blank foo
175
175
176 $ hg self
176 $ hg self
177 self
177 self
178 $ hg echo
178 $ hg echo
179
179
180 $ hg echo foo
180 $ hg echo foo
181 foo
181 foo
182 $ hg echo 'test $2' foo
182 $ hg echo 'test $2' foo
183 test $2 foo
183 test $2 foo
184 $ hg echo1 foo bar baz
184 $ hg echo1 foo bar baz
185 foo
185 foo
186 $ hg echo2 foo bar baz
186 $ hg echo2 foo bar baz
187 bar
187 bar
188 $ hg echo13 foo bar baz test
188 $ hg echo13 foo bar baz test
189 foo baz
189 foo baz
190 $ hg echo2 foo
190 $ hg echo2 foo
191
191
192 $ echo bar > bar
192 $ echo bar > bar
193 $ hg ci -qA -m bar
193 $ hg ci -qA -m bar
194 $ hg count .
194 $ hg count .
195 1
195 1
196 $ hg count 'branch(default)'
196 $ hg count 'branch(default)'
197 2
197 2
198 $ hg mcount -r '"branch(default)"'
198 $ hg mcount -r '"branch(default)"'
199 2
199 2
200
200
201 $ hg tglog
201 $ hg tglog
202 @ 1:7e7f92de180e: 'bar'
202 @ 1:7e7f92de180e: 'bar'
203 |
203 |
204 o 0:e63c23eaa88a: 'foo'
204 o 0:e63c23eaa88a: 'foo'
205
205
206
206
207
207
208 shadowing
208 shadowing
209
209
210 $ hg i
210 $ hg i
211 hg: command 'i' is ambiguous:
211 hg: command 'i' is ambiguous:
212 idalias idaliaslong idaliasshell identify import incoming init
212 idalias idaliaslong idaliasshell identify import incoming init
213 [255]
213 [255]
214 $ hg id
214 $ hg id
215 7e7f92de180e tip
215 7e7f92de180e tip
216 $ hg ida
216 $ hg ida
217 hg: command 'ida' is ambiguous:
217 hg: command 'ida' is ambiguous:
218 idalias idaliaslong idaliasshell
218 idalias idaliaslong idaliasshell
219 [255]
219 [255]
220 $ hg idalias
220 $ hg idalias
221 7e7f92de180e tip
221 7e7f92de180e tip
222 $ hg idaliasl
222 $ hg idaliasl
223 7e7f92de180e tip
223 7e7f92de180e tip
224 $ hg idaliass
224 $ hg idaliass
225 test
225 test
226 $ hg parentsshell
226 $ hg parentsshell
227 hg: command 'parentsshell' is ambiguous:
227 hg: command 'parentsshell' is ambiguous:
228 parentsshell1 parentsshell2
228 parentsshell1 parentsshell2
229 [255]
229 [255]
230 $ hg parentsshell1
230 $ hg parentsshell1
231 one
231 one
232 $ hg parentsshell2
232 $ hg parentsshell2
233 two
233 two
234
234
235
235
236 shell aliases with global options
236 shell aliases with global options
237
237
238 $ hg init sub
238 $ hg init sub
239 $ cd sub
239 $ cd sub
240 $ hg count 'branch(default)'
240 $ hg count 'branch(default)'
241 0
241 0
242 $ hg -v count 'branch(default)'
242 $ hg -v count 'branch(default)'
243 0
243 0
244 $ hg -R .. count 'branch(default)'
244 $ hg -R .. count 'branch(default)'
245 0
245 0
246 $ hg --cwd .. count 'branch(default)'
246 $ hg --cwd .. count 'branch(default)'
247 2
247 2
248 $ hg echo --cwd ..
248 $ hg echo --cwd ..
249 --cwd ..
249 --cwd ..
250
250
251
251
252 repo specific shell aliases
252 repo specific shell aliases
253
253
254 $ cat >> .hg/hgrc <<EOF
254 $ cat >> .hg/hgrc <<EOF
255 > [alias]
255 > [alias]
256 > subalias = !echo sub \$@
256 > subalias = !echo sub \$@
257 > EOF
257 > EOF
258 $ cat >> ../.hg/hgrc <<EOF
258 $ cat >> ../.hg/hgrc <<EOF
259 > [alias]
259 > [alias]
260 > mainalias = !echo main \$@
260 > mainalias = !echo main \$@
261 > EOF
261 > EOF
262
262
263
263
264 shell alias defined in current repo
264 shell alias defined in current repo
265
265
266 $ hg subalias
266 $ hg subalias
267 sub
267 sub
268 $ hg --cwd .. subalias > /dev/null
268 $ hg --cwd .. subalias > /dev/null
269 hg: unknown command 'subalias'
269 hg: unknown command 'subalias'
270 [255]
270 [255]
271 $ hg -R .. subalias > /dev/null
271 $ hg -R .. subalias > /dev/null
272 hg: unknown command 'subalias'
272 hg: unknown command 'subalias'
273 [255]
273 [255]
274
274
275
275
276 shell alias defined in other repo
276 shell alias defined in other repo
277
277
278 $ hg mainalias > /dev/null
278 $ hg mainalias > /dev/null
279 hg: unknown command 'mainalias'
279 hg: unknown command 'mainalias'
280 [255]
280 [255]
281 $ hg -R .. mainalias
281 $ hg -R .. mainalias
282 main
282 main
283 $ hg --cwd .. mainalias
283 $ hg --cwd .. mainalias
284 main
284 main
285
285
286
286
287 shell aliases with escaped $ chars
287 shell aliases with escaped $ chars
288
288
289 $ hg escaped1
289 $ hg escaped1
290 test$test
290 test$test
291 $ hg escaped2
291 $ hg escaped2
292 HGFOO is BAR
292 HGFOO is BAR
293 $ hg escaped3 HGFOO
293 $ hg escaped3 HGFOO
294 HGFOO is BAR
294 HGFOO is BAR
295 $ hg escaped4 test
295 $ hg escaped4 test
296 $0 $@
296 $0 $@
297
297
298
298
299 invalid arguments
299 invalid arguments
300
300
301 $ hg rt foo
301 $ hg rt foo
302 hg rt: invalid arguments
302 hg rt: invalid arguments
303 hg rt
303 hg rt
304
304
305 alias for: hg root
305 alias for: hg root
306
306
307 print the root (top) of the current working directory
307 use "hg help rt" to show the full help text
308
309 Print the root directory of the current repository.
310
311 Returns 0 on success.
312
313 use "hg -v help rt" to show global options
314 [255]
308 [255]
315
309
316 invalid global arguments for normal commands, aliases, and shell aliases
310 invalid global arguments for normal commands, aliases, and shell aliases
317
311
318 $ hg --invalid root
312 $ hg --invalid root
319 hg: option --invalid not recognized
313 hg: option --invalid not recognized
320 Mercurial Distributed SCM
314 Mercurial Distributed SCM
321
315
322 basic commands:
316 basic commands:
323
317
324 add add the specified files on the next commit
318 add add the specified files on the next commit
325 annotate show changeset information by line for each file
319 annotate show changeset information by line for each file
326 clone make a copy of an existing repository
320 clone make a copy of an existing repository
327 commit commit the specified files or all outstanding changes
321 commit commit the specified files or all outstanding changes
328 diff diff repository (or selected files)
322 diff diff repository (or selected files)
329 export dump the header and diffs for one or more changesets
323 export dump the header and diffs for one or more changesets
330 forget forget the specified files on the next commit
324 forget forget the specified files on the next commit
331 init create a new repository in the given directory
325 init create a new repository in the given directory
332 log show revision history of entire repository or files
326 log show revision history of entire repository or files
333 merge merge working directory with another revision
327 merge merge working directory with another revision
334 pull pull changes from the specified source
328 pull pull changes from the specified source
335 push push changes to the specified destination
329 push push changes to the specified destination
336 remove remove the specified files on the next commit
330 remove remove the specified files on the next commit
337 serve start stand-alone webserver
331 serve start stand-alone webserver
338 status show changed files in the working directory
332 status show changed files in the working directory
339 summary summarize working directory state
333 summary summarize working directory state
340 update update working directory (or switch revisions)
334 update update working directory (or switch revisions)
341
335
342 use "hg help" for the full list of commands or "hg -v" for details
336 use "hg help" for the full list of commands or "hg -v" for details
343 [255]
337 [255]
344 $ hg --invalid mylog
338 $ hg --invalid mylog
345 hg: option --invalid not recognized
339 hg: option --invalid not recognized
346 Mercurial Distributed SCM
340 Mercurial Distributed SCM
347
341
348 basic commands:
342 basic commands:
349
343
350 add add the specified files on the next commit
344 add add the specified files on the next commit
351 annotate show changeset information by line for each file
345 annotate show changeset information by line for each file
352 clone make a copy of an existing repository
346 clone make a copy of an existing repository
353 commit commit the specified files or all outstanding changes
347 commit commit the specified files or all outstanding changes
354 diff diff repository (or selected files)
348 diff diff repository (or selected files)
355 export dump the header and diffs for one or more changesets
349 export dump the header and diffs for one or more changesets
356 forget forget the specified files on the next commit
350 forget forget the specified files on the next commit
357 init create a new repository in the given directory
351 init create a new repository in the given directory
358 log show revision history of entire repository or files
352 log show revision history of entire repository or files
359 merge merge working directory with another revision
353 merge merge working directory with another revision
360 pull pull changes from the specified source
354 pull pull changes from the specified source
361 push push changes to the specified destination
355 push push changes to the specified destination
362 remove remove the specified files on the next commit
356 remove remove the specified files on the next commit
363 serve start stand-alone webserver
357 serve start stand-alone webserver
364 status show changed files in the working directory
358 status show changed files in the working directory
365 summary summarize working directory state
359 summary summarize working directory state
366 update update working directory (or switch revisions)
360 update update working directory (or switch revisions)
367
361
368 use "hg help" for the full list of commands or "hg -v" for details
362 use "hg help" for the full list of commands or "hg -v" for details
369 [255]
363 [255]
370 $ hg --invalid blank
364 $ hg --invalid blank
371 hg: option --invalid not recognized
365 hg: option --invalid not recognized
372 Mercurial Distributed SCM
366 Mercurial Distributed SCM
373
367
374 basic commands:
368 basic commands:
375
369
376 add add the specified files on the next commit
370 add add the specified files on the next commit
377 annotate show changeset information by line for each file
371 annotate show changeset information by line for each file
378 clone make a copy of an existing repository
372 clone make a copy of an existing repository
379 commit commit the specified files or all outstanding changes
373 commit commit the specified files or all outstanding changes
380 diff diff repository (or selected files)
374 diff diff repository (or selected files)
381 export dump the header and diffs for one or more changesets
375 export dump the header and diffs for one or more changesets
382 forget forget the specified files on the next commit
376 forget forget the specified files on the next commit
383 init create a new repository in the given directory
377 init create a new repository in the given directory
384 log show revision history of entire repository or files
378 log show revision history of entire repository or files
385 merge merge working directory with another revision
379 merge merge working directory with another revision
386 pull pull changes from the specified source
380 pull pull changes from the specified source
387 push push changes to the specified destination
381 push push changes to the specified destination
388 remove remove the specified files on the next commit
382 remove remove the specified files on the next commit
389 serve start stand-alone webserver
383 serve start stand-alone webserver
390 status show changed files in the working directory
384 status show changed files in the working directory
391 summary summarize working directory state
385 summary summarize working directory state
392 update update working directory (or switch revisions)
386 update update working directory (or switch revisions)
393
387
394 use "hg help" for the full list of commands or "hg -v" for details
388 use "hg help" for the full list of commands or "hg -v" for details
395 [255]
389 [255]
396
390
@@ -1,66 +1,52 b''
1 test command parsing and dispatch
1 test command parsing and dispatch
2
2
3 $ "$TESTDIR/hghave" no-outer-repo || exit 80
3 $ "$TESTDIR/hghave" no-outer-repo || exit 80
4
4
5 $ dir=`pwd`
5 $ dir=`pwd`
6
6
7 $ hg init a
7 $ hg init a
8 $ cd a
8 $ cd a
9 $ echo a > a
9 $ echo a > a
10 $ hg ci -Ama
10 $ hg ci -Ama
11 adding a
11 adding a
12
12
13 Missing arg:
13 Missing arg:
14
14
15 $ hg cat
15 $ hg cat
16 hg cat: invalid arguments
16 hg cat: invalid arguments
17 hg cat [OPTION]... FILE...
17 hg cat [OPTION]... FILE...
18
18
19 output the current or given revision of files
19 output the current or given revision of files
20
20
21 Print the specified files as they were at the given revision. If no
22 revision is given, the parent of the working directory is used, or tip if
23 no revision is checked out.
24
25 Output may be to a file, in which case the name of the file is given using
26 a format string. The formatting rules are the same as for the export
27 command, with the following additions:
28
29 "%s" basename of file being printed
30 "%d" dirname of file being printed, or '.' if in repository root
31 "%p" root-relative path name of file being printed
32
33 Returns 0 on success.
34
35 options:
21 options:
36
22
37 -o --output FORMAT print output to file with formatted name
23 -o --output FORMAT print output to file with formatted name
38 -r --rev REV print the given revision
24 -r --rev REV print the given revision
39 --decode apply any matching decode filter
25 --decode apply any matching decode filter
40 -I --include PATTERN [+] include names matching the given patterns
26 -I --include PATTERN [+] include names matching the given patterns
41 -X --exclude PATTERN [+] exclude names matching the given patterns
27 -X --exclude PATTERN [+] exclude names matching the given patterns
42
28
43 [+] marked option can be specified multiple times
29 [+] marked option can be specified multiple times
44
30
45 use "hg -v help cat" to show global options
31 use "hg help cat" to show the full help text
46 [255]
32 [255]
47
33
48 [defaults]
34 [defaults]
49
35
50 $ hg cat a
36 $ hg cat a
51 a
37 a
52 $ cat >> $HGRCPATH <<EOF
38 $ cat >> $HGRCPATH <<EOF
53 > [defaults]
39 > [defaults]
54 > cat = -r null
40 > cat = -r null
55 > EOF
41 > EOF
56 $ hg cat a
42 $ hg cat a
57 a: no such file in rev 000000000000
43 a: no such file in rev 000000000000
58 [1]
44 [1]
59
45
60 No repo:
46 No repo:
61
47
62 $ cd $dir
48 $ cd $dir
63 $ hg cat
49 $ hg cat
64 abort: There is no Mercurial repository here (.hg not found)!
50 abort: There is no Mercurial repository here (.hg not found)!
65 [255]
51 [255]
66
52
@@ -1,803 +1,792 b''
1 Short help:
1 Short help:
2
2
3 $ hg
3 $ hg
4 Mercurial Distributed SCM
4 Mercurial Distributed SCM
5
5
6 basic commands:
6 basic commands:
7
7
8 add add the specified files on the next commit
8 add add the specified files on the next commit
9 annotate show changeset information by line for each file
9 annotate show changeset information by line for each file
10 clone make a copy of an existing repository
10 clone make a copy of an existing repository
11 commit commit the specified files or all outstanding changes
11 commit commit the specified files or all outstanding changes
12 diff diff repository (or selected files)
12 diff diff repository (or selected files)
13 export dump the header and diffs for one or more changesets
13 export dump the header and diffs for one or more changesets
14 forget forget the specified files on the next commit
14 forget forget the specified files on the next commit
15 init create a new repository in the given directory
15 init create a new repository in the given directory
16 log show revision history of entire repository or files
16 log show revision history of entire repository or files
17 merge merge working directory with another revision
17 merge merge working directory with another revision
18 pull pull changes from the specified source
18 pull pull changes from the specified source
19 push push changes to the specified destination
19 push push changes to the specified destination
20 remove remove the specified files on the next commit
20 remove remove the specified files on the next commit
21 serve start stand-alone webserver
21 serve start stand-alone webserver
22 status show changed files in the working directory
22 status show changed files in the working directory
23 summary summarize working directory state
23 summary summarize working directory state
24 update update working directory (or switch revisions)
24 update update working directory (or switch revisions)
25
25
26 use "hg help" for the full list of commands or "hg -v" for details
26 use "hg help" for the full list of commands or "hg -v" for details
27
27
28 $ hg -q
28 $ hg -q
29 add add the specified files on the next commit
29 add add the specified files on the next commit
30 annotate show changeset information by line for each file
30 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
31 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
32 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
33 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
34 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
35 forget forget the specified files on the next commit
36 init create a new repository in the given directory
36 init create a new repository in the given directory
37 log show revision history of entire repository or files
37 log show revision history of entire repository or files
38 merge merge working directory with another revision
38 merge merge working directory with another revision
39 pull pull changes from the specified source
39 pull pull changes from the specified source
40 push push changes to the specified destination
40 push push changes to the specified destination
41 remove remove the specified files on the next commit
41 remove remove the specified files on the next commit
42 serve start stand-alone webserver
42 serve start stand-alone webserver
43 status show changed files in the working directory
43 status show changed files in the working directory
44 summary summarize working directory state
44 summary summarize working directory state
45 update update working directory (or switch revisions)
45 update update working directory (or switch revisions)
46
46
47 $ hg help
47 $ hg help
48 Mercurial Distributed SCM
48 Mercurial Distributed SCM
49
49
50 list of commands:
50 list of commands:
51
51
52 add add the specified files on the next commit
52 add add the specified files on the next commit
53 addremove add all new files, delete all missing files
53 addremove add all new files, delete all missing files
54 annotate show changeset information by line for each file
54 annotate show changeset information by line for each file
55 archive create an unversioned archive of a repository revision
55 archive create an unversioned archive of a repository revision
56 backout reverse effect of earlier changeset
56 backout reverse effect of earlier changeset
57 bisect subdivision search of changesets
57 bisect subdivision search of changesets
58 bookmarks track a line of development with movable markers
58 bookmarks track a line of development with movable markers
59 branch set or show the current branch name
59 branch set or show the current branch name
60 branches list repository named branches
60 branches list repository named branches
61 bundle create a changegroup file
61 bundle create a changegroup file
62 cat output the current or given revision of files
62 cat output the current or given revision of files
63 clone make a copy of an existing repository
63 clone make a copy of an existing repository
64 commit commit the specified files or all outstanding changes
64 commit commit the specified files or all outstanding changes
65 copy mark files as copied for the next commit
65 copy mark files as copied for the next commit
66 diff diff repository (or selected files)
66 diff diff repository (or selected files)
67 export dump the header and diffs for one or more changesets
67 export dump the header and diffs for one or more changesets
68 forget forget the specified files on the next commit
68 forget forget the specified files on the next commit
69 grep search for a pattern in specified files and revisions
69 grep search for a pattern in specified files and revisions
70 heads show current repository heads or show branch heads
70 heads show current repository heads or show branch heads
71 help show help for a given topic or a help overview
71 help show help for a given topic or a help overview
72 identify identify the working copy or specified revision
72 identify identify the working copy or specified revision
73 import import an ordered set of patches
73 import import an ordered set of patches
74 incoming show new changesets found in source
74 incoming show new changesets found in source
75 init create a new repository in the given directory
75 init create a new repository in the given directory
76 locate locate files matching specific patterns
76 locate locate files matching specific patterns
77 log show revision history of entire repository or files
77 log show revision history of entire repository or files
78 manifest output the current or given revision of the project manifest
78 manifest output the current or given revision of the project manifest
79 merge merge working directory with another revision
79 merge merge working directory with another revision
80 outgoing show changesets not found in the destination
80 outgoing show changesets not found in the destination
81 parents show the parents of the working directory or revision
81 parents show the parents of the working directory or revision
82 paths show aliases for remote repositories
82 paths show aliases for remote repositories
83 pull pull changes from the specified source
83 pull pull changes from the specified source
84 push push changes to the specified destination
84 push push changes to the specified destination
85 recover roll back an interrupted transaction
85 recover roll back an interrupted transaction
86 remove remove the specified files on the next commit
86 remove remove the specified files on the next commit
87 rename rename files; equivalent of copy + remove
87 rename rename files; equivalent of copy + remove
88 resolve redo merges or set/view the merge status of files
88 resolve redo merges or set/view the merge status of files
89 revert restore individual files or directories to an earlier state
89 revert restore individual files or directories to an earlier state
90 rollback roll back the last transaction (dangerous)
90 rollback roll back the last transaction (dangerous)
91 root print the root (top) of the current working directory
91 root print the root (top) of the current working directory
92 serve start stand-alone webserver
92 serve start stand-alone webserver
93 showconfig show combined config settings from all hgrc files
93 showconfig show combined config settings from all hgrc files
94 status show changed files in the working directory
94 status show changed files in the working directory
95 summary summarize working directory state
95 summary summarize working directory state
96 tag add one or more tags for the current or given revision
96 tag add one or more tags for the current or given revision
97 tags list repository tags
97 tags list repository tags
98 tip show the tip revision
98 tip show the tip revision
99 unbundle apply one or more changegroup files
99 unbundle apply one or more changegroup files
100 update update working directory (or switch revisions)
100 update update working directory (or switch revisions)
101 verify verify the integrity of the repository
101 verify verify the integrity of the repository
102 version output version and copyright information
102 version output version and copyright information
103
103
104 additional help topics:
104 additional help topics:
105
105
106 config Configuration Files
106 config Configuration Files
107 dates Date Formats
107 dates Date Formats
108 diffs Diff Formats
108 diffs Diff Formats
109 environment Environment Variables
109 environment Environment Variables
110 extensions Using additional features
110 extensions Using additional features
111 glossary Glossary
111 glossary Glossary
112 hgweb Configuring hgweb
112 hgweb Configuring hgweb
113 merge-tools Merge Tools
113 merge-tools Merge Tools
114 multirevs Specifying Multiple Revisions
114 multirevs Specifying Multiple Revisions
115 patterns File Name Patterns
115 patterns File Name Patterns
116 revisions Specifying Single Revisions
116 revisions Specifying Single Revisions
117 revsets Specifying Revision Sets
117 revsets Specifying Revision Sets
118 subrepos Subrepositories
118 subrepos Subrepositories
119 templating Template Usage
119 templating Template Usage
120 urls URL Paths
120 urls URL Paths
121
121
122 use "hg -v help" to show builtin aliases and global options
122 use "hg -v help" to show builtin aliases and global options
123
123
124 $ hg -q help
124 $ hg -q help
125 add add the specified files on the next commit
125 add add the specified files on the next commit
126 addremove add all new files, delete all missing files
126 addremove add all new files, delete all missing files
127 annotate show changeset information by line for each file
127 annotate show changeset information by line for each file
128 archive create an unversioned archive of a repository revision
128 archive create an unversioned archive of a repository revision
129 backout reverse effect of earlier changeset
129 backout reverse effect of earlier changeset
130 bisect subdivision search of changesets
130 bisect subdivision search of changesets
131 bookmarks track a line of development with movable markers
131 bookmarks track a line of development with movable markers
132 branch set or show the current branch name
132 branch set or show the current branch name
133 branches list repository named branches
133 branches list repository named branches
134 bundle create a changegroup file
134 bundle create a changegroup file
135 cat output the current or given revision of files
135 cat output the current or given revision of files
136 clone make a copy of an existing repository
136 clone make a copy of an existing repository
137 commit commit the specified files or all outstanding changes
137 commit commit the specified files or all outstanding changes
138 copy mark files as copied for the next commit
138 copy mark files as copied for the next commit
139 diff diff repository (or selected files)
139 diff diff repository (or selected files)
140 export dump the header and diffs for one or more changesets
140 export dump the header and diffs for one or more changesets
141 forget forget the specified files on the next commit
141 forget forget the specified files on the next commit
142 grep search for a pattern in specified files and revisions
142 grep search for a pattern in specified files and revisions
143 heads show current repository heads or show branch heads
143 heads show current repository heads or show branch heads
144 help show help for a given topic or a help overview
144 help show help for a given topic or a help overview
145 identify identify the working copy or specified revision
145 identify identify the working copy or specified revision
146 import import an ordered set of patches
146 import import an ordered set of patches
147 incoming show new changesets found in source
147 incoming show new changesets found in source
148 init create a new repository in the given directory
148 init create a new repository in the given directory
149 locate locate files matching specific patterns
149 locate locate files matching specific patterns
150 log show revision history of entire repository or files
150 log show revision history of entire repository or files
151 manifest output the current or given revision of the project manifest
151 manifest output the current or given revision of the project manifest
152 merge merge working directory with another revision
152 merge merge working directory with another revision
153 outgoing show changesets not found in the destination
153 outgoing show changesets not found in the destination
154 parents show the parents of the working directory or revision
154 parents show the parents of the working directory or revision
155 paths show aliases for remote repositories
155 paths show aliases for remote repositories
156 pull pull changes from the specified source
156 pull pull changes from the specified source
157 push push changes to the specified destination
157 push push changes to the specified destination
158 recover roll back an interrupted transaction
158 recover roll back an interrupted transaction
159 remove remove the specified files on the next commit
159 remove remove the specified files on the next commit
160 rename rename files; equivalent of copy + remove
160 rename rename files; equivalent of copy + remove
161 resolve redo merges or set/view the merge status of files
161 resolve redo merges or set/view the merge status of files
162 revert restore individual files or directories to an earlier state
162 revert restore individual files or directories to an earlier state
163 rollback roll back the last transaction (dangerous)
163 rollback roll back the last transaction (dangerous)
164 root print the root (top) of the current working directory
164 root print the root (top) of the current working directory
165 serve start stand-alone webserver
165 serve start stand-alone webserver
166 showconfig show combined config settings from all hgrc files
166 showconfig show combined config settings from all hgrc files
167 status show changed files in the working directory
167 status show changed files in the working directory
168 summary summarize working directory state
168 summary summarize working directory state
169 tag add one or more tags for the current or given revision
169 tag add one or more tags for the current or given revision
170 tags list repository tags
170 tags list repository tags
171 tip show the tip revision
171 tip show the tip revision
172 unbundle apply one or more changegroup files
172 unbundle apply one or more changegroup files
173 update update working directory (or switch revisions)
173 update update working directory (or switch revisions)
174 verify verify the integrity of the repository
174 verify verify the integrity of the repository
175 version output version and copyright information
175 version output version and copyright information
176
176
177 additional help topics:
177 additional help topics:
178
178
179 config Configuration Files
179 config Configuration Files
180 dates Date Formats
180 dates Date Formats
181 diffs Diff Formats
181 diffs Diff Formats
182 environment Environment Variables
182 environment Environment Variables
183 extensions Using additional features
183 extensions Using additional features
184 glossary Glossary
184 glossary Glossary
185 hgweb Configuring hgweb
185 hgweb Configuring hgweb
186 merge-tools Merge Tools
186 merge-tools Merge Tools
187 multirevs Specifying Multiple Revisions
187 multirevs Specifying Multiple Revisions
188 patterns File Name Patterns
188 patterns File Name Patterns
189 revisions Specifying Single Revisions
189 revisions Specifying Single Revisions
190 revsets Specifying Revision Sets
190 revsets Specifying Revision Sets
191 subrepos Subrepositories
191 subrepos Subrepositories
192 templating Template Usage
192 templating Template Usage
193 urls URL Paths
193 urls URL Paths
194
194
195 Test short command list with verbose option
195 Test short command list with verbose option
196
196
197 $ hg -v help shortlist
197 $ hg -v help shortlist
198 Mercurial Distributed SCM (version *) (glob)
198 Mercurial Distributed SCM (version *) (glob)
199 (see http://mercurial.selenic.com for more information)
199 (see http://mercurial.selenic.com for more information)
200
200
201 Copyright (C) 2005-2011 Matt Mackall and others
201 Copyright (C) 2005-2011 Matt Mackall and others
202 This is free software; see the source for copying conditions. There is NO
202 This is free software; see the source for copying conditions. There is NO
203 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
203 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
204
204
205 basic commands:
205 basic commands:
206
206
207 add:
207 add:
208 add the specified files on the next commit
208 add the specified files on the next commit
209 annotate, blame:
209 annotate, blame:
210 show changeset information by line for each file
210 show changeset information by line for each file
211 clone:
211 clone:
212 make a copy of an existing repository
212 make a copy of an existing repository
213 commit, ci:
213 commit, ci:
214 commit the specified files or all outstanding changes
214 commit the specified files or all outstanding changes
215 diff:
215 diff:
216 diff repository (or selected files)
216 diff repository (or selected files)
217 export:
217 export:
218 dump the header and diffs for one or more changesets
218 dump the header and diffs for one or more changesets
219 forget:
219 forget:
220 forget the specified files on the next commit
220 forget the specified files on the next commit
221 init:
221 init:
222 create a new repository in the given directory
222 create a new repository in the given directory
223 log, history:
223 log, history:
224 show revision history of entire repository or files
224 show revision history of entire repository or files
225 merge:
225 merge:
226 merge working directory with another revision
226 merge working directory with another revision
227 pull:
227 pull:
228 pull changes from the specified source
228 pull changes from the specified source
229 push:
229 push:
230 push changes to the specified destination
230 push changes to the specified destination
231 remove, rm:
231 remove, rm:
232 remove the specified files on the next commit
232 remove the specified files on the next commit
233 serve:
233 serve:
234 start stand-alone webserver
234 start stand-alone webserver
235 status, st:
235 status, st:
236 show changed files in the working directory
236 show changed files in the working directory
237 summary, sum:
237 summary, sum:
238 summarize working directory state
238 summarize working directory state
239 update, up, checkout, co:
239 update, up, checkout, co:
240 update working directory (or switch revisions)
240 update working directory (or switch revisions)
241
241
242 global options:
242 global options:
243 -R --repository REPO repository root directory or name of overlay bundle
243 -R --repository REPO repository root directory or name of overlay bundle
244 file
244 file
245 --cwd DIR change working directory
245 --cwd DIR change working directory
246 -y --noninteractive do not prompt, assume 'yes' for any required answers
246 -y --noninteractive do not prompt, assume 'yes' for any required answers
247 -q --quiet suppress output
247 -q --quiet suppress output
248 -v --verbose enable additional output
248 -v --verbose enable additional output
249 --config CONFIG [+] set/override config option (use 'section.name=value')
249 --config CONFIG [+] set/override config option (use 'section.name=value')
250 --debug enable debugging output
250 --debug enable debugging output
251 --debugger start debugger
251 --debugger start debugger
252 --encoding ENCODE set the charset encoding (default: ascii)
252 --encoding ENCODE set the charset encoding (default: ascii)
253 --encodingmode MODE set the charset encoding mode (default: strict)
253 --encodingmode MODE set the charset encoding mode (default: strict)
254 --traceback always print a traceback on exception
254 --traceback always print a traceback on exception
255 --time time how long the command takes
255 --time time how long the command takes
256 --profile print command execution profile
256 --profile print command execution profile
257 --version output version information and exit
257 --version output version information and exit
258 -h --help display help and exit
258 -h --help display help and exit
259
259
260 [+] marked option can be specified multiple times
260 [+] marked option can be specified multiple times
261
261
262 use "hg help" for the full list of commands
262 use "hg help" for the full list of commands
263
263
264 $ hg add -h
264 $ hg add -h
265 hg add [OPTION]... [FILE]...
265 hg add [OPTION]... [FILE]...
266
266
267 add the specified files on the next commit
267 add the specified files on the next commit
268
268
269 Schedule files to be version controlled and added to the repository.
269 Schedule files to be version controlled and added to the repository.
270
270
271 The files will be added to the repository at the next commit. To undo an
271 The files will be added to the repository at the next commit. To undo an
272 add before that, see "hg forget".
272 add before that, see "hg forget".
273
273
274 If no names are given, add all files to the repository.
274 If no names are given, add all files to the repository.
275
275
276 Returns 0 if all files are successfully added.
276 Returns 0 if all files are successfully added.
277
277
278 use "hg -v help add" to show verbose help
278 use "hg -v help add" to show verbose help
279
279
280 options:
280 options:
281
281
282 -I --include PATTERN [+] include names matching the given patterns
282 -I --include PATTERN [+] include names matching the given patterns
283 -X --exclude PATTERN [+] exclude names matching the given patterns
283 -X --exclude PATTERN [+] exclude names matching the given patterns
284 -S --subrepos recurse into subrepositories
284 -S --subrepos recurse into subrepositories
285 -n --dry-run do not perform actions, just print output
285 -n --dry-run do not perform actions, just print output
286
286
287 [+] marked option can be specified multiple times
287 [+] marked option can be specified multiple times
288
288
289 use "hg -v help add" to show global options
289 use "hg -v help add" to show global options
290
290
291 Verbose help for add
291 Verbose help for add
292
292
293 $ hg add -hv
293 $ hg add -hv
294 hg add [OPTION]... [FILE]...
294 hg add [OPTION]... [FILE]...
295
295
296 add the specified files on the next commit
296 add the specified files on the next commit
297
297
298 Schedule files to be version controlled and added to the repository.
298 Schedule files to be version controlled and added to the repository.
299
299
300 The files will be added to the repository at the next commit. To undo an
300 The files will be added to the repository at the next commit. To undo an
301 add before that, see "hg forget".
301 add before that, see "hg forget".
302
302
303 If no names are given, add all files to the repository.
303 If no names are given, add all files to the repository.
304
304
305 An example showing how new (unknown) files are added automatically by "hg
305 An example showing how new (unknown) files are added automatically by "hg
306 add":
306 add":
307
307
308 $ ls
308 $ ls
309 foo.c
309 foo.c
310 $ hg status
310 $ hg status
311 ? foo.c
311 ? foo.c
312 $ hg add
312 $ hg add
313 adding foo.c
313 adding foo.c
314 $ hg status
314 $ hg status
315 A foo.c
315 A foo.c
316
316
317 Returns 0 if all files are successfully added.
317 Returns 0 if all files are successfully added.
318
318
319 options:
319 options:
320
320
321 -I --include PATTERN [+] include names matching the given patterns
321 -I --include PATTERN [+] include names matching the given patterns
322 -X --exclude PATTERN [+] exclude names matching the given patterns
322 -X --exclude PATTERN [+] exclude names matching the given patterns
323 -S --subrepos recurse into subrepositories
323 -S --subrepos recurse into subrepositories
324 -n --dry-run do not perform actions, just print output
324 -n --dry-run do not perform actions, just print output
325
325
326 global options:
326 global options:
327 -R --repository REPO repository root directory or name of overlay bundle
327 -R --repository REPO repository root directory or name of overlay bundle
328 file
328 file
329 --cwd DIR change working directory
329 --cwd DIR change working directory
330 -y --noninteractive do not prompt, assume 'yes' for any required
330 -y --noninteractive do not prompt, assume 'yes' for any required
331 answers
331 answers
332 -q --quiet suppress output
332 -q --quiet suppress output
333 -v --verbose enable additional output
333 -v --verbose enable additional output
334 --config CONFIG [+] set/override config option (use
334 --config CONFIG [+] set/override config option (use
335 'section.name=value')
335 'section.name=value')
336 --debug enable debugging output
336 --debug enable debugging output
337 --debugger start debugger
337 --debugger start debugger
338 --encoding ENCODE set the charset encoding (default: ascii)
338 --encoding ENCODE set the charset encoding (default: ascii)
339 --encodingmode MODE set the charset encoding mode (default: strict)
339 --encodingmode MODE set the charset encoding mode (default: strict)
340 --traceback always print a traceback on exception
340 --traceback always print a traceback on exception
341 --time time how long the command takes
341 --time time how long the command takes
342 --profile print command execution profile
342 --profile print command execution profile
343 --version output version information and exit
343 --version output version information and exit
344 -h --help display help and exit
344 -h --help display help and exit
345
345
346 [+] marked option can be specified multiple times
346 [+] marked option can be specified multiple times
347
347
348 Test help option with version option
348 Test help option with version option
349
349
350 $ hg add -h --version
350 $ hg add -h --version
351 Mercurial Distributed SCM (version *) (glob)
351 Mercurial Distributed SCM (version *) (glob)
352 (see http://mercurial.selenic.com for more information)
352 (see http://mercurial.selenic.com for more information)
353
353
354 Copyright (C) 2005-2011 Matt Mackall and others
354 Copyright (C) 2005-2011 Matt Mackall and others
355 This is free software; see the source for copying conditions. There is NO
355 This is free software; see the source for copying conditions. There is NO
356 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
356 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
357
357
358 hg add [OPTION]... [FILE]...
358 hg add [OPTION]... [FILE]...
359
359
360 add the specified files on the next commit
360 add the specified files on the next commit
361
361
362 Schedule files to be version controlled and added to the repository.
362 Schedule files to be version controlled and added to the repository.
363
363
364 The files will be added to the repository at the next commit. To undo an
364 The files will be added to the repository at the next commit. To undo an
365 add before that, see "hg forget".
365 add before that, see "hg forget".
366
366
367 If no names are given, add all files to the repository.
367 If no names are given, add all files to the repository.
368
368
369 Returns 0 if all files are successfully added.
369 Returns 0 if all files are successfully added.
370
370
371 use "hg -v help add" to show verbose help
371 use "hg -v help add" to show verbose help
372
372
373 options:
373 options:
374
374
375 -I --include PATTERN [+] include names matching the given patterns
375 -I --include PATTERN [+] include names matching the given patterns
376 -X --exclude PATTERN [+] exclude names matching the given patterns
376 -X --exclude PATTERN [+] exclude names matching the given patterns
377 -S --subrepos recurse into subrepositories
377 -S --subrepos recurse into subrepositories
378 -n --dry-run do not perform actions, just print output
378 -n --dry-run do not perform actions, just print output
379
379
380 [+] marked option can be specified multiple times
380 [+] marked option can be specified multiple times
381
381
382 use "hg -v help add" to show global options
382 use "hg -v help add" to show global options
383
383
384 $ hg add --skjdfks
384 $ hg add --skjdfks
385 hg add: option --skjdfks not recognized
385 hg add: option --skjdfks not recognized
386 hg add [OPTION]... [FILE]...
386 hg add [OPTION]... [FILE]...
387
387
388 add the specified files on the next commit
388 add the specified files on the next commit
389
389
390 Schedule files to be version controlled and added to the repository.
391
392 The files will be added to the repository at the next commit. To undo an
393 add before that, see "hg forget".
394
395 If no names are given, add all files to the repository.
396
397 Returns 0 if all files are successfully added.
398
399 use "hg -v help add" to show verbose help
400
401 options:
390 options:
402
391
403 -I --include PATTERN [+] include names matching the given patterns
392 -I --include PATTERN [+] include names matching the given patterns
404 -X --exclude PATTERN [+] exclude names matching the given patterns
393 -X --exclude PATTERN [+] exclude names matching the given patterns
405 -S --subrepos recurse into subrepositories
394 -S --subrepos recurse into subrepositories
406 -n --dry-run do not perform actions, just print output
395 -n --dry-run do not perform actions, just print output
407
396
408 [+] marked option can be specified multiple times
397 [+] marked option can be specified multiple times
409
398
410 use "hg -v help add" to show global options
399 use "hg help add" to show the full help text
411 [255]
400 [255]
412
401
413 Test ambiguous command help
402 Test ambiguous command help
414
403
415 $ hg help ad
404 $ hg help ad
416 list of commands:
405 list of commands:
417
406
418 add add the specified files on the next commit
407 add add the specified files on the next commit
419 addremove add all new files, delete all missing files
408 addremove add all new files, delete all missing files
420
409
421 use "hg -v help ad" to show builtin aliases and global options
410 use "hg -v help ad" to show builtin aliases and global options
422
411
423 Test command without options
412 Test command without options
424
413
425 $ hg help verify
414 $ hg help verify
426 hg verify
415 hg verify
427
416
428 verify the integrity of the repository
417 verify the integrity of the repository
429
418
430 Verify the integrity of the current repository.
419 Verify the integrity of the current repository.
431
420
432 This will perform an extensive check of the repository's integrity,
421 This will perform an extensive check of the repository's integrity,
433 validating the hashes and checksums of each entry in the changelog,
422 validating the hashes and checksums of each entry in the changelog,
434 manifest, and tracked files, as well as the integrity of their crosslinks
423 manifest, and tracked files, as well as the integrity of their crosslinks
435 and indices.
424 and indices.
436
425
437 Returns 0 on success, 1 if errors are encountered.
426 Returns 0 on success, 1 if errors are encountered.
438
427
439 use "hg -v help verify" to show global options
428 use "hg -v help verify" to show global options
440
429
441 $ hg help diff
430 $ hg help diff
442 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
431 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
443
432
444 diff repository (or selected files)
433 diff repository (or selected files)
445
434
446 Show differences between revisions for the specified files.
435 Show differences between revisions for the specified files.
447
436
448 Differences between files are shown using the unified diff format.
437 Differences between files are shown using the unified diff format.
449
438
450 Note:
439 Note:
451 diff may generate unexpected results for merges, as it will default to
440 diff may generate unexpected results for merges, as it will default to
452 comparing against the working directory's first parent changeset if no
441 comparing against the working directory's first parent changeset if no
453 revisions are specified.
442 revisions are specified.
454
443
455 When two revision arguments are given, then changes are shown between
444 When two revision arguments are given, then changes are shown between
456 those revisions. If only one revision is specified then that revision is
445 those revisions. If only one revision is specified then that revision is
457 compared to the working directory, and, when no revisions are specified,
446 compared to the working directory, and, when no revisions are specified,
458 the working directory files are compared to its parent.
447 the working directory files are compared to its parent.
459
448
460 Alternatively you can specify -c/--change with a revision to see the
449 Alternatively you can specify -c/--change with a revision to see the
461 changes in that changeset relative to its first parent.
450 changes in that changeset relative to its first parent.
462
451
463 Without the -a/--text option, diff will avoid generating diffs of files it
452 Without the -a/--text option, diff will avoid generating diffs of files it
464 detects as binary. With -a, diff will generate a diff anyway, probably
453 detects as binary. With -a, diff will generate a diff anyway, probably
465 with undesirable results.
454 with undesirable results.
466
455
467 Use the -g/--git option to generate diffs in the git extended diff format.
456 Use the -g/--git option to generate diffs in the git extended diff format.
468 For more information, read "hg help diffs".
457 For more information, read "hg help diffs".
469
458
470 Returns 0 on success.
459 Returns 0 on success.
471
460
472 options:
461 options:
473
462
474 -r --rev REV [+] revision
463 -r --rev REV [+] revision
475 -c --change REV change made by revision
464 -c --change REV change made by revision
476 -a --text treat all files as text
465 -a --text treat all files as text
477 -g --git use git extended diff format
466 -g --git use git extended diff format
478 --nodates omit dates from diff headers
467 --nodates omit dates from diff headers
479 -p --show-function show which function each change is in
468 -p --show-function show which function each change is in
480 --reverse produce a diff that undoes the changes
469 --reverse produce a diff that undoes the changes
481 -w --ignore-all-space ignore white space when comparing lines
470 -w --ignore-all-space ignore white space when comparing lines
482 -b --ignore-space-change ignore changes in the amount of white space
471 -b --ignore-space-change ignore changes in the amount of white space
483 -B --ignore-blank-lines ignore changes whose lines are all blank
472 -B --ignore-blank-lines ignore changes whose lines are all blank
484 -U --unified NUM number of lines of context to show
473 -U --unified NUM number of lines of context to show
485 --stat output diffstat-style summary of changes
474 --stat output diffstat-style summary of changes
486 -I --include PATTERN [+] include names matching the given patterns
475 -I --include PATTERN [+] include names matching the given patterns
487 -X --exclude PATTERN [+] exclude names matching the given patterns
476 -X --exclude PATTERN [+] exclude names matching the given patterns
488 -S --subrepos recurse into subrepositories
477 -S --subrepos recurse into subrepositories
489
478
490 [+] marked option can be specified multiple times
479 [+] marked option can be specified multiple times
491
480
492 use "hg -v help diff" to show global options
481 use "hg -v help diff" to show global options
493
482
494 $ hg help status
483 $ hg help status
495 hg status [OPTION]... [FILE]...
484 hg status [OPTION]... [FILE]...
496
485
497 aliases: st
486 aliases: st
498
487
499 show changed files in the working directory
488 show changed files in the working directory
500
489
501 Show status of files in the repository. If names are given, only files
490 Show status of files in the repository. If names are given, only files
502 that match are shown. Files that are clean or ignored or the source of a
491 that match are shown. Files that are clean or ignored or the source of a
503 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
492 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
504 -C/--copies or -A/--all are given. Unless options described with "show
493 -C/--copies or -A/--all are given. Unless options described with "show
505 only ..." are given, the options -mardu are used.
494 only ..." are given, the options -mardu are used.
506
495
507 Option -q/--quiet hides untracked (unknown and ignored) files unless
496 Option -q/--quiet hides untracked (unknown and ignored) files unless
508 explicitly requested with -u/--unknown or -i/--ignored.
497 explicitly requested with -u/--unknown or -i/--ignored.
509
498
510 Note:
499 Note:
511 status may appear to disagree with diff if permissions have changed or
500 status may appear to disagree with diff if permissions have changed or
512 a merge has occurred. The standard diff format does not report
501 a merge has occurred. The standard diff format does not report
513 permission changes and diff only reports changes relative to one merge
502 permission changes and diff only reports changes relative to one merge
514 parent.
503 parent.
515
504
516 If one revision is given, it is used as the base revision. If two
505 If one revision is given, it is used as the base revision. If two
517 revisions are given, the differences between them are shown. The --change
506 revisions are given, the differences between them are shown. The --change
518 option can also be used as a shortcut to list the changed files of a
507 option can also be used as a shortcut to list the changed files of a
519 revision from its first parent.
508 revision from its first parent.
520
509
521 The codes used to show the status of files are:
510 The codes used to show the status of files are:
522
511
523 M = modified
512 M = modified
524 A = added
513 A = added
525 R = removed
514 R = removed
526 C = clean
515 C = clean
527 ! = missing (deleted by non-hg command, but still tracked)
516 ! = missing (deleted by non-hg command, but still tracked)
528 ? = not tracked
517 ? = not tracked
529 I = ignored
518 I = ignored
530 = origin of the previous file listed as A (added)
519 = origin of the previous file listed as A (added)
531
520
532 Returns 0 on success.
521 Returns 0 on success.
533
522
534 options:
523 options:
535
524
536 -A --all show status of all files
525 -A --all show status of all files
537 -m --modified show only modified files
526 -m --modified show only modified files
538 -a --added show only added files
527 -a --added show only added files
539 -r --removed show only removed files
528 -r --removed show only removed files
540 -d --deleted show only deleted (but tracked) files
529 -d --deleted show only deleted (but tracked) files
541 -c --clean show only files without changes
530 -c --clean show only files without changes
542 -u --unknown show only unknown (not tracked) files
531 -u --unknown show only unknown (not tracked) files
543 -i --ignored show only ignored files
532 -i --ignored show only ignored files
544 -n --no-status hide status prefix
533 -n --no-status hide status prefix
545 -C --copies show source of copied files
534 -C --copies show source of copied files
546 -0 --print0 end filenames with NUL, for use with xargs
535 -0 --print0 end filenames with NUL, for use with xargs
547 --rev REV [+] show difference from revision
536 --rev REV [+] show difference from revision
548 --change REV list the changed files of a revision
537 --change REV list the changed files of a revision
549 -I --include PATTERN [+] include names matching the given patterns
538 -I --include PATTERN [+] include names matching the given patterns
550 -X --exclude PATTERN [+] exclude names matching the given patterns
539 -X --exclude PATTERN [+] exclude names matching the given patterns
551 -S --subrepos recurse into subrepositories
540 -S --subrepos recurse into subrepositories
552
541
553 [+] marked option can be specified multiple times
542 [+] marked option can be specified multiple times
554
543
555 use "hg -v help status" to show global options
544 use "hg -v help status" to show global options
556
545
557 $ hg -q help status
546 $ hg -q help status
558 hg status [OPTION]... [FILE]...
547 hg status [OPTION]... [FILE]...
559
548
560 show changed files in the working directory
549 show changed files in the working directory
561
550
562 $ hg help foo
551 $ hg help foo
563 hg: unknown command 'foo'
552 hg: unknown command 'foo'
564 Mercurial Distributed SCM
553 Mercurial Distributed SCM
565
554
566 basic commands:
555 basic commands:
567
556
568 add add the specified files on the next commit
557 add add the specified files on the next commit
569 annotate show changeset information by line for each file
558 annotate show changeset information by line for each file
570 clone make a copy of an existing repository
559 clone make a copy of an existing repository
571 commit commit the specified files or all outstanding changes
560 commit commit the specified files or all outstanding changes
572 diff diff repository (or selected files)
561 diff diff repository (or selected files)
573 export dump the header and diffs for one or more changesets
562 export dump the header and diffs for one or more changesets
574 forget forget the specified files on the next commit
563 forget forget the specified files on the next commit
575 init create a new repository in the given directory
564 init create a new repository in the given directory
576 log show revision history of entire repository or files
565 log show revision history of entire repository or files
577 merge merge working directory with another revision
566 merge merge working directory with another revision
578 pull pull changes from the specified source
567 pull pull changes from the specified source
579 push push changes to the specified destination
568 push push changes to the specified destination
580 remove remove the specified files on the next commit
569 remove remove the specified files on the next commit
581 serve start stand-alone webserver
570 serve start stand-alone webserver
582 status show changed files in the working directory
571 status show changed files in the working directory
583 summary summarize working directory state
572 summary summarize working directory state
584 update update working directory (or switch revisions)
573 update update working directory (or switch revisions)
585
574
586 use "hg help" for the full list of commands or "hg -v" for details
575 use "hg help" for the full list of commands or "hg -v" for details
587 [255]
576 [255]
588
577
589 $ hg skjdfks
578 $ hg skjdfks
590 hg: unknown command 'skjdfks'
579 hg: unknown command 'skjdfks'
591 Mercurial Distributed SCM
580 Mercurial Distributed SCM
592
581
593 basic commands:
582 basic commands:
594
583
595 add add the specified files on the next commit
584 add add the specified files on the next commit
596 annotate show changeset information by line for each file
585 annotate show changeset information by line for each file
597 clone make a copy of an existing repository
586 clone make a copy of an existing repository
598 commit commit the specified files or all outstanding changes
587 commit commit the specified files or all outstanding changes
599 diff diff repository (or selected files)
588 diff diff repository (or selected files)
600 export dump the header and diffs for one or more changesets
589 export dump the header and diffs for one or more changesets
601 forget forget the specified files on the next commit
590 forget forget the specified files on the next commit
602 init create a new repository in the given directory
591 init create a new repository in the given directory
603 log show revision history of entire repository or files
592 log show revision history of entire repository or files
604 merge merge working directory with another revision
593 merge merge working directory with another revision
605 pull pull changes from the specified source
594 pull pull changes from the specified source
606 push push changes to the specified destination
595 push push changes to the specified destination
607 remove remove the specified files on the next commit
596 remove remove the specified files on the next commit
608 serve start stand-alone webserver
597 serve start stand-alone webserver
609 status show changed files in the working directory
598 status show changed files in the working directory
610 summary summarize working directory state
599 summary summarize working directory state
611 update update working directory (or switch revisions)
600 update update working directory (or switch revisions)
612
601
613 use "hg help" for the full list of commands or "hg -v" for details
602 use "hg help" for the full list of commands or "hg -v" for details
614 [255]
603 [255]
615
604
616 $ cat > helpext.py <<EOF
605 $ cat > helpext.py <<EOF
617 > import os
606 > import os
618 > from mercurial import commands
607 > from mercurial import commands
619 >
608 >
620 > def nohelp(ui, *args, **kwargs):
609 > def nohelp(ui, *args, **kwargs):
621 > pass
610 > pass
622 >
611 >
623 > cmdtable = {
612 > cmdtable = {
624 > "nohelp": (nohelp, [], "hg nohelp"),
613 > "nohelp": (nohelp, [], "hg nohelp"),
625 > }
614 > }
626 >
615 >
627 > commands.norepo += ' nohelp'
616 > commands.norepo += ' nohelp'
628 > EOF
617 > EOF
629 $ echo '[extensions]' >> $HGRCPATH
618 $ echo '[extensions]' >> $HGRCPATH
630 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
619 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
631
620
632 Test command with no help text
621 Test command with no help text
633
622
634 $ hg help nohelp
623 $ hg help nohelp
635 hg nohelp
624 hg nohelp
636
625
637 (no help text available)
626 (no help text available)
638
627
639 use "hg -v help nohelp" to show global options
628 use "hg -v help nohelp" to show global options
640
629
641 Test that default list of commands omits extension commands
630 Test that default list of commands omits extension commands
642
631
643 $ hg help
632 $ hg help
644 Mercurial Distributed SCM
633 Mercurial Distributed SCM
645
634
646 list of commands:
635 list of commands:
647
636
648 add add the specified files on the next commit
637 add add the specified files on the next commit
649 addremove add all new files, delete all missing files
638 addremove add all new files, delete all missing files
650 annotate show changeset information by line for each file
639 annotate show changeset information by line for each file
651 archive create an unversioned archive of a repository revision
640 archive create an unversioned archive of a repository revision
652 backout reverse effect of earlier changeset
641 backout reverse effect of earlier changeset
653 bisect subdivision search of changesets
642 bisect subdivision search of changesets
654 bookmarks track a line of development with movable markers
643 bookmarks track a line of development with movable markers
655 branch set or show the current branch name
644 branch set or show the current branch name
656 branches list repository named branches
645 branches list repository named branches
657 bundle create a changegroup file
646 bundle create a changegroup file
658 cat output the current or given revision of files
647 cat output the current or given revision of files
659 clone make a copy of an existing repository
648 clone make a copy of an existing repository
660 commit commit the specified files or all outstanding changes
649 commit commit the specified files or all outstanding changes
661 copy mark files as copied for the next commit
650 copy mark files as copied for the next commit
662 diff diff repository (or selected files)
651 diff diff repository (or selected files)
663 export dump the header and diffs for one or more changesets
652 export dump the header and diffs for one or more changesets
664 forget forget the specified files on the next commit
653 forget forget the specified files on the next commit
665 grep search for a pattern in specified files and revisions
654 grep search for a pattern in specified files and revisions
666 heads show current repository heads or show branch heads
655 heads show current repository heads or show branch heads
667 help show help for a given topic or a help overview
656 help show help for a given topic or a help overview
668 identify identify the working copy or specified revision
657 identify identify the working copy or specified revision
669 import import an ordered set of patches
658 import import an ordered set of patches
670 incoming show new changesets found in source
659 incoming show new changesets found in source
671 init create a new repository in the given directory
660 init create a new repository in the given directory
672 locate locate files matching specific patterns
661 locate locate files matching specific patterns
673 log show revision history of entire repository or files
662 log show revision history of entire repository or files
674 manifest output the current or given revision of the project manifest
663 manifest output the current or given revision of the project manifest
675 merge merge working directory with another revision
664 merge merge working directory with another revision
676 outgoing show changesets not found in the destination
665 outgoing show changesets not found in the destination
677 parents show the parents of the working directory or revision
666 parents show the parents of the working directory or revision
678 paths show aliases for remote repositories
667 paths show aliases for remote repositories
679 pull pull changes from the specified source
668 pull pull changes from the specified source
680 push push changes to the specified destination
669 push push changes to the specified destination
681 recover roll back an interrupted transaction
670 recover roll back an interrupted transaction
682 remove remove the specified files on the next commit
671 remove remove the specified files on the next commit
683 rename rename files; equivalent of copy + remove
672 rename rename files; equivalent of copy + remove
684 resolve redo merges or set/view the merge status of files
673 resolve redo merges or set/view the merge status of files
685 revert restore individual files or directories to an earlier state
674 revert restore individual files or directories to an earlier state
686 rollback roll back the last transaction (dangerous)
675 rollback roll back the last transaction (dangerous)
687 root print the root (top) of the current working directory
676 root print the root (top) of the current working directory
688 serve start stand-alone webserver
677 serve start stand-alone webserver
689 showconfig show combined config settings from all hgrc files
678 showconfig show combined config settings from all hgrc files
690 status show changed files in the working directory
679 status show changed files in the working directory
691 summary summarize working directory state
680 summary summarize working directory state
692 tag add one or more tags for the current or given revision
681 tag add one or more tags for the current or given revision
693 tags list repository tags
682 tags list repository tags
694 tip show the tip revision
683 tip show the tip revision
695 unbundle apply one or more changegroup files
684 unbundle apply one or more changegroup files
696 update update working directory (or switch revisions)
685 update update working directory (or switch revisions)
697 verify verify the integrity of the repository
686 verify verify the integrity of the repository
698 version output version and copyright information
687 version output version and copyright information
699
688
700 enabled extensions:
689 enabled extensions:
701
690
702 helpext (no help text available)
691 helpext (no help text available)
703
692
704 additional help topics:
693 additional help topics:
705
694
706 config Configuration Files
695 config Configuration Files
707 dates Date Formats
696 dates Date Formats
708 diffs Diff Formats
697 diffs Diff Formats
709 environment Environment Variables
698 environment Environment Variables
710 extensions Using additional features
699 extensions Using additional features
711 glossary Glossary
700 glossary Glossary
712 hgweb Configuring hgweb
701 hgweb Configuring hgweb
713 merge-tools Merge Tools
702 merge-tools Merge Tools
714 multirevs Specifying Multiple Revisions
703 multirevs Specifying Multiple Revisions
715 patterns File Name Patterns
704 patterns File Name Patterns
716 revisions Specifying Single Revisions
705 revisions Specifying Single Revisions
717 revsets Specifying Revision Sets
706 revsets Specifying Revision Sets
718 subrepos Subrepositories
707 subrepos Subrepositories
719 templating Template Usage
708 templating Template Usage
720 urls URL Paths
709 urls URL Paths
721
710
722 use "hg -v help" to show builtin aliases and global options
711 use "hg -v help" to show builtin aliases and global options
723
712
724
713
725
714
726 Test list of commands with command with no help text
715 Test list of commands with command with no help text
727
716
728 $ hg help helpext
717 $ hg help helpext
729 helpext extension - no help text available
718 helpext extension - no help text available
730
719
731 list of commands:
720 list of commands:
732
721
733 nohelp (no help text available)
722 nohelp (no help text available)
734
723
735 use "hg -v help helpext" to show builtin aliases and global options
724 use "hg -v help helpext" to show builtin aliases and global options
736
725
737 Test a help topic
726 Test a help topic
738
727
739 $ hg help revs
728 $ hg help revs
740 Specifying Single Revisions
729 Specifying Single Revisions
741
730
742 Mercurial supports several ways to specify individual revisions.
731 Mercurial supports several ways to specify individual revisions.
743
732
744 A plain integer is treated as a revision number. Negative integers are
733 A plain integer is treated as a revision number. Negative integers are
745 treated as sequential offsets from the tip, with -1 denoting the tip, -2
734 treated as sequential offsets from the tip, with -1 denoting the tip, -2
746 denoting the revision prior to the tip, and so forth.
735 denoting the revision prior to the tip, and so forth.
747
736
748 A 40-digit hexadecimal string is treated as a unique revision identifier.
737 A 40-digit hexadecimal string is treated as a unique revision identifier.
749
738
750 A hexadecimal string less than 40 characters long is treated as a unique
739 A hexadecimal string less than 40 characters long is treated as a unique
751 revision identifier and is referred to as a short-form identifier. A
740 revision identifier and is referred to as a short-form identifier. A
752 short-form identifier is only valid if it is the prefix of exactly one
741 short-form identifier is only valid if it is the prefix of exactly one
753 full-length identifier.
742 full-length identifier.
754
743
755 Any other string is treated as a tag or branch name. A tag name is a
744 Any other string is treated as a tag or branch name. A tag name is a
756 symbolic name associated with a revision identifier. A branch name denotes
745 symbolic name associated with a revision identifier. A branch name denotes
757 the tipmost revision of that branch. Tag and branch names must not contain
746 the tipmost revision of that branch. Tag and branch names must not contain
758 the ":" character.
747 the ":" character.
759
748
760 The reserved name "tip" is a special tag that always identifies the most
749 The reserved name "tip" is a special tag that always identifies the most
761 recent revision.
750 recent revision.
762
751
763 The reserved name "null" indicates the null revision. This is the revision
752 The reserved name "null" indicates the null revision. This is the revision
764 of an empty repository, and the parent of revision 0.
753 of an empty repository, and the parent of revision 0.
765
754
766 The reserved name "." indicates the working directory parent. If no
755 The reserved name "." indicates the working directory parent. If no
767 working directory is checked out, it is equivalent to null. If an
756 working directory is checked out, it is equivalent to null. If an
768 uncommitted merge is in progress, "." is the revision of the first parent.
757 uncommitted merge is in progress, "." is the revision of the first parent.
769
758
770 Test templating help
759 Test templating help
771
760
772 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
761 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
773 desc String. The text of the changeset description.
762 desc String. The text of the changeset description.
774 diffstat String. Statistics of changes with the following format:
763 diffstat String. Statistics of changes with the following format:
775 firstline Any text. Returns the first line of text.
764 firstline Any text. Returns the first line of text.
776 nonempty Any text. Returns '(none)' if the string is empty.
765 nonempty Any text. Returns '(none)' if the string is empty.
777
766
778 Test help hooks
767 Test help hooks
779
768
780 $ cat > helphook1.py <<EOF
769 $ cat > helphook1.py <<EOF
781 > from mercurial import help
770 > from mercurial import help
782 >
771 >
783 > def rewrite(topic, doc):
772 > def rewrite(topic, doc):
784 > return doc + '\nhelphook1\n'
773 > return doc + '\nhelphook1\n'
785 >
774 >
786 > def extsetup(ui):
775 > def extsetup(ui):
787 > help.addtopichook('revsets', rewrite)
776 > help.addtopichook('revsets', rewrite)
788 > EOF
777 > EOF
789 $ cat > helphook2.py <<EOF
778 $ cat > helphook2.py <<EOF
790 > from mercurial import help
779 > from mercurial import help
791 >
780 >
792 > def rewrite(topic, doc):
781 > def rewrite(topic, doc):
793 > return doc + '\nhelphook2\n'
782 > return doc + '\nhelphook2\n'
794 >
783 >
795 > def extsetup(ui):
784 > def extsetup(ui):
796 > help.addtopichook('revsets', rewrite)
785 > help.addtopichook('revsets', rewrite)
797 > EOF
786 > EOF
798 $ echo '[extensions]' >> $HGRCPATH
787 $ echo '[extensions]' >> $HGRCPATH
799 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
788 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
800 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
789 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
801 $ hg help revsets | grep helphook
790 $ hg help revsets | grep helphook
802 helphook1
791 helphook1
803 helphook2
792 helphook2
@@ -1,370 +1,368 b''
1 Create configuration
1 Create configuration
2
2
3 $ echo "[ui]" >> $HGRCPATH
3 $ echo "[ui]" >> $HGRCPATH
4 $ echo "interactive=true" >> $HGRCPATH
4 $ echo "interactive=true" >> $HGRCPATH
5
5
6 help record (no record)
6 help record (no record)
7
7
8 $ hg help record
8 $ hg help record
9 record extension - commands to interactively select changes for commit/qrefresh
9 record extension - commands to interactively select changes for commit/qrefresh
10
10
11 use "hg help extensions" for information on enabling extensions
11 use "hg help extensions" for information on enabling extensions
12
12
13 help qrecord (no record)
13 help qrecord (no record)
14
14
15 $ hg help qrecord
15 $ hg help qrecord
16 'qrecord' is provided by the following extension:
16 'qrecord' is provided by the following extension:
17
17
18 record commands to interactively select changes for commit/qrefresh
18 record commands to interactively select changes for commit/qrefresh
19
19
20 use "hg help extensions" for information on enabling extensions
20 use "hg help extensions" for information on enabling extensions
21
21
22 $ echo "[extensions]" >> $HGRCPATH
22 $ echo "[extensions]" >> $HGRCPATH
23 $ echo "record=" >> $HGRCPATH
23 $ echo "record=" >> $HGRCPATH
24
24
25 help record (record)
25 help record (record)
26
26
27 $ hg help record
27 $ hg help record
28 hg record [OPTION]... [FILE]...
28 hg record [OPTION]... [FILE]...
29
29
30 interactively select changes to commit
30 interactively select changes to commit
31
31
32 If a list of files is omitted, all changes reported by "hg status" will be
32 If a list of files is omitted, all changes reported by "hg status" will be
33 candidates for recording.
33 candidates for recording.
34
34
35 See "hg help dates" for a list of formats valid for -d/--date.
35 See "hg help dates" for a list of formats valid for -d/--date.
36
36
37 You will be prompted for whether to record changes to each modified file,
37 You will be prompted for whether to record changes to each modified file,
38 and for files with multiple changes, for each change to use. For each
38 and for files with multiple changes, for each change to use. For each
39 query, the following responses are possible:
39 query, the following responses are possible:
40
40
41 y - record this change
41 y - record this change
42 n - skip this change
42 n - skip this change
43
43
44 s - skip remaining changes to this file
44 s - skip remaining changes to this file
45 f - record remaining changes to this file
45 f - record remaining changes to this file
46
46
47 d - done, skip remaining changes and files
47 d - done, skip remaining changes and files
48 a - record all changes to all remaining files
48 a - record all changes to all remaining files
49 q - quit, recording no changes
49 q - quit, recording no changes
50
50
51 ? - display help
51 ? - display help
52
52
53 This command is not available when committing a merge.
53 This command is not available when committing a merge.
54
54
55 options:
55 options:
56
56
57 -A --addremove mark new/missing files as added/removed before
57 -A --addremove mark new/missing files as added/removed before
58 committing
58 committing
59 --close-branch mark a branch as closed, hiding it from the branch
59 --close-branch mark a branch as closed, hiding it from the branch
60 list
60 list
61 -I --include PATTERN [+] include names matching the given patterns
61 -I --include PATTERN [+] include names matching the given patterns
62 -X --exclude PATTERN [+] exclude names matching the given patterns
62 -X --exclude PATTERN [+] exclude names matching the given patterns
63 -m --message TEXT use text as commit message
63 -m --message TEXT use text as commit message
64 -l --logfile FILE read commit message from file
64 -l --logfile FILE read commit message from file
65 -d --date DATE record datecode as commit date
65 -d --date DATE record datecode as commit date
66 -u --user USER record the specified user as committer
66 -u --user USER record the specified user as committer
67
67
68 [+] marked option can be specified multiple times
68 [+] marked option can be specified multiple times
69
69
70 use "hg -v help record" to show global options
70 use "hg -v help record" to show global options
71
71
72 help (no mq, so no qrecord)
72 help (no mq, so no qrecord)
73
73
74 $ hg help qrecord
74 $ hg help qrecord
75 hg qrecord [OPTION]... PATCH [FILE]...
75 hg qrecord [OPTION]... PATCH [FILE]...
76
76
77 interactively record a new patch
77 interactively record a new patch
78
78
79 See "hg help qnew" & "hg help record" for more information and usage.
79 See "hg help qnew" & "hg help record" for more information and usage.
80
80
81 use "hg -v help qrecord" to show global options
81 use "hg -v help qrecord" to show global options
82
82
83 $ hg init a
83 $ hg init a
84
84
85 qrecord (mq not present)
85 qrecord (mq not present)
86
86
87 $ hg -R a qrecord
87 $ hg -R a qrecord
88 hg qrecord: invalid arguments
88 hg qrecord: invalid arguments
89 hg qrecord [OPTION]... PATCH [FILE]...
89 hg qrecord [OPTION]... PATCH [FILE]...
90
90
91 interactively record a new patch
91 interactively record a new patch
92
92
93 See "hg help qnew" & "hg help record" for more information and usage.
93 use "hg help qrecord" to show the full help text
94
95 use "hg -v help qrecord" to show global options
96 [255]
94 [255]
97
95
98 qrecord patch (mq not present)
96 qrecord patch (mq not present)
99
97
100 $ hg -R a qrecord patch
98 $ hg -R a qrecord patch
101 abort: 'mq' extension not loaded
99 abort: 'mq' extension not loaded
102 [255]
100 [255]
103
101
104 help (mq present)
102 help (mq present)
105
103
106 $ echo "mq=" >> $HGRCPATH
104 $ echo "mq=" >> $HGRCPATH
107 $ hg help qrecord
105 $ hg help qrecord
108 hg qrecord [OPTION]... PATCH [FILE]...
106 hg qrecord [OPTION]... PATCH [FILE]...
109
107
110 interactively record a new patch
108 interactively record a new patch
111
109
112 See "hg help qnew" & "hg help record" for more information and usage.
110 See "hg help qnew" & "hg help record" for more information and usage.
113
111
114 options:
112 options:
115
113
116 -e --edit edit commit message
114 -e --edit edit commit message
117 -g --git use git extended diff format
115 -g --git use git extended diff format
118 -U --currentuser add "From: <current user>" to patch
116 -U --currentuser add "From: <current user>" to patch
119 -u --user USER add "From: <USER>" to patch
117 -u --user USER add "From: <USER>" to patch
120 -D --currentdate add "Date: <current date>" to patch
118 -D --currentdate add "Date: <current date>" to patch
121 -d --date DATE add "Date: <DATE>" to patch
119 -d --date DATE add "Date: <DATE>" to patch
122 -I --include PATTERN [+] include names matching the given patterns
120 -I --include PATTERN [+] include names matching the given patterns
123 -X --exclude PATTERN [+] exclude names matching the given patterns
121 -X --exclude PATTERN [+] exclude names matching the given patterns
124 -m --message TEXT use text as commit message
122 -m --message TEXT use text as commit message
125 -l --logfile FILE read commit message from file
123 -l --logfile FILE read commit message from file
126
124
127 [+] marked option can be specified multiple times
125 [+] marked option can be specified multiple times
128
126
129 use "hg -v help qrecord" to show global options
127 use "hg -v help qrecord" to show global options
130
128
131 $ cd a
129 $ cd a
132
130
133 Base commit
131 Base commit
134
132
135 $ cat > 1.txt <<EOF
133 $ cat > 1.txt <<EOF
136 > 1
134 > 1
137 > 2
135 > 2
138 > 3
136 > 3
139 > 4
137 > 4
140 > 5
138 > 5
141 > EOF
139 > EOF
142 $ cat > 2.txt <<EOF
140 $ cat > 2.txt <<EOF
143 > a
141 > a
144 > b
142 > b
145 > c
143 > c
146 > d
144 > d
147 > e
145 > e
148 > f
146 > f
149 > EOF
147 > EOF
150
148
151 $ mkdir dir
149 $ mkdir dir
152 $ cat > dir/a.txt <<EOF
150 $ cat > dir/a.txt <<EOF
153 > hello world
151 > hello world
154 >
152 >
155 > someone
153 > someone
156 > up
154 > up
157 > there
155 > there
158 > loves
156 > loves
159 > me
157 > me
160 > EOF
158 > EOF
161
159
162 $ hg add 1.txt 2.txt dir/a.txt
160 $ hg add 1.txt 2.txt dir/a.txt
163 $ hg commit -m 'initial checkin'
161 $ hg commit -m 'initial checkin'
164
162
165 Changing files
163 Changing files
166
164
167 $ sed -e 's/2/2 2/;s/4/4 4/' 1.txt > 1.txt.new
165 $ sed -e 's/2/2 2/;s/4/4 4/' 1.txt > 1.txt.new
168 $ sed -e 's/b/b b/' 2.txt > 2.txt.new
166 $ sed -e 's/b/b b/' 2.txt > 2.txt.new
169 $ sed -e 's/hello world/hello world!/' dir/a.txt > dir/a.txt.new
167 $ sed -e 's/hello world/hello world!/' dir/a.txt > dir/a.txt.new
170
168
171 $ mv -f 1.txt.new 1.txt
169 $ mv -f 1.txt.new 1.txt
172 $ mv -f 2.txt.new 2.txt
170 $ mv -f 2.txt.new 2.txt
173 $ mv -f dir/a.txt.new dir/a.txt
171 $ mv -f dir/a.txt.new dir/a.txt
174
172
175 Whole diff
173 Whole diff
176
174
177 $ hg diff --nodates
175 $ hg diff --nodates
178 diff -r 1057167b20ef 1.txt
176 diff -r 1057167b20ef 1.txt
179 --- a/1.txt
177 --- a/1.txt
180 +++ b/1.txt
178 +++ b/1.txt
181 @@ -1,5 +1,5 @@
179 @@ -1,5 +1,5 @@
182 1
180 1
183 -2
181 -2
184 +2 2
182 +2 2
185 3
183 3
186 -4
184 -4
187 +4 4
185 +4 4
188 5
186 5
189 diff -r 1057167b20ef 2.txt
187 diff -r 1057167b20ef 2.txt
190 --- a/2.txt
188 --- a/2.txt
191 +++ b/2.txt
189 +++ b/2.txt
192 @@ -1,5 +1,5 @@
190 @@ -1,5 +1,5 @@
193 a
191 a
194 -b
192 -b
195 +b b
193 +b b
196 c
194 c
197 d
195 d
198 e
196 e
199 diff -r 1057167b20ef dir/a.txt
197 diff -r 1057167b20ef dir/a.txt
200 --- a/dir/a.txt
198 --- a/dir/a.txt
201 +++ b/dir/a.txt
199 +++ b/dir/a.txt
202 @@ -1,4 +1,4 @@
200 @@ -1,4 +1,4 @@
203 -hello world
201 -hello world
204 +hello world!
202 +hello world!
205
203
206 someone
204 someone
207 up
205 up
208
206
209 qrecord a.patch
207 qrecord a.patch
210
208
211 $ hg qrecord -d '0 0' -m aaa a.patch <<EOF
209 $ hg qrecord -d '0 0' -m aaa a.patch <<EOF
212 > y
210 > y
213 > y
211 > y
214 > n
212 > n
215 > y
213 > y
216 > y
214 > y
217 > n
215 > n
218 > EOF
216 > EOF
219 diff --git a/1.txt b/1.txt
217 diff --git a/1.txt b/1.txt
220 2 hunks, 2 lines changed
218 2 hunks, 2 lines changed
221 examine changes to '1.txt'? [Ynsfdaq?]
219 examine changes to '1.txt'? [Ynsfdaq?]
222 @@ -1,3 +1,3 @@
220 @@ -1,3 +1,3 @@
223 1
221 1
224 -2
222 -2
225 +2 2
223 +2 2
226 3
224 3
227 record change 1/4 to '1.txt'? [Ynsfdaq?]
225 record change 1/4 to '1.txt'? [Ynsfdaq?]
228 @@ -3,3 +3,3 @@
226 @@ -3,3 +3,3 @@
229 3
227 3
230 -4
228 -4
231 +4 4
229 +4 4
232 5
230 5
233 record change 2/4 to '1.txt'? [Ynsfdaq?]
231 record change 2/4 to '1.txt'? [Ynsfdaq?]
234 diff --git a/2.txt b/2.txt
232 diff --git a/2.txt b/2.txt
235 1 hunks, 1 lines changed
233 1 hunks, 1 lines changed
236 examine changes to '2.txt'? [Ynsfdaq?]
234 examine changes to '2.txt'? [Ynsfdaq?]
237 @@ -1,5 +1,5 @@
235 @@ -1,5 +1,5 @@
238 a
236 a
239 -b
237 -b
240 +b b
238 +b b
241 c
239 c
242 d
240 d
243 e
241 e
244 record change 3/4 to '2.txt'? [Ynsfdaq?]
242 record change 3/4 to '2.txt'? [Ynsfdaq?]
245 diff --git a/dir/a.txt b/dir/a.txt
243 diff --git a/dir/a.txt b/dir/a.txt
246 1 hunks, 1 lines changed
244 1 hunks, 1 lines changed
247 examine changes to 'dir/a.txt'? [Ynsfdaq?]
245 examine changes to 'dir/a.txt'? [Ynsfdaq?]
248
246
249 After qrecord a.patch 'tip'"
247 After qrecord a.patch 'tip'"
250
248
251 $ hg tip -p
249 $ hg tip -p
252 changeset: 1:5d1ca63427ee
250 changeset: 1:5d1ca63427ee
253 tag: a.patch
251 tag: a.patch
254 tag: qbase
252 tag: qbase
255 tag: qtip
253 tag: qtip
256 tag: tip
254 tag: tip
257 user: test
255 user: test
258 date: Thu Jan 01 00:00:00 1970 +0000
256 date: Thu Jan 01 00:00:00 1970 +0000
259 summary: aaa
257 summary: aaa
260
258
261 diff -r 1057167b20ef -r 5d1ca63427ee 1.txt
259 diff -r 1057167b20ef -r 5d1ca63427ee 1.txt
262 --- a/1.txt Thu Jan 01 00:00:00 1970 +0000
260 --- a/1.txt Thu Jan 01 00:00:00 1970 +0000
263 +++ b/1.txt Thu Jan 01 00:00:00 1970 +0000
261 +++ b/1.txt Thu Jan 01 00:00:00 1970 +0000
264 @@ -1,5 +1,5 @@
262 @@ -1,5 +1,5 @@
265 1
263 1
266 -2
264 -2
267 +2 2
265 +2 2
268 3
266 3
269 4
267 4
270 5
268 5
271 diff -r 1057167b20ef -r 5d1ca63427ee 2.txt
269 diff -r 1057167b20ef -r 5d1ca63427ee 2.txt
272 --- a/2.txt Thu Jan 01 00:00:00 1970 +0000
270 --- a/2.txt Thu Jan 01 00:00:00 1970 +0000
273 +++ b/2.txt Thu Jan 01 00:00:00 1970 +0000
271 +++ b/2.txt Thu Jan 01 00:00:00 1970 +0000
274 @@ -1,5 +1,5 @@
272 @@ -1,5 +1,5 @@
275 a
273 a
276 -b
274 -b
277 +b b
275 +b b
278 c
276 c
279 d
277 d
280 e
278 e
281
279
282
280
283 After qrecord a.patch 'diff'"
281 After qrecord a.patch 'diff'"
284
282
285 $ hg diff --nodates
283 $ hg diff --nodates
286 diff -r 5d1ca63427ee 1.txt
284 diff -r 5d1ca63427ee 1.txt
287 --- a/1.txt
285 --- a/1.txt
288 +++ b/1.txt
286 +++ b/1.txt
289 @@ -1,5 +1,5 @@
287 @@ -1,5 +1,5 @@
290 1
288 1
291 2 2
289 2 2
292 3
290 3
293 -4
291 -4
294 +4 4
292 +4 4
295 5
293 5
296 diff -r 5d1ca63427ee dir/a.txt
294 diff -r 5d1ca63427ee dir/a.txt
297 --- a/dir/a.txt
295 --- a/dir/a.txt
298 +++ b/dir/a.txt
296 +++ b/dir/a.txt
299 @@ -1,4 +1,4 @@
297 @@ -1,4 +1,4 @@
300 -hello world
298 -hello world
301 +hello world!
299 +hello world!
302
300
303 someone
301 someone
304 up
302 up
305
303
306 qrecord b.patch
304 qrecord b.patch
307
305
308 $ hg qrecord -d '0 0' -m bbb b.patch <<EOF
306 $ hg qrecord -d '0 0' -m bbb b.patch <<EOF
309 > y
307 > y
310 > y
308 > y
311 > y
309 > y
312 > y
310 > y
313 > EOF
311 > EOF
314 diff --git a/1.txt b/1.txt
312 diff --git a/1.txt b/1.txt
315 1 hunks, 1 lines changed
313 1 hunks, 1 lines changed
316 examine changes to '1.txt'? [Ynsfdaq?]
314 examine changes to '1.txt'? [Ynsfdaq?]
317 @@ -1,5 +1,5 @@
315 @@ -1,5 +1,5 @@
318 1
316 1
319 2 2
317 2 2
320 3
318 3
321 -4
319 -4
322 +4 4
320 +4 4
323 5
321 5
324 record change 1/2 to '1.txt'? [Ynsfdaq?]
322 record change 1/2 to '1.txt'? [Ynsfdaq?]
325 diff --git a/dir/a.txt b/dir/a.txt
323 diff --git a/dir/a.txt b/dir/a.txt
326 1 hunks, 1 lines changed
324 1 hunks, 1 lines changed
327 examine changes to 'dir/a.txt'? [Ynsfdaq?]
325 examine changes to 'dir/a.txt'? [Ynsfdaq?]
328 @@ -1,4 +1,4 @@
326 @@ -1,4 +1,4 @@
329 -hello world
327 -hello world
330 +hello world!
328 +hello world!
331
329
332 someone
330 someone
333 up
331 up
334 record change 2/2 to 'dir/a.txt'? [Ynsfdaq?]
332 record change 2/2 to 'dir/a.txt'? [Ynsfdaq?]
335
333
336 After qrecord b.patch 'tip'
334 After qrecord b.patch 'tip'
337
335
338 $ hg tip -p
336 $ hg tip -p
339 changeset: 2:b056198bf878
337 changeset: 2:b056198bf878
340 tag: b.patch
338 tag: b.patch
341 tag: qtip
339 tag: qtip
342 tag: tip
340 tag: tip
343 user: test
341 user: test
344 date: Thu Jan 01 00:00:00 1970 +0000
342 date: Thu Jan 01 00:00:00 1970 +0000
345 summary: bbb
343 summary: bbb
346
344
347 diff -r 5d1ca63427ee -r b056198bf878 1.txt
345 diff -r 5d1ca63427ee -r b056198bf878 1.txt
348 --- a/1.txt Thu Jan 01 00:00:00 1970 +0000
346 --- a/1.txt Thu Jan 01 00:00:00 1970 +0000
349 +++ b/1.txt Thu Jan 01 00:00:00 1970 +0000
347 +++ b/1.txt Thu Jan 01 00:00:00 1970 +0000
350 @@ -1,5 +1,5 @@
348 @@ -1,5 +1,5 @@
351 1
349 1
352 2 2
350 2 2
353 3
351 3
354 -4
352 -4
355 +4 4
353 +4 4
356 5
354 5
357 diff -r 5d1ca63427ee -r b056198bf878 dir/a.txt
355 diff -r 5d1ca63427ee -r b056198bf878 dir/a.txt
358 --- a/dir/a.txt Thu Jan 01 00:00:00 1970 +0000
356 --- a/dir/a.txt Thu Jan 01 00:00:00 1970 +0000
359 +++ b/dir/a.txt Thu Jan 01 00:00:00 1970 +0000
357 +++ b/dir/a.txt Thu Jan 01 00:00:00 1970 +0000
360 @@ -1,4 +1,4 @@
358 @@ -1,4 +1,4 @@
361 -hello world
359 -hello world
362 +hello world!
360 +hello world!
363
361
364 someone
362 someone
365 up
363 up
366
364
367
365
368 After qrecord b.patch 'diff'
366 After qrecord b.patch 'diff'
369
367
370 $ hg diff --nodates
368 $ hg diff --nodates
General Comments 0
You need to be logged in to leave comments. Login now