##// END OF EJS Templates
showconfig: don't accept multiple sections and one config item...
Brodie Rao -
r12697:14853ca7 default
parent child Browse files
Show More
@@ -1,4449 +1,4451 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, nullid, nullrev, short
8 from node import hex, 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
12 import hg, util, revlog, extensions, copies, error
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
16 import minirst, revset
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 ctx = repo[opts.get('rev')]
129 ctx = repo[opts.get('rev')]
130 m = cmdutil.match(repo, pats, opts)
130 m = cmdutil.match(repo, pats, opts)
131 follow = not opts.get('no_follow')
131 follow = not opts.get('no_follow')
132 for abs in ctx.walk(m):
132 for abs in ctx.walk(m):
133 fctx = ctx[abs]
133 fctx = ctx[abs]
134 if not opts.get('text') and util.binary(fctx.data()):
134 if not opts.get('text') and util.binary(fctx.data()):
135 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
135 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
136 continue
136 continue
137
137
138 lines = fctx.annotate(follow=follow, linenumber=linenumber)
138 lines = fctx.annotate(follow=follow, linenumber=linenumber)
139 pieces = []
139 pieces = []
140
140
141 for f in funcmap:
141 for f in funcmap:
142 l = [f(n) for n, dummy in lines]
142 l = [f(n) for n, dummy in lines]
143 if l:
143 if l:
144 sized = [(x, encoding.colwidth(x)) for x in l]
144 sized = [(x, encoding.colwidth(x)) for x in l]
145 ml = max([w for x, w in sized])
145 ml = max([w for x, w in sized])
146 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
146 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
147
147
148 if pieces:
148 if pieces:
149 for p, l in zip(zip(*pieces), lines):
149 for p, l in zip(zip(*pieces), lines):
150 ui.write("%s: %s" % (" ".join(p), l[1]))
150 ui.write("%s: %s" % (" ".join(p), l[1]))
151
151
152 def archive(ui, repo, dest, **opts):
152 def archive(ui, repo, dest, **opts):
153 '''create an unversioned archive of a repository revision
153 '''create an unversioned archive of a repository revision
154
154
155 By default, the revision used is the parent of the working
155 By default, the revision used is the parent of the working
156 directory; use -r/--rev to specify a different revision.
156 directory; use -r/--rev to specify a different revision.
157
157
158 The archive type is automatically detected based on file
158 The archive type is automatically detected based on file
159 extension (or override using -t/--type).
159 extension (or override using -t/--type).
160
160
161 Valid types are:
161 Valid types are:
162
162
163 :``files``: a directory full of files (default)
163 :``files``: a directory full of files (default)
164 :``tar``: tar archive, uncompressed
164 :``tar``: tar archive, uncompressed
165 :``tbz2``: tar archive, compressed using bzip2
165 :``tbz2``: tar archive, compressed using bzip2
166 :``tgz``: tar archive, compressed using gzip
166 :``tgz``: tar archive, compressed using gzip
167 :``uzip``: zip archive, uncompressed
167 :``uzip``: zip archive, uncompressed
168 :``zip``: zip archive, compressed using deflate
168 :``zip``: zip archive, compressed using deflate
169
169
170 The exact name of the destination archive or directory is given
170 The exact name of the destination archive or directory is given
171 using a format string; see :hg:`help export` for details.
171 using a format string; see :hg:`help export` for details.
172
172
173 Each member added to an archive file has a directory prefix
173 Each member added to an archive file has a directory prefix
174 prepended. Use -p/--prefix to specify a format string for the
174 prepended. Use -p/--prefix to specify a format string for the
175 prefix. The default is the basename of the archive, with suffixes
175 prefix. The default is the basename of the archive, with suffixes
176 removed.
176 removed.
177
177
178 Returns 0 on success.
178 Returns 0 on success.
179 '''
179 '''
180
180
181 ctx = repo[opts.get('rev')]
181 ctx = repo[opts.get('rev')]
182 if not ctx:
182 if not ctx:
183 raise util.Abort(_('no working directory: please specify a revision'))
183 raise util.Abort(_('no working directory: please specify a revision'))
184 node = ctx.node()
184 node = ctx.node()
185 dest = cmdutil.make_filename(repo, dest, node)
185 dest = cmdutil.make_filename(repo, dest, node)
186 if os.path.realpath(dest) == repo.root:
186 if os.path.realpath(dest) == repo.root:
187 raise util.Abort(_('repository root cannot be destination'))
187 raise util.Abort(_('repository root cannot be destination'))
188
188
189 kind = opts.get('type') or archival.guesskind(dest) or 'files'
189 kind = opts.get('type') or archival.guesskind(dest) or 'files'
190 prefix = opts.get('prefix')
190 prefix = opts.get('prefix')
191
191
192 if dest == '-':
192 if dest == '-':
193 if kind == 'files':
193 if kind == 'files':
194 raise util.Abort(_('cannot archive plain files to stdout'))
194 raise util.Abort(_('cannot archive plain files to stdout'))
195 dest = sys.stdout
195 dest = sys.stdout
196 if not prefix:
196 if not prefix:
197 prefix = os.path.basename(repo.root) + '-%h'
197 prefix = os.path.basename(repo.root) + '-%h'
198
198
199 prefix = cmdutil.make_filename(repo, prefix, node)
199 prefix = cmdutil.make_filename(repo, prefix, node)
200 matchfn = cmdutil.match(repo, [], opts)
200 matchfn = cmdutil.match(repo, [], opts)
201 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
201 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
202 matchfn, prefix, subrepos=opts.get('subrepos'))
202 matchfn, prefix, subrepos=opts.get('subrepos'))
203
203
204 def backout(ui, repo, node=None, rev=None, **opts):
204 def backout(ui, repo, node=None, rev=None, **opts):
205 '''reverse effect of earlier changeset
205 '''reverse effect of earlier changeset
206
206
207 Commit the backed out changes as a new changeset. The new
207 Commit the backed out changes as a new changeset. The new
208 changeset is a child of the backed out changeset.
208 changeset is a child of the backed out changeset.
209
209
210 If you backout a changeset other than the tip, a new head is
210 If you backout a changeset other than the tip, a new head is
211 created. This head will be the new tip and you should merge this
211 created. This head will be the new tip and you should merge this
212 backout changeset with another head.
212 backout changeset with another head.
213
213
214 The --merge option remembers the parent of the working directory
214 The --merge option remembers the parent of the working directory
215 before starting the backout, then merges the new head with that
215 before starting the backout, then merges the new head with that
216 changeset afterwards. This saves you from doing the merge by hand.
216 changeset afterwards. This saves you from doing the merge by hand.
217 The result of this merge is not committed, as with a normal merge.
217 The result of this merge is not committed, as with a normal merge.
218
218
219 See :hg:`help dates` for a list of formats valid for -d/--date.
219 See :hg:`help dates` for a list of formats valid for -d/--date.
220
220
221 Returns 0 on success.
221 Returns 0 on success.
222 '''
222 '''
223 if rev and node:
223 if rev and node:
224 raise util.Abort(_("please specify just one revision"))
224 raise util.Abort(_("please specify just one revision"))
225
225
226 if not rev:
226 if not rev:
227 rev = node
227 rev = node
228
228
229 if not rev:
229 if not rev:
230 raise util.Abort(_("please specify a revision to backout"))
230 raise util.Abort(_("please specify a revision to backout"))
231
231
232 date = opts.get('date')
232 date = opts.get('date')
233 if date:
233 if date:
234 opts['date'] = util.parsedate(date)
234 opts['date'] = util.parsedate(date)
235
235
236 cmdutil.bail_if_changed(repo)
236 cmdutil.bail_if_changed(repo)
237 node = repo.lookup(rev)
237 node = repo.lookup(rev)
238
238
239 op1, op2 = repo.dirstate.parents()
239 op1, op2 = repo.dirstate.parents()
240 a = repo.changelog.ancestor(op1, node)
240 a = repo.changelog.ancestor(op1, node)
241 if a != node:
241 if a != node:
242 raise util.Abort(_('cannot backout change on a different branch'))
242 raise util.Abort(_('cannot backout change on a different branch'))
243
243
244 p1, p2 = repo.changelog.parents(node)
244 p1, p2 = repo.changelog.parents(node)
245 if p1 == nullid:
245 if p1 == nullid:
246 raise util.Abort(_('cannot backout a change with no parents'))
246 raise util.Abort(_('cannot backout a change with no parents'))
247 if p2 != nullid:
247 if p2 != nullid:
248 if not opts.get('parent'):
248 if not opts.get('parent'):
249 raise util.Abort(_('cannot backout a merge changeset without '
249 raise util.Abort(_('cannot backout a merge changeset without '
250 '--parent'))
250 '--parent'))
251 p = repo.lookup(opts['parent'])
251 p = repo.lookup(opts['parent'])
252 if p not in (p1, p2):
252 if p not in (p1, p2):
253 raise util.Abort(_('%s is not a parent of %s') %
253 raise util.Abort(_('%s is not a parent of %s') %
254 (short(p), short(node)))
254 (short(p), short(node)))
255 parent = p
255 parent = p
256 else:
256 else:
257 if opts.get('parent'):
257 if opts.get('parent'):
258 raise util.Abort(_('cannot use --parent on non-merge changeset'))
258 raise util.Abort(_('cannot use --parent on non-merge changeset'))
259 parent = p1
259 parent = p1
260
260
261 # the backout should appear on the same branch
261 # the backout should appear on the same branch
262 branch = repo.dirstate.branch()
262 branch = repo.dirstate.branch()
263 hg.clean(repo, node, show_stats=False)
263 hg.clean(repo, node, show_stats=False)
264 repo.dirstate.setbranch(branch)
264 repo.dirstate.setbranch(branch)
265 revert_opts = opts.copy()
265 revert_opts = opts.copy()
266 revert_opts['date'] = None
266 revert_opts['date'] = None
267 revert_opts['all'] = True
267 revert_opts['all'] = True
268 revert_opts['rev'] = hex(parent)
268 revert_opts['rev'] = hex(parent)
269 revert_opts['no_backup'] = None
269 revert_opts['no_backup'] = None
270 revert(ui, repo, **revert_opts)
270 revert(ui, repo, **revert_opts)
271 commit_opts = opts.copy()
271 commit_opts = opts.copy()
272 commit_opts['addremove'] = False
272 commit_opts['addremove'] = False
273 if not commit_opts['message'] and not commit_opts['logfile']:
273 if not commit_opts['message'] and not commit_opts['logfile']:
274 # we don't translate commit messages
274 # we don't translate commit messages
275 commit_opts['message'] = "Backed out changeset %s" % short(node)
275 commit_opts['message'] = "Backed out changeset %s" % short(node)
276 commit_opts['force_editor'] = True
276 commit_opts['force_editor'] = True
277 commit(ui, repo, **commit_opts)
277 commit(ui, repo, **commit_opts)
278 def nice(node):
278 def nice(node):
279 return '%d:%s' % (repo.changelog.rev(node), short(node))
279 return '%d:%s' % (repo.changelog.rev(node), short(node))
280 ui.status(_('changeset %s backs out changeset %s\n') %
280 ui.status(_('changeset %s backs out changeset %s\n') %
281 (nice(repo.changelog.tip()), nice(node)))
281 (nice(repo.changelog.tip()), nice(node)))
282 if op1 != node:
282 if op1 != node:
283 hg.clean(repo, op1, show_stats=False)
283 hg.clean(repo, op1, show_stats=False)
284 if opts.get('merge'):
284 if opts.get('merge'):
285 ui.status(_('merging with changeset %s\n')
285 ui.status(_('merging with changeset %s\n')
286 % nice(repo.changelog.tip()))
286 % nice(repo.changelog.tip()))
287 hg.merge(repo, hex(repo.changelog.tip()))
287 hg.merge(repo, hex(repo.changelog.tip()))
288 else:
288 else:
289 ui.status(_('the backout changeset is a new head - '
289 ui.status(_('the backout changeset is a new head - '
290 'do not forget to merge\n'))
290 'do not forget to merge\n'))
291 ui.status(_('(use "backout --merge" '
291 ui.status(_('(use "backout --merge" '
292 'if you want to auto-merge)\n'))
292 'if you want to auto-merge)\n'))
293
293
294 def bisect(ui, repo, rev=None, extra=None, command=None,
294 def bisect(ui, repo, rev=None, extra=None, command=None,
295 reset=None, good=None, bad=None, skip=None, noupdate=None):
295 reset=None, good=None, bad=None, skip=None, noupdate=None):
296 """subdivision search of changesets
296 """subdivision search of changesets
297
297
298 This command helps to find changesets which introduce problems. To
298 This command helps to find changesets which introduce problems. To
299 use, mark the earliest changeset you know exhibits the problem as
299 use, mark the earliest changeset you know exhibits the problem as
300 bad, then mark the latest changeset which is free from the problem
300 bad, then mark the latest changeset which is free from the problem
301 as good. Bisect will update your working directory to a revision
301 as good. Bisect will update your working directory to a revision
302 for testing (unless the -U/--noupdate option is specified). Once
302 for testing (unless the -U/--noupdate option is specified). Once
303 you have performed tests, mark the working directory as good or
303 you have performed tests, mark the working directory as good or
304 bad, and bisect will either update to another candidate changeset
304 bad, and bisect will either update to another candidate changeset
305 or announce that it has found the bad revision.
305 or announce that it has found the bad revision.
306
306
307 As a shortcut, you can also use the revision argument to mark a
307 As a shortcut, you can also use the revision argument to mark a
308 revision as good or bad without checking it out first.
308 revision as good or bad without checking it out first.
309
309
310 If you supply a command, it will be used for automatic bisection.
310 If you supply a command, it will be used for automatic bisection.
311 Its exit status will be used to mark revisions as good or bad:
311 Its exit status will be used to mark revisions as good or bad:
312 status 0 means good, 125 means to skip the revision, 127
312 status 0 means good, 125 means to skip the revision, 127
313 (command not found) will abort the bisection, and any other
313 (command not found) will abort the bisection, and any other
314 non-zero exit status means the revision is bad.
314 non-zero exit status means the revision is bad.
315
315
316 Returns 0 on success.
316 Returns 0 on success.
317 """
317 """
318 def print_result(nodes, good):
318 def print_result(nodes, good):
319 displayer = cmdutil.show_changeset(ui, repo, {})
319 displayer = cmdutil.show_changeset(ui, repo, {})
320 if len(nodes) == 1:
320 if len(nodes) == 1:
321 # narrowed it down to a single revision
321 # narrowed it down to a single revision
322 if good:
322 if good:
323 ui.write(_("The first good revision is:\n"))
323 ui.write(_("The first good revision is:\n"))
324 else:
324 else:
325 ui.write(_("The first bad revision is:\n"))
325 ui.write(_("The first bad revision is:\n"))
326 displayer.show(repo[nodes[0]])
326 displayer.show(repo[nodes[0]])
327 parents = repo[nodes[0]].parents()
327 parents = repo[nodes[0]].parents()
328 if len(parents) > 1:
328 if len(parents) > 1:
329 side = good and state['bad'] or state['good']
329 side = good and state['bad'] or state['good']
330 num = len(set(i.node() for i in parents) & set(side))
330 num = len(set(i.node() for i in parents) & set(side))
331 if num == 1:
331 if num == 1:
332 common = parents[0].ancestor(parents[1])
332 common = parents[0].ancestor(parents[1])
333 ui.write(_('Not all ancestors of this changeset have been'
333 ui.write(_('Not all ancestors of this changeset have been'
334 ' checked.\nTo check the other ancestors, start'
334 ' checked.\nTo check the other ancestors, start'
335 ' from the common ancestor, %s.\n' % common))
335 ' from the common ancestor, %s.\n' % common))
336 else:
336 else:
337 # multiple possible revisions
337 # multiple possible revisions
338 if good:
338 if good:
339 ui.write(_("Due to skipped revisions, the first "
339 ui.write(_("Due to skipped revisions, the first "
340 "good revision could be any of:\n"))
340 "good revision could be any of:\n"))
341 else:
341 else:
342 ui.write(_("Due to skipped revisions, the first "
342 ui.write(_("Due to skipped revisions, the first "
343 "bad revision could be any of:\n"))
343 "bad revision could be any of:\n"))
344 for n in nodes:
344 for n in nodes:
345 displayer.show(repo[n])
345 displayer.show(repo[n])
346 displayer.close()
346 displayer.close()
347
347
348 def check_state(state, interactive=True):
348 def check_state(state, interactive=True):
349 if not state['good'] or not state['bad']:
349 if not state['good'] or not state['bad']:
350 if (good or bad or skip or reset) and interactive:
350 if (good or bad or skip or reset) and interactive:
351 return
351 return
352 if not state['good']:
352 if not state['good']:
353 raise util.Abort(_('cannot bisect (no known good revisions)'))
353 raise util.Abort(_('cannot bisect (no known good revisions)'))
354 else:
354 else:
355 raise util.Abort(_('cannot bisect (no known bad revisions)'))
355 raise util.Abort(_('cannot bisect (no known bad revisions)'))
356 return True
356 return True
357
357
358 # backward compatibility
358 # backward compatibility
359 if rev in "good bad reset init".split():
359 if rev in "good bad reset init".split():
360 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
360 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
361 cmd, rev, extra = rev, extra, None
361 cmd, rev, extra = rev, extra, None
362 if cmd == "good":
362 if cmd == "good":
363 good = True
363 good = True
364 elif cmd == "bad":
364 elif cmd == "bad":
365 bad = True
365 bad = True
366 else:
366 else:
367 reset = True
367 reset = True
368 elif extra or good + bad + skip + reset + bool(command) > 1:
368 elif extra or good + bad + skip + reset + bool(command) > 1:
369 raise util.Abort(_('incompatible arguments'))
369 raise util.Abort(_('incompatible arguments'))
370
370
371 if reset:
371 if reset:
372 p = repo.join("bisect.state")
372 p = repo.join("bisect.state")
373 if os.path.exists(p):
373 if os.path.exists(p):
374 os.unlink(p)
374 os.unlink(p)
375 return
375 return
376
376
377 state = hbisect.load_state(repo)
377 state = hbisect.load_state(repo)
378
378
379 if command:
379 if command:
380 changesets = 1
380 changesets = 1
381 try:
381 try:
382 while changesets:
382 while changesets:
383 # update state
383 # update state
384 status = util.system(command)
384 status = util.system(command)
385 if status == 125:
385 if status == 125:
386 transition = "skip"
386 transition = "skip"
387 elif status == 0:
387 elif status == 0:
388 transition = "good"
388 transition = "good"
389 # status < 0 means process was killed
389 # status < 0 means process was killed
390 elif status == 127:
390 elif status == 127:
391 raise util.Abort(_("failed to execute %s") % command)
391 raise util.Abort(_("failed to execute %s") % command)
392 elif status < 0:
392 elif status < 0:
393 raise util.Abort(_("%s killed") % command)
393 raise util.Abort(_("%s killed") % command)
394 else:
394 else:
395 transition = "bad"
395 transition = "bad"
396 ctx = repo[rev or '.']
396 ctx = repo[rev or '.']
397 state[transition].append(ctx.node())
397 state[transition].append(ctx.node())
398 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
398 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
399 check_state(state, interactive=False)
399 check_state(state, interactive=False)
400 # bisect
400 # bisect
401 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
401 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
402 # update to next check
402 # update to next check
403 cmdutil.bail_if_changed(repo)
403 cmdutil.bail_if_changed(repo)
404 hg.clean(repo, nodes[0], show_stats=False)
404 hg.clean(repo, nodes[0], show_stats=False)
405 finally:
405 finally:
406 hbisect.save_state(repo, state)
406 hbisect.save_state(repo, state)
407 print_result(nodes, good)
407 print_result(nodes, good)
408 return
408 return
409
409
410 # update state
410 # update state
411
411
412 if rev:
412 if rev:
413 nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
413 nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
414 else:
414 else:
415 nodes = [repo.lookup('.')]
415 nodes = [repo.lookup('.')]
416
416
417 if good or bad or skip:
417 if good or bad or skip:
418 if good:
418 if good:
419 state['good'] += nodes
419 state['good'] += nodes
420 elif bad:
420 elif bad:
421 state['bad'] += nodes
421 state['bad'] += nodes
422 elif skip:
422 elif skip:
423 state['skip'] += nodes
423 state['skip'] += nodes
424 hbisect.save_state(repo, state)
424 hbisect.save_state(repo, state)
425
425
426 if not check_state(state):
426 if not check_state(state):
427 return
427 return
428
428
429 # actually bisect
429 # actually bisect
430 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
430 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
431 if changesets == 0:
431 if changesets == 0:
432 print_result(nodes, good)
432 print_result(nodes, good)
433 else:
433 else:
434 assert len(nodes) == 1 # only a single node can be tested next
434 assert len(nodes) == 1 # only a single node can be tested next
435 node = nodes[0]
435 node = nodes[0]
436 # compute the approximate number of remaining tests
436 # compute the approximate number of remaining tests
437 tests, size = 0, 2
437 tests, size = 0, 2
438 while size <= changesets:
438 while size <= changesets:
439 tests, size = tests + 1, size * 2
439 tests, size = tests + 1, size * 2
440 rev = repo.changelog.rev(node)
440 rev = repo.changelog.rev(node)
441 ui.write(_("Testing changeset %d:%s "
441 ui.write(_("Testing changeset %d:%s "
442 "(%d changesets remaining, ~%d tests)\n")
442 "(%d changesets remaining, ~%d tests)\n")
443 % (rev, short(node), changesets, tests))
443 % (rev, short(node), changesets, tests))
444 if not noupdate:
444 if not noupdate:
445 cmdutil.bail_if_changed(repo)
445 cmdutil.bail_if_changed(repo)
446 return hg.clean(repo, node)
446 return hg.clean(repo, node)
447
447
448 def branch(ui, repo, label=None, **opts):
448 def branch(ui, repo, label=None, **opts):
449 """set or show the current branch name
449 """set or show the current branch name
450
450
451 With no argument, show the current branch name. With one argument,
451 With no argument, show the current branch name. With one argument,
452 set the working directory branch name (the branch will not exist
452 set the working directory branch name (the branch will not exist
453 in the repository until the next commit). Standard practice
453 in the repository until the next commit). Standard practice
454 recommends that primary development take place on the 'default'
454 recommends that primary development take place on the 'default'
455 branch.
455 branch.
456
456
457 Unless -f/--force is specified, branch will not let you set a
457 Unless -f/--force is specified, branch will not let you set a
458 branch name that already exists, even if it's inactive.
458 branch name that already exists, even if it's inactive.
459
459
460 Use -C/--clean to reset the working directory branch to that of
460 Use -C/--clean to reset the working directory branch to that of
461 the parent of the working directory, negating a previous branch
461 the parent of the working directory, negating a previous branch
462 change.
462 change.
463
463
464 Use the command :hg:`update` to switch to an existing branch. Use
464 Use the command :hg:`update` to switch to an existing branch. Use
465 :hg:`commit --close-branch` to mark this branch as closed.
465 :hg:`commit --close-branch` to mark this branch as closed.
466
466
467 Returns 0 on success.
467 Returns 0 on success.
468 """
468 """
469
469
470 if opts.get('clean'):
470 if opts.get('clean'):
471 label = repo[None].parents()[0].branch()
471 label = repo[None].parents()[0].branch()
472 repo.dirstate.setbranch(label)
472 repo.dirstate.setbranch(label)
473 ui.status(_('reset working directory to branch %s\n') % label)
473 ui.status(_('reset working directory to branch %s\n') % label)
474 elif label:
474 elif label:
475 utflabel = encoding.fromlocal(label)
475 utflabel = encoding.fromlocal(label)
476 if not opts.get('force') and utflabel in repo.branchtags():
476 if not opts.get('force') and utflabel in repo.branchtags():
477 if label not in [p.branch() for p in repo.parents()]:
477 if label not in [p.branch() for p in repo.parents()]:
478 raise util.Abort(_('a branch of the same name already exists'
478 raise util.Abort(_('a branch of the same name already exists'
479 " (use 'hg update' to switch to it)"))
479 " (use 'hg update' to switch to it)"))
480 repo.dirstate.setbranch(utflabel)
480 repo.dirstate.setbranch(utflabel)
481 ui.status(_('marked working directory as branch %s\n') % label)
481 ui.status(_('marked working directory as branch %s\n') % label)
482 else:
482 else:
483 ui.write("%s\n" % encoding.tolocal(repo.dirstate.branch()))
483 ui.write("%s\n" % encoding.tolocal(repo.dirstate.branch()))
484
484
485 def branches(ui, repo, active=False, closed=False):
485 def branches(ui, repo, active=False, closed=False):
486 """list repository named branches
486 """list repository named branches
487
487
488 List the repository's named branches, indicating which ones are
488 List the repository's named branches, indicating which ones are
489 inactive. If -c/--closed is specified, also list branches which have
489 inactive. If -c/--closed is specified, also list branches which have
490 been marked closed (see :hg:`commit --close-branch`).
490 been marked closed (see :hg:`commit --close-branch`).
491
491
492 If -a/--active is specified, only show active branches. A branch
492 If -a/--active is specified, only show active branches. A branch
493 is considered active if it contains repository heads.
493 is considered active if it contains repository heads.
494
494
495 Use the command :hg:`update` to switch to an existing branch.
495 Use the command :hg:`update` to switch to an existing branch.
496
496
497 Returns 0.
497 Returns 0.
498 """
498 """
499
499
500 hexfunc = ui.debugflag and hex or short
500 hexfunc = ui.debugflag and hex or short
501 activebranches = [repo[n].branch() for n in repo.heads()]
501 activebranches = [repo[n].branch() for n in repo.heads()]
502 def testactive(tag, node):
502 def testactive(tag, node):
503 realhead = tag in activebranches
503 realhead = tag in activebranches
504 open = node in repo.branchheads(tag, closed=False)
504 open = node in repo.branchheads(tag, closed=False)
505 return realhead and open
505 return realhead and open
506 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
506 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
507 for tag, node in repo.branchtags().items()],
507 for tag, node in repo.branchtags().items()],
508 reverse=True)
508 reverse=True)
509
509
510 for isactive, node, tag in branches:
510 for isactive, node, tag in branches:
511 if (not active) or isactive:
511 if (not active) or isactive:
512 encodedtag = encoding.tolocal(tag)
512 encodedtag = encoding.tolocal(tag)
513 if ui.quiet:
513 if ui.quiet:
514 ui.write("%s\n" % encodedtag)
514 ui.write("%s\n" % encodedtag)
515 else:
515 else:
516 hn = repo.lookup(node)
516 hn = repo.lookup(node)
517 if isactive:
517 if isactive:
518 label = 'branches.active'
518 label = 'branches.active'
519 notice = ''
519 notice = ''
520 elif hn not in repo.branchheads(tag, closed=False):
520 elif hn not in repo.branchheads(tag, closed=False):
521 if not closed:
521 if not closed:
522 continue
522 continue
523 label = 'branches.closed'
523 label = 'branches.closed'
524 notice = _(' (closed)')
524 notice = _(' (closed)')
525 else:
525 else:
526 label = 'branches.inactive'
526 label = 'branches.inactive'
527 notice = _(' (inactive)')
527 notice = _(' (inactive)')
528 if tag == repo.dirstate.branch():
528 if tag == repo.dirstate.branch():
529 label = 'branches.current'
529 label = 'branches.current'
530 rev = str(node).rjust(31 - encoding.colwidth(encodedtag))
530 rev = str(node).rjust(31 - encoding.colwidth(encodedtag))
531 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
531 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
532 encodedtag = ui.label(encodedtag, label)
532 encodedtag = ui.label(encodedtag, label)
533 ui.write("%s %s%s\n" % (encodedtag, rev, notice))
533 ui.write("%s %s%s\n" % (encodedtag, rev, notice))
534
534
535 def bundle(ui, repo, fname, dest=None, **opts):
535 def bundle(ui, repo, fname, dest=None, **opts):
536 """create a changegroup file
536 """create a changegroup file
537
537
538 Generate a compressed changegroup file collecting changesets not
538 Generate a compressed changegroup file collecting changesets not
539 known to be in another repository.
539 known to be in another repository.
540
540
541 If you omit the destination repository, then hg assumes the
541 If you omit the destination repository, then hg assumes the
542 destination will have all the nodes you specify with --base
542 destination will have all the nodes you specify with --base
543 parameters. To create a bundle containing all changesets, use
543 parameters. To create a bundle containing all changesets, use
544 -a/--all (or --base null).
544 -a/--all (or --base null).
545
545
546 You can change compression method with the -t/--type option.
546 You can change compression method with the -t/--type option.
547 The available compression methods are: none, bzip2, and
547 The available compression methods are: none, bzip2, and
548 gzip (by default, bundles are compressed using bzip2).
548 gzip (by default, bundles are compressed using bzip2).
549
549
550 The bundle file can then be transferred using conventional means
550 The bundle file can then be transferred using conventional means
551 and applied to another repository with the unbundle or pull
551 and applied to another repository with the unbundle or pull
552 command. This is useful when direct push and pull are not
552 command. This is useful when direct push and pull are not
553 available or when exporting an entire repository is undesirable.
553 available or when exporting an entire repository is undesirable.
554
554
555 Applying bundles preserves all changeset contents including
555 Applying bundles preserves all changeset contents including
556 permissions, copy/rename information, and revision history.
556 permissions, copy/rename information, and revision history.
557
557
558 Returns 0 on success, 1 if no changes found.
558 Returns 0 on success, 1 if no changes found.
559 """
559 """
560 revs = opts.get('rev') or None
560 revs = opts.get('rev') or None
561 if opts.get('all'):
561 if opts.get('all'):
562 base = ['null']
562 base = ['null']
563 else:
563 else:
564 base = opts.get('base')
564 base = opts.get('base')
565 if base:
565 if base:
566 if dest:
566 if dest:
567 raise util.Abort(_("--base is incompatible with specifying "
567 raise util.Abort(_("--base is incompatible with specifying "
568 "a destination"))
568 "a destination"))
569 base = [repo.lookup(rev) for rev in base]
569 base = [repo.lookup(rev) for rev in base]
570 # create the right base
570 # create the right base
571 # XXX: nodesbetween / changegroup* should be "fixed" instead
571 # XXX: nodesbetween / changegroup* should be "fixed" instead
572 o = []
572 o = []
573 has = set((nullid,))
573 has = set((nullid,))
574 for n in base:
574 for n in base:
575 has.update(repo.changelog.reachable(n))
575 has.update(repo.changelog.reachable(n))
576 if revs:
576 if revs:
577 revs = [repo.lookup(rev) for rev in revs]
577 revs = [repo.lookup(rev) for rev in revs]
578 visit = revs[:]
578 visit = revs[:]
579 has.difference_update(visit)
579 has.difference_update(visit)
580 else:
580 else:
581 visit = repo.changelog.heads()
581 visit = repo.changelog.heads()
582 seen = {}
582 seen = {}
583 while visit:
583 while visit:
584 n = visit.pop(0)
584 n = visit.pop(0)
585 parents = [p for p in repo.changelog.parents(n) if p not in has]
585 parents = [p for p in repo.changelog.parents(n) if p not in has]
586 if len(parents) == 0:
586 if len(parents) == 0:
587 if n not in has:
587 if n not in has:
588 o.append(n)
588 o.append(n)
589 else:
589 else:
590 for p in parents:
590 for p in parents:
591 if p not in seen:
591 if p not in seen:
592 seen[p] = 1
592 seen[p] = 1
593 visit.append(p)
593 visit.append(p)
594 else:
594 else:
595 dest = ui.expandpath(dest or 'default-push', dest or 'default')
595 dest = ui.expandpath(dest or 'default-push', dest or 'default')
596 dest, branches = hg.parseurl(dest, opts.get('branch'))
596 dest, branches = hg.parseurl(dest, opts.get('branch'))
597 other = hg.repository(hg.remoteui(repo, opts), dest)
597 other = hg.repository(hg.remoteui(repo, opts), dest)
598 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
598 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
599 if revs:
599 if revs:
600 revs = [repo.lookup(rev) for rev in revs]
600 revs = [repo.lookup(rev) for rev in revs]
601 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
601 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
602
602
603 if not o:
603 if not o:
604 ui.status(_("no changes found\n"))
604 ui.status(_("no changes found\n"))
605 return 1
605 return 1
606
606
607 if revs:
607 if revs:
608 cg = repo.changegroupsubset(o, revs, 'bundle')
608 cg = repo.changegroupsubset(o, revs, 'bundle')
609 else:
609 else:
610 cg = repo.changegroup(o, 'bundle')
610 cg = repo.changegroup(o, 'bundle')
611
611
612 bundletype = opts.get('type', 'bzip2').lower()
612 bundletype = opts.get('type', 'bzip2').lower()
613 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
613 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
614 bundletype = btypes.get(bundletype)
614 bundletype = btypes.get(bundletype)
615 if bundletype not in changegroup.bundletypes:
615 if bundletype not in changegroup.bundletypes:
616 raise util.Abort(_('unknown bundle type specified with --type'))
616 raise util.Abort(_('unknown bundle type specified with --type'))
617
617
618 changegroup.writebundle(cg, fname, bundletype)
618 changegroup.writebundle(cg, fname, bundletype)
619
619
620 def cat(ui, repo, file1, *pats, **opts):
620 def cat(ui, repo, file1, *pats, **opts):
621 """output the current or given revision of files
621 """output the current or given revision of files
622
622
623 Print the specified files as they were at the given revision. If
623 Print the specified files as they were at the given revision. If
624 no revision is given, the parent of the working directory is used,
624 no revision is given, the parent of the working directory is used,
625 or tip if no revision is checked out.
625 or tip if no revision is checked out.
626
626
627 Output may be to a file, in which case the name of the file is
627 Output may be to a file, in which case the name of the file is
628 given using a format string. The formatting rules are the same as
628 given using a format string. The formatting rules are the same as
629 for the export command, with the following additions:
629 for the export command, with the following additions:
630
630
631 :``%s``: basename of file being printed
631 :``%s``: basename of file being printed
632 :``%d``: dirname of file being printed, or '.' if in repository root
632 :``%d``: dirname of file being printed, or '.' if in repository root
633 :``%p``: root-relative path name of file being printed
633 :``%p``: root-relative path name of file being printed
634
634
635 Returns 0 on success.
635 Returns 0 on success.
636 """
636 """
637 ctx = cmdutil.revsingle(repo, opts.get('rev'))
637 ctx = cmdutil.revsingle(repo, opts.get('rev'))
638 err = 1
638 err = 1
639 m = cmdutil.match(repo, (file1,) + pats, opts)
639 m = cmdutil.match(repo, (file1,) + pats, opts)
640 for abs in ctx.walk(m):
640 for abs in ctx.walk(m):
641 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
641 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
642 data = ctx[abs].data()
642 data = ctx[abs].data()
643 if opts.get('decode'):
643 if opts.get('decode'):
644 data = repo.wwritedata(abs, data)
644 data = repo.wwritedata(abs, data)
645 fp.write(data)
645 fp.write(data)
646 err = 0
646 err = 0
647 return err
647 return err
648
648
649 def clone(ui, source, dest=None, **opts):
649 def clone(ui, source, dest=None, **opts):
650 """make a copy of an existing repository
650 """make a copy of an existing repository
651
651
652 Create a copy of an existing repository in a new directory.
652 Create a copy of an existing repository in a new directory.
653
653
654 If no destination directory name is specified, it defaults to the
654 If no destination directory name is specified, it defaults to the
655 basename of the source.
655 basename of the source.
656
656
657 The location of the source is added to the new repository's
657 The location of the source is added to the new repository's
658 .hg/hgrc file, as the default to be used for future pulls.
658 .hg/hgrc file, as the default to be used for future pulls.
659
659
660 See :hg:`help urls` for valid source format details.
660 See :hg:`help urls` for valid source format details.
661
661
662 It is possible to specify an ``ssh://`` URL as the destination, but no
662 It is possible to specify an ``ssh://`` URL as the destination, but no
663 .hg/hgrc and working directory will be created on the remote side.
663 .hg/hgrc and working directory will be created on the remote side.
664 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
664 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
665
665
666 A set of changesets (tags, or branch names) to pull may be specified
666 A set of changesets (tags, or branch names) to pull may be specified
667 by listing each changeset (tag, or branch name) with -r/--rev.
667 by listing each changeset (tag, or branch name) with -r/--rev.
668 If -r/--rev is used, the cloned repository will contain only a subset
668 If -r/--rev is used, the cloned repository will contain only a subset
669 of the changesets of the source repository. Only the set of changesets
669 of the changesets of the source repository. Only the set of changesets
670 defined by all -r/--rev options (including all their ancestors)
670 defined by all -r/--rev options (including all their ancestors)
671 will be pulled into the destination repository.
671 will be pulled into the destination repository.
672 No subsequent changesets (including subsequent tags) will be present
672 No subsequent changesets (including subsequent tags) will be present
673 in the destination.
673 in the destination.
674
674
675 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
675 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
676 local source repositories.
676 local source repositories.
677
677
678 For efficiency, hardlinks are used for cloning whenever the source
678 For efficiency, hardlinks are used for cloning whenever the source
679 and destination are on the same filesystem (note this applies only
679 and destination are on the same filesystem (note this applies only
680 to the repository data, not to the working directory). Some
680 to the repository data, not to the working directory). Some
681 filesystems, such as AFS, implement hardlinking incorrectly, but
681 filesystems, such as AFS, implement hardlinking incorrectly, but
682 do not report errors. In these cases, use the --pull option to
682 do not report errors. In these cases, use the --pull option to
683 avoid hardlinking.
683 avoid hardlinking.
684
684
685 In some cases, you can clone repositories and the working directory
685 In some cases, you can clone repositories and the working directory
686 using full hardlinks with ::
686 using full hardlinks with ::
687
687
688 $ cp -al REPO REPOCLONE
688 $ cp -al REPO REPOCLONE
689
689
690 This is the fastest way to clone, but it is not always safe. The
690 This is the fastest way to clone, but it is not always safe. The
691 operation is not atomic (making sure REPO is not modified during
691 operation is not atomic (making sure REPO is not modified during
692 the operation is up to you) and you have to make sure your editor
692 the operation is up to you) and you have to make sure your editor
693 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
693 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
694 this is not compatible with certain extensions that place their
694 this is not compatible with certain extensions that place their
695 metadata under the .hg directory, such as mq.
695 metadata under the .hg directory, such as mq.
696
696
697 Mercurial will update the working directory to the first applicable
697 Mercurial will update the working directory to the first applicable
698 revision from this list:
698 revision from this list:
699
699
700 a) null if -U or the source repository has no changesets
700 a) null if -U or the source repository has no changesets
701 b) if -u . and the source repository is local, the first parent of
701 b) if -u . and the source repository is local, the first parent of
702 the source repository's working directory
702 the source repository's working directory
703 c) the changeset specified with -u (if a branch name, this means the
703 c) the changeset specified with -u (if a branch name, this means the
704 latest head of that branch)
704 latest head of that branch)
705 d) the changeset specified with -r
705 d) the changeset specified with -r
706 e) the tipmost head specified with -b
706 e) the tipmost head specified with -b
707 f) the tipmost head specified with the url#branch source syntax
707 f) the tipmost head specified with the url#branch source syntax
708 g) the tipmost head of the default branch
708 g) the tipmost head of the default branch
709 h) tip
709 h) tip
710
710
711 Returns 0 on success.
711 Returns 0 on success.
712 """
712 """
713 if opts.get('noupdate') and opts.get('updaterev'):
713 if opts.get('noupdate') and opts.get('updaterev'):
714 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
714 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
715
715
716 r = hg.clone(hg.remoteui(ui, opts), source, dest,
716 r = hg.clone(hg.remoteui(ui, opts), source, dest,
717 pull=opts.get('pull'),
717 pull=opts.get('pull'),
718 stream=opts.get('uncompressed'),
718 stream=opts.get('uncompressed'),
719 rev=opts.get('rev'),
719 rev=opts.get('rev'),
720 update=opts.get('updaterev') or not opts.get('noupdate'),
720 update=opts.get('updaterev') or not opts.get('noupdate'),
721 branch=opts.get('branch'))
721 branch=opts.get('branch'))
722
722
723 return r is None
723 return r is None
724
724
725 def commit(ui, repo, *pats, **opts):
725 def commit(ui, repo, *pats, **opts):
726 """commit the specified files or all outstanding changes
726 """commit the specified files or all outstanding changes
727
727
728 Commit changes to the given files into the repository. Unlike a
728 Commit changes to the given files into the repository. Unlike a
729 centralized RCS, this operation is a local operation. See
729 centralized RCS, this operation is a local operation. See
730 :hg:`push` for a way to actively distribute your changes.
730 :hg:`push` for a way to actively distribute your changes.
731
731
732 If a list of files is omitted, all changes reported by :hg:`status`
732 If a list of files is omitted, all changes reported by :hg:`status`
733 will be committed.
733 will be committed.
734
734
735 If you are committing the result of a merge, do not provide any
735 If you are committing the result of a merge, do not provide any
736 filenames or -I/-X filters.
736 filenames or -I/-X filters.
737
737
738 If no commit message is specified, Mercurial starts your
738 If no commit message is specified, Mercurial starts your
739 configured editor where you can enter a message. In case your
739 configured editor where you can enter a message. In case your
740 commit fails, you will find a backup of your message in
740 commit fails, you will find a backup of your message in
741 ``.hg/last-message.txt``.
741 ``.hg/last-message.txt``.
742
742
743 See :hg:`help dates` for a list of formats valid for -d/--date.
743 See :hg:`help dates` for a list of formats valid for -d/--date.
744
744
745 Returns 0 on success, 1 if nothing changed.
745 Returns 0 on success, 1 if nothing changed.
746 """
746 """
747 extra = {}
747 extra = {}
748 if opts.get('close_branch'):
748 if opts.get('close_branch'):
749 if repo['.'].node() not in repo.branchheads():
749 if repo['.'].node() not in repo.branchheads():
750 # The topo heads set is included in the branch heads set of the
750 # The topo heads set is included in the branch heads set of the
751 # current branch, so it's sufficient to test branchheads
751 # current branch, so it's sufficient to test branchheads
752 raise util.Abort(_('can only close branch heads'))
752 raise util.Abort(_('can only close branch heads'))
753 extra['close'] = 1
753 extra['close'] = 1
754 e = cmdutil.commiteditor
754 e = cmdutil.commiteditor
755 if opts.get('force_editor'):
755 if opts.get('force_editor'):
756 e = cmdutil.commitforceeditor
756 e = cmdutil.commitforceeditor
757
757
758 def commitfunc(ui, repo, message, match, opts):
758 def commitfunc(ui, repo, message, match, opts):
759 return repo.commit(message, opts.get('user'), opts.get('date'), match,
759 return repo.commit(message, opts.get('user'), opts.get('date'), match,
760 editor=e, extra=extra)
760 editor=e, extra=extra)
761
761
762 branch = repo[None].branch()
762 branch = repo[None].branch()
763 bheads = repo.branchheads(branch)
763 bheads = repo.branchheads(branch)
764
764
765 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
765 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
766 if not node:
766 if not node:
767 ui.status(_("nothing changed\n"))
767 ui.status(_("nothing changed\n"))
768 return 1
768 return 1
769
769
770 ctx = repo[node]
770 ctx = repo[node]
771 parents = ctx.parents()
771 parents = ctx.parents()
772
772
773 if bheads and not [x for x in parents
773 if bheads and not [x for x in parents
774 if x.node() in bheads and x.branch() == branch]:
774 if x.node() in bheads and x.branch() == branch]:
775 ui.status(_('created new head\n'))
775 ui.status(_('created new head\n'))
776 # The message is not printed for initial roots. For the other
776 # The message is not printed for initial roots. For the other
777 # changesets, it is printed in the following situations:
777 # changesets, it is printed in the following situations:
778 #
778 #
779 # Par column: for the 2 parents with ...
779 # Par column: for the 2 parents with ...
780 # N: null or no parent
780 # N: null or no parent
781 # B: parent is on another named branch
781 # B: parent is on another named branch
782 # C: parent is a regular non head changeset
782 # C: parent is a regular non head changeset
783 # H: parent was a branch head of the current branch
783 # H: parent was a branch head of the current branch
784 # Msg column: whether we print "created new head" message
784 # Msg column: whether we print "created new head" message
785 # In the following, it is assumed that there already exists some
785 # In the following, it is assumed that there already exists some
786 # initial branch heads of the current branch, otherwise nothing is
786 # initial branch heads of the current branch, otherwise nothing is
787 # printed anyway.
787 # printed anyway.
788 #
788 #
789 # Par Msg Comment
789 # Par Msg Comment
790 # NN y additional topo root
790 # NN y additional topo root
791 #
791 #
792 # BN y additional branch root
792 # BN y additional branch root
793 # CN y additional topo head
793 # CN y additional topo head
794 # HN n usual case
794 # HN n usual case
795 #
795 #
796 # BB y weird additional branch root
796 # BB y weird additional branch root
797 # CB y branch merge
797 # CB y branch merge
798 # HB n merge with named branch
798 # HB n merge with named branch
799 #
799 #
800 # CC y additional head from merge
800 # CC y additional head from merge
801 # CH n merge with a head
801 # CH n merge with a head
802 #
802 #
803 # HH n head merge: head count decreases
803 # HH n head merge: head count decreases
804
804
805 if not opts.get('close_branch'):
805 if not opts.get('close_branch'):
806 for r in parents:
806 for r in parents:
807 if r.extra().get('close') and r.branch() == branch:
807 if r.extra().get('close') and r.branch() == branch:
808 ui.status(_('reopening closed branch head %d\n') % r)
808 ui.status(_('reopening closed branch head %d\n') % r)
809
809
810 if ui.debugflag:
810 if ui.debugflag:
811 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
811 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
812 elif ui.verbose:
812 elif ui.verbose:
813 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
813 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
814
814
815 def copy(ui, repo, *pats, **opts):
815 def copy(ui, repo, *pats, **opts):
816 """mark files as copied for the next commit
816 """mark files as copied for the next commit
817
817
818 Mark dest as having copies of source files. If dest is a
818 Mark dest as having copies of source files. If dest is a
819 directory, copies are put in that directory. If dest is a file,
819 directory, copies are put in that directory. If dest is a file,
820 the source must be a single file.
820 the source must be a single file.
821
821
822 By default, this command copies the contents of files as they
822 By default, this command copies the contents of files as they
823 exist in the working directory. If invoked with -A/--after, the
823 exist in the working directory. If invoked with -A/--after, the
824 operation is recorded, but no copying is performed.
824 operation is recorded, but no copying is performed.
825
825
826 This command takes effect with the next commit. To undo a copy
826 This command takes effect with the next commit. To undo a copy
827 before that, see :hg:`revert`.
827 before that, see :hg:`revert`.
828
828
829 Returns 0 on success, 1 if errors are encountered.
829 Returns 0 on success, 1 if errors are encountered.
830 """
830 """
831 wlock = repo.wlock(False)
831 wlock = repo.wlock(False)
832 try:
832 try:
833 return cmdutil.copy(ui, repo, pats, opts)
833 return cmdutil.copy(ui, repo, pats, opts)
834 finally:
834 finally:
835 wlock.release()
835 wlock.release()
836
836
837 def debugancestor(ui, repo, *args):
837 def debugancestor(ui, repo, *args):
838 """find the ancestor revision of two revisions in a given index"""
838 """find the ancestor revision of two revisions in a given index"""
839 if len(args) == 3:
839 if len(args) == 3:
840 index, rev1, rev2 = args
840 index, rev1, rev2 = args
841 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
841 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
842 lookup = r.lookup
842 lookup = r.lookup
843 elif len(args) == 2:
843 elif len(args) == 2:
844 if not repo:
844 if not repo:
845 raise util.Abort(_("there is no Mercurial repository here "
845 raise util.Abort(_("there is no Mercurial repository here "
846 "(.hg not found)"))
846 "(.hg not found)"))
847 rev1, rev2 = args
847 rev1, rev2 = args
848 r = repo.changelog
848 r = repo.changelog
849 lookup = repo.lookup
849 lookup = repo.lookup
850 else:
850 else:
851 raise util.Abort(_('either two or three arguments required'))
851 raise util.Abort(_('either two or three arguments required'))
852 a = r.ancestor(lookup(rev1), lookup(rev2))
852 a = r.ancestor(lookup(rev1), lookup(rev2))
853 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
853 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
854
854
855 def debugbuilddag(ui, repo, text,
855 def debugbuilddag(ui, repo, text,
856 mergeable_file=False,
856 mergeable_file=False,
857 appended_file=False,
857 appended_file=False,
858 overwritten_file=False,
858 overwritten_file=False,
859 new_file=False):
859 new_file=False):
860 """builds a repo with a given dag from scratch in the current empty repo
860 """builds a repo with a given dag from scratch in the current empty repo
861
861
862 Elements:
862 Elements:
863
863
864 - "+n" is a linear run of n nodes based on the current default parent
864 - "+n" is a linear run of n nodes based on the current default parent
865 - "." is a single node based on the current default parent
865 - "." is a single node based on the current default parent
866 - "$" resets the default parent to null (implied at the start);
866 - "$" resets the default parent to null (implied at the start);
867 otherwise the default parent is always the last node created
867 otherwise the default parent is always the last node created
868 - "<p" sets the default parent to the backref p
868 - "<p" sets the default parent to the backref p
869 - "*p" is a fork at parent p, which is a backref
869 - "*p" is a fork at parent p, which is a backref
870 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
870 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
871 - "/p2" is a merge of the preceding node and p2
871 - "/p2" is a merge of the preceding node and p2
872 - ":tag" defines a local tag for the preceding node
872 - ":tag" defines a local tag for the preceding node
873 - "@branch" sets the named branch for subsequent nodes
873 - "@branch" sets the named branch for subsequent nodes
874 - "!command" runs the command using your shell
874 - "!command" runs the command using your shell
875 - "!!my command\\n" is like "!", but to the end of the line
875 - "!!my command\\n" is like "!", but to the end of the line
876 - "#...\\n" is a comment up to the end of the line
876 - "#...\\n" is a comment up to the end of the line
877
877
878 Whitespace between the above elements is ignored.
878 Whitespace between the above elements is ignored.
879
879
880 A backref is either
880 A backref is either
881
881
882 - a number n, which references the node curr-n, where curr is the current
882 - a number n, which references the node curr-n, where curr is the current
883 node, or
883 node, or
884 - the name of a local tag you placed earlier using ":tag", or
884 - the name of a local tag you placed earlier using ":tag", or
885 - empty to denote the default parent.
885 - empty to denote the default parent.
886
886
887 All string valued-elements are either strictly alphanumeric, or must
887 All string valued-elements are either strictly alphanumeric, or must
888 be enclosed in double quotes ("..."), with "\\" as escape character.
888 be enclosed in double quotes ("..."), with "\\" as escape character.
889
889
890 Note that the --overwritten-file and --appended-file options imply the
890 Note that the --overwritten-file and --appended-file options imply the
891 use of "HGMERGE=internal:local" during DAG buildup.
891 use of "HGMERGE=internal:local" during DAG buildup.
892 """
892 """
893
893
894 if not (mergeable_file or appended_file or overwritten_file or new_file):
894 if not (mergeable_file or appended_file or overwritten_file or new_file):
895 raise util.Abort(_('need at least one of -m, -a, -o, -n'))
895 raise util.Abort(_('need at least one of -m, -a, -o, -n'))
896
896
897 if len(repo.changelog) > 0:
897 if len(repo.changelog) > 0:
898 raise util.Abort(_('repository is not empty'))
898 raise util.Abort(_('repository is not empty'))
899
899
900 if overwritten_file or appended_file:
900 if overwritten_file or appended_file:
901 # we don't want to fail in merges during buildup
901 # we don't want to fail in merges during buildup
902 os.environ['HGMERGE'] = 'internal:local'
902 os.environ['HGMERGE'] = 'internal:local'
903
903
904 def writefile(fname, text, fmode="wb"):
904 def writefile(fname, text, fmode="wb"):
905 f = open(fname, fmode)
905 f = open(fname, fmode)
906 try:
906 try:
907 f.write(text)
907 f.write(text)
908 finally:
908 finally:
909 f.close()
909 f.close()
910
910
911 if mergeable_file:
911 if mergeable_file:
912 linesperrev = 2
912 linesperrev = 2
913 # determine number of revs in DAG
913 # determine number of revs in DAG
914 n = 0
914 n = 0
915 for type, data in dagparser.parsedag(text):
915 for type, data in dagparser.parsedag(text):
916 if type == 'n':
916 if type == 'n':
917 n += 1
917 n += 1
918 # make a file with k lines per rev
918 # make a file with k lines per rev
919 writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
919 writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
920 + "\n")
920 + "\n")
921
921
922 at = -1
922 at = -1
923 atbranch = 'default'
923 atbranch = 'default'
924 for type, data in dagparser.parsedag(text):
924 for type, data in dagparser.parsedag(text):
925 if type == 'n':
925 if type == 'n':
926 ui.status('node %s\n' % str(data))
926 ui.status('node %s\n' % str(data))
927 id, ps = data
927 id, ps = data
928 p1 = ps[0]
928 p1 = ps[0]
929 if p1 != at:
929 if p1 != at:
930 update(ui, repo, node=p1, clean=True)
930 update(ui, repo, node=p1, clean=True)
931 at = p1
931 at = p1
932 if repo.dirstate.branch() != atbranch:
932 if repo.dirstate.branch() != atbranch:
933 branch(ui, repo, atbranch, force=True)
933 branch(ui, repo, atbranch, force=True)
934 if len(ps) > 1:
934 if len(ps) > 1:
935 p2 = ps[1]
935 p2 = ps[1]
936 merge(ui, repo, node=p2)
936 merge(ui, repo, node=p2)
937
937
938 if mergeable_file:
938 if mergeable_file:
939 f = open("mf", "rb+")
939 f = open("mf", "rb+")
940 try:
940 try:
941 lines = f.read().split("\n")
941 lines = f.read().split("\n")
942 lines[id * linesperrev] += " r%i" % id
942 lines[id * linesperrev] += " r%i" % id
943 f.seek(0)
943 f.seek(0)
944 f.write("\n".join(lines))
944 f.write("\n".join(lines))
945 finally:
945 finally:
946 f.close()
946 f.close()
947
947
948 if appended_file:
948 if appended_file:
949 writefile("af", "r%i\n" % id, "ab")
949 writefile("af", "r%i\n" % id, "ab")
950
950
951 if overwritten_file:
951 if overwritten_file:
952 writefile("of", "r%i\n" % id)
952 writefile("of", "r%i\n" % id)
953
953
954 if new_file:
954 if new_file:
955 writefile("nf%i" % id, "r%i\n" % id)
955 writefile("nf%i" % id, "r%i\n" % id)
956
956
957 commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
957 commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
958 at = id
958 at = id
959 elif type == 'l':
959 elif type == 'l':
960 id, name = data
960 id, name = data
961 ui.status('tag %s\n' % name)
961 ui.status('tag %s\n' % name)
962 tag(ui, repo, name, local=True)
962 tag(ui, repo, name, local=True)
963 elif type == 'a':
963 elif type == 'a':
964 ui.status('branch %s\n' % data)
964 ui.status('branch %s\n' % data)
965 atbranch = data
965 atbranch = data
966 elif type in 'cC':
966 elif type in 'cC':
967 r = util.system(data, cwd=repo.root)
967 r = util.system(data, cwd=repo.root)
968 if r:
968 if r:
969 desc, r = util.explain_exit(r)
969 desc, r = util.explain_exit(r)
970 raise util.Abort(_('%s command %s') % (data, desc))
970 raise util.Abort(_('%s command %s') % (data, desc))
971
971
972 def debugcommands(ui, cmd='', *args):
972 def debugcommands(ui, cmd='', *args):
973 """list all available commands and options"""
973 """list all available commands and options"""
974 for cmd, vals in sorted(table.iteritems()):
974 for cmd, vals in sorted(table.iteritems()):
975 cmd = cmd.split('|')[0].strip('^')
975 cmd = cmd.split('|')[0].strip('^')
976 opts = ', '.join([i[1] for i in vals[1]])
976 opts = ', '.join([i[1] for i in vals[1]])
977 ui.write('%s: %s\n' % (cmd, opts))
977 ui.write('%s: %s\n' % (cmd, opts))
978
978
979 def debugcomplete(ui, cmd='', **opts):
979 def debugcomplete(ui, cmd='', **opts):
980 """returns the completion list associated with the given command"""
980 """returns the completion list associated with the given command"""
981
981
982 if opts.get('options'):
982 if opts.get('options'):
983 options = []
983 options = []
984 otables = [globalopts]
984 otables = [globalopts]
985 if cmd:
985 if cmd:
986 aliases, entry = cmdutil.findcmd(cmd, table, False)
986 aliases, entry = cmdutil.findcmd(cmd, table, False)
987 otables.append(entry[1])
987 otables.append(entry[1])
988 for t in otables:
988 for t in otables:
989 for o in t:
989 for o in t:
990 if "(DEPRECATED)" in o[3]:
990 if "(DEPRECATED)" in o[3]:
991 continue
991 continue
992 if o[0]:
992 if o[0]:
993 options.append('-%s' % o[0])
993 options.append('-%s' % o[0])
994 options.append('--%s' % o[1])
994 options.append('--%s' % o[1])
995 ui.write("%s\n" % "\n".join(options))
995 ui.write("%s\n" % "\n".join(options))
996 return
996 return
997
997
998 cmdlist = cmdutil.findpossible(cmd, table)
998 cmdlist = cmdutil.findpossible(cmd, table)
999 if ui.verbose:
999 if ui.verbose:
1000 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1000 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1001 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1001 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1002
1002
1003 def debugfsinfo(ui, path = "."):
1003 def debugfsinfo(ui, path = "."):
1004 """show information detected about current filesystem"""
1004 """show information detected about current filesystem"""
1005 open('.debugfsinfo', 'w').write('')
1005 open('.debugfsinfo', 'w').write('')
1006 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1006 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1007 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1007 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1008 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1008 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1009 and 'yes' or 'no'))
1009 and 'yes' or 'no'))
1010 os.unlink('.debugfsinfo')
1010 os.unlink('.debugfsinfo')
1011
1011
1012 def debugrebuildstate(ui, repo, rev="tip"):
1012 def debugrebuildstate(ui, repo, rev="tip"):
1013 """rebuild the dirstate as it would look like for the given revision"""
1013 """rebuild the dirstate as it would look like for the given revision"""
1014 ctx = repo[rev]
1014 ctx = repo[rev]
1015 wlock = repo.wlock()
1015 wlock = repo.wlock()
1016 try:
1016 try:
1017 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1017 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1018 finally:
1018 finally:
1019 wlock.release()
1019 wlock.release()
1020
1020
1021 def debugcheckstate(ui, repo):
1021 def debugcheckstate(ui, repo):
1022 """validate the correctness of the current dirstate"""
1022 """validate the correctness of the current dirstate"""
1023 parent1, parent2 = repo.dirstate.parents()
1023 parent1, parent2 = repo.dirstate.parents()
1024 m1 = repo[parent1].manifest()
1024 m1 = repo[parent1].manifest()
1025 m2 = repo[parent2].manifest()
1025 m2 = repo[parent2].manifest()
1026 errors = 0
1026 errors = 0
1027 for f in repo.dirstate:
1027 for f in repo.dirstate:
1028 state = repo.dirstate[f]
1028 state = repo.dirstate[f]
1029 if state in "nr" and f not in m1:
1029 if state in "nr" and f not in m1:
1030 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1030 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1031 errors += 1
1031 errors += 1
1032 if state in "a" and f in m1:
1032 if state in "a" and f in m1:
1033 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1033 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1034 errors += 1
1034 errors += 1
1035 if state in "m" and f not in m1 and f not in m2:
1035 if state in "m" and f not in m1 and f not in m2:
1036 ui.warn(_("%s in state %s, but not in either manifest\n") %
1036 ui.warn(_("%s in state %s, but not in either manifest\n") %
1037 (f, state))
1037 (f, state))
1038 errors += 1
1038 errors += 1
1039 for f in m1:
1039 for f in m1:
1040 state = repo.dirstate[f]
1040 state = repo.dirstate[f]
1041 if state not in "nrm":
1041 if state not in "nrm":
1042 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1042 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1043 errors += 1
1043 errors += 1
1044 if errors:
1044 if errors:
1045 error = _(".hg/dirstate inconsistent with current parent's manifest")
1045 error = _(".hg/dirstate inconsistent with current parent's manifest")
1046 raise util.Abort(error)
1046 raise util.Abort(error)
1047
1047
1048 def showconfig(ui, repo, *values, **opts):
1048 def showconfig(ui, repo, *values, **opts):
1049 """show combined config settings from all hgrc files
1049 """show combined config settings from all hgrc files
1050
1050
1051 With no arguments, print names and values of all config items.
1051 With no arguments, print names and values of all config items.
1052
1052
1053 With one argument of the form section.name, print just the value
1053 With one argument of the form section.name, print just the value
1054 of that config item.
1054 of that config item.
1055
1055
1056 With multiple arguments, print names and values of all config
1056 With multiple arguments, print names and values of all config
1057 items with matching section names.
1057 items with matching section names.
1058
1058
1059 With --debug, the source (filename and line number) is printed
1059 With --debug, the source (filename and line number) is printed
1060 for each config item.
1060 for each config item.
1061
1061
1062 Returns 0 on success.
1062 Returns 0 on success.
1063 """
1063 """
1064
1064
1065 for f in util.rcpath():
1065 for f in util.rcpath():
1066 ui.debug(_('read config from: %s\n') % f)
1066 ui.debug(_('read config from: %s\n') % f)
1067 untrusted = bool(opts.get('untrusted'))
1067 untrusted = bool(opts.get('untrusted'))
1068 if values:
1068 if values:
1069 if len([v for v in values if '.' in v]) > 1:
1069 sections = [v for v in values if '.' not in v]
1070 items = [v for v in values if '.' in v]
1071 if len(items) > 1 or items and sections:
1070 raise util.Abort(_('only one config item permitted'))
1072 raise util.Abort(_('only one config item permitted'))
1071 for section, name, value in ui.walkconfig(untrusted=untrusted):
1073 for section, name, value in ui.walkconfig(untrusted=untrusted):
1072 sectname = section + '.' + name
1074 sectname = section + '.' + name
1073 if values:
1075 if values:
1074 for v in values:
1076 for v in values:
1075 if v == section:
1077 if v == section:
1076 ui.debug('%s: ' %
1078 ui.debug('%s: ' %
1077 ui.configsource(section, name, untrusted))
1079 ui.configsource(section, name, untrusted))
1078 ui.write('%s=%s\n' % (sectname, value))
1080 ui.write('%s=%s\n' % (sectname, value))
1079 elif v == sectname:
1081 elif v == sectname:
1080 ui.debug('%s: ' %
1082 ui.debug('%s: ' %
1081 ui.configsource(section, name, untrusted))
1083 ui.configsource(section, name, untrusted))
1082 ui.write(value, '\n')
1084 ui.write(value, '\n')
1083 else:
1085 else:
1084 ui.debug('%s: ' %
1086 ui.debug('%s: ' %
1085 ui.configsource(section, name, untrusted))
1087 ui.configsource(section, name, untrusted))
1086 ui.write('%s=%s\n' % (sectname, value))
1088 ui.write('%s=%s\n' % (sectname, value))
1087
1089
1088 def debugpushkey(ui, repopath, namespace, *keyinfo):
1090 def debugpushkey(ui, repopath, namespace, *keyinfo):
1089 '''access the pushkey key/value protocol
1091 '''access the pushkey key/value protocol
1090
1092
1091 With two args, list the keys in the given namespace.
1093 With two args, list the keys in the given namespace.
1092
1094
1093 With five args, set a key to new if it currently is set to old.
1095 With five args, set a key to new if it currently is set to old.
1094 Reports success or failure.
1096 Reports success or failure.
1095 '''
1097 '''
1096
1098
1097 target = hg.repository(ui, repopath)
1099 target = hg.repository(ui, repopath)
1098 if keyinfo:
1100 if keyinfo:
1099 key, old, new = keyinfo
1101 key, old, new = keyinfo
1100 r = target.pushkey(namespace, key, old, new)
1102 r = target.pushkey(namespace, key, old, new)
1101 ui.status(str(r) + '\n')
1103 ui.status(str(r) + '\n')
1102 return not(r)
1104 return not(r)
1103 else:
1105 else:
1104 for k, v in target.listkeys(namespace).iteritems():
1106 for k, v in target.listkeys(namespace).iteritems():
1105 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1107 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1106 v.encode('string-escape')))
1108 v.encode('string-escape')))
1107
1109
1108 def debugrevspec(ui, repo, expr):
1110 def debugrevspec(ui, repo, expr):
1109 '''parse and apply a revision specification'''
1111 '''parse and apply a revision specification'''
1110 if ui.verbose:
1112 if ui.verbose:
1111 tree = revset.parse(expr)
1113 tree = revset.parse(expr)
1112 ui.note(tree, "\n")
1114 ui.note(tree, "\n")
1113 func = revset.match(expr)
1115 func = revset.match(expr)
1114 for c in func(repo, range(len(repo))):
1116 for c in func(repo, range(len(repo))):
1115 ui.write("%s\n" % c)
1117 ui.write("%s\n" % c)
1116
1118
1117 def debugsetparents(ui, repo, rev1, rev2=None):
1119 def debugsetparents(ui, repo, rev1, rev2=None):
1118 """manually set the parents of the current working directory
1120 """manually set the parents of the current working directory
1119
1121
1120 This is useful for writing repository conversion tools, but should
1122 This is useful for writing repository conversion tools, but should
1121 be used with care.
1123 be used with care.
1122
1124
1123 Returns 0 on success.
1125 Returns 0 on success.
1124 """
1126 """
1125
1127
1126 if not rev2:
1128 if not rev2:
1127 rev2 = hex(nullid)
1129 rev2 = hex(nullid)
1128
1130
1129 wlock = repo.wlock()
1131 wlock = repo.wlock()
1130 try:
1132 try:
1131 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
1133 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
1132 finally:
1134 finally:
1133 wlock.release()
1135 wlock.release()
1134
1136
1135 def debugstate(ui, repo, nodates=None):
1137 def debugstate(ui, repo, nodates=None):
1136 """show the contents of the current dirstate"""
1138 """show the contents of the current dirstate"""
1137 timestr = ""
1139 timestr = ""
1138 showdate = not nodates
1140 showdate = not nodates
1139 for file_, ent in sorted(repo.dirstate._map.iteritems()):
1141 for file_, ent in sorted(repo.dirstate._map.iteritems()):
1140 if showdate:
1142 if showdate:
1141 if ent[3] == -1:
1143 if ent[3] == -1:
1142 # Pad or slice to locale representation
1144 # Pad or slice to locale representation
1143 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1145 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1144 time.localtime(0)))
1146 time.localtime(0)))
1145 timestr = 'unset'
1147 timestr = 'unset'
1146 timestr = (timestr[:locale_len] +
1148 timestr = (timestr[:locale_len] +
1147 ' ' * (locale_len - len(timestr)))
1149 ' ' * (locale_len - len(timestr)))
1148 else:
1150 else:
1149 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1151 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1150 time.localtime(ent[3]))
1152 time.localtime(ent[3]))
1151 if ent[1] & 020000:
1153 if ent[1] & 020000:
1152 mode = 'lnk'
1154 mode = 'lnk'
1153 else:
1155 else:
1154 mode = '%3o' % (ent[1] & 0777)
1156 mode = '%3o' % (ent[1] & 0777)
1155 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1157 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1156 for f in repo.dirstate.copies():
1158 for f in repo.dirstate.copies():
1157 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1159 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1158
1160
1159 def debugsub(ui, repo, rev=None):
1161 def debugsub(ui, repo, rev=None):
1160 if rev == '':
1162 if rev == '':
1161 rev = None
1163 rev = None
1162 for k, v in sorted(repo[rev].substate.items()):
1164 for k, v in sorted(repo[rev].substate.items()):
1163 ui.write('path %s\n' % k)
1165 ui.write('path %s\n' % k)
1164 ui.write(' source %s\n' % v[0])
1166 ui.write(' source %s\n' % v[0])
1165 ui.write(' revision %s\n' % v[1])
1167 ui.write(' revision %s\n' % v[1])
1166
1168
1167 def debugdag(ui, repo, file_=None, *revs, **opts):
1169 def debugdag(ui, repo, file_=None, *revs, **opts):
1168 """format the changelog or an index DAG as a concise textual description
1170 """format the changelog or an index DAG as a concise textual description
1169
1171
1170 If you pass a revlog index, the revlog's DAG is emitted. If you list
1172 If you pass a revlog index, the revlog's DAG is emitted. If you list
1171 revision numbers, they get labelled in the output as rN.
1173 revision numbers, they get labelled in the output as rN.
1172
1174
1173 Otherwise, the changelog DAG of the current repo is emitted.
1175 Otherwise, the changelog DAG of the current repo is emitted.
1174 """
1176 """
1175 spaces = opts.get('spaces')
1177 spaces = opts.get('spaces')
1176 dots = opts.get('dots')
1178 dots = opts.get('dots')
1177 if file_:
1179 if file_:
1178 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1180 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1179 revs = set((int(r) for r in revs))
1181 revs = set((int(r) for r in revs))
1180 def events():
1182 def events():
1181 for r in rlog:
1183 for r in rlog:
1182 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1184 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1183 if r in revs:
1185 if r in revs:
1184 yield 'l', (r, "r%i" % r)
1186 yield 'l', (r, "r%i" % r)
1185 elif repo:
1187 elif repo:
1186 cl = repo.changelog
1188 cl = repo.changelog
1187 tags = opts.get('tags')
1189 tags = opts.get('tags')
1188 branches = opts.get('branches')
1190 branches = opts.get('branches')
1189 if tags:
1191 if tags:
1190 labels = {}
1192 labels = {}
1191 for l, n in repo.tags().items():
1193 for l, n in repo.tags().items():
1192 labels.setdefault(cl.rev(n), []).append(l)
1194 labels.setdefault(cl.rev(n), []).append(l)
1193 def events():
1195 def events():
1194 b = "default"
1196 b = "default"
1195 for r in cl:
1197 for r in cl:
1196 if branches:
1198 if branches:
1197 newb = cl.read(cl.node(r))[5]['branch']
1199 newb = cl.read(cl.node(r))[5]['branch']
1198 if newb != b:
1200 if newb != b:
1199 yield 'a', newb
1201 yield 'a', newb
1200 b = newb
1202 b = newb
1201 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1203 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1202 if tags:
1204 if tags:
1203 ls = labels.get(r)
1205 ls = labels.get(r)
1204 if ls:
1206 if ls:
1205 for l in ls:
1207 for l in ls:
1206 yield 'l', (r, l)
1208 yield 'l', (r, l)
1207 else:
1209 else:
1208 raise util.Abort(_('need repo for changelog dag'))
1210 raise util.Abort(_('need repo for changelog dag'))
1209
1211
1210 for line in dagparser.dagtextlines(events(),
1212 for line in dagparser.dagtextlines(events(),
1211 addspaces=spaces,
1213 addspaces=spaces,
1212 wraplabels=True,
1214 wraplabels=True,
1213 wrapannotations=True,
1215 wrapannotations=True,
1214 wrapnonlinear=dots,
1216 wrapnonlinear=dots,
1215 usedots=dots,
1217 usedots=dots,
1216 maxlinewidth=70):
1218 maxlinewidth=70):
1217 ui.write(line)
1219 ui.write(line)
1218 ui.write("\n")
1220 ui.write("\n")
1219
1221
1220 def debugdata(ui, repo, file_, rev):
1222 def debugdata(ui, repo, file_, rev):
1221 """dump the contents of a data file revision"""
1223 """dump the contents of a data file revision"""
1222 r = None
1224 r = None
1223 if repo:
1225 if repo:
1224 filelog = repo.file(file_)
1226 filelog = repo.file(file_)
1225 if len(filelog):
1227 if len(filelog):
1226 r = filelog
1228 r = filelog
1227 if not r:
1229 if not r:
1228 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1230 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1229 try:
1231 try:
1230 ui.write(r.revision(r.lookup(rev)))
1232 ui.write(r.revision(r.lookup(rev)))
1231 except KeyError:
1233 except KeyError:
1232 raise util.Abort(_('invalid revision identifier %s') % rev)
1234 raise util.Abort(_('invalid revision identifier %s') % rev)
1233
1235
1234 def debugdate(ui, date, range=None, **opts):
1236 def debugdate(ui, date, range=None, **opts):
1235 """parse and display a date"""
1237 """parse and display a date"""
1236 if opts["extended"]:
1238 if opts["extended"]:
1237 d = util.parsedate(date, util.extendeddateformats)
1239 d = util.parsedate(date, util.extendeddateformats)
1238 else:
1240 else:
1239 d = util.parsedate(date)
1241 d = util.parsedate(date)
1240 ui.write("internal: %s %s\n" % d)
1242 ui.write("internal: %s %s\n" % d)
1241 ui.write("standard: %s\n" % util.datestr(d))
1243 ui.write("standard: %s\n" % util.datestr(d))
1242 if range:
1244 if range:
1243 m = util.matchdate(range)
1245 m = util.matchdate(range)
1244 ui.write("match: %s\n" % m(d[0]))
1246 ui.write("match: %s\n" % m(d[0]))
1245
1247
1246 def debugindex(ui, repo, file_):
1248 def debugindex(ui, repo, file_):
1247 """dump the contents of an index file"""
1249 """dump the contents of an index file"""
1248 r = None
1250 r = None
1249 if repo:
1251 if repo:
1250 filelog = repo.file(file_)
1252 filelog = repo.file(file_)
1251 if len(filelog):
1253 if len(filelog):
1252 r = filelog
1254 r = filelog
1253 if not r:
1255 if not r:
1254 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1256 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1255 ui.write(" rev offset length base linkrev"
1257 ui.write(" rev offset length base linkrev"
1256 " nodeid p1 p2\n")
1258 " nodeid p1 p2\n")
1257 for i in r:
1259 for i in r:
1258 node = r.node(i)
1260 node = r.node(i)
1259 try:
1261 try:
1260 pp = r.parents(node)
1262 pp = r.parents(node)
1261 except:
1263 except:
1262 pp = [nullid, nullid]
1264 pp = [nullid, nullid]
1263 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1265 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1264 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1266 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1265 short(node), short(pp[0]), short(pp[1])))
1267 short(node), short(pp[0]), short(pp[1])))
1266
1268
1267 def debugindexdot(ui, repo, file_):
1269 def debugindexdot(ui, repo, file_):
1268 """dump an index DAG as a graphviz dot file"""
1270 """dump an index DAG as a graphviz dot file"""
1269 r = None
1271 r = None
1270 if repo:
1272 if repo:
1271 filelog = repo.file(file_)
1273 filelog = repo.file(file_)
1272 if len(filelog):
1274 if len(filelog):
1273 r = filelog
1275 r = filelog
1274 if not r:
1276 if not r:
1275 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1277 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1276 ui.write("digraph G {\n")
1278 ui.write("digraph G {\n")
1277 for i in r:
1279 for i in r:
1278 node = r.node(i)
1280 node = r.node(i)
1279 pp = r.parents(node)
1281 pp = r.parents(node)
1280 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1282 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1281 if pp[1] != nullid:
1283 if pp[1] != nullid:
1282 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1284 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1283 ui.write("}\n")
1285 ui.write("}\n")
1284
1286
1285 def debuginstall(ui):
1287 def debuginstall(ui):
1286 '''test Mercurial installation
1288 '''test Mercurial installation
1287
1289
1288 Returns 0 on success.
1290 Returns 0 on success.
1289 '''
1291 '''
1290
1292
1291 def writetemp(contents):
1293 def writetemp(contents):
1292 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1294 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1293 f = os.fdopen(fd, "wb")
1295 f = os.fdopen(fd, "wb")
1294 f.write(contents)
1296 f.write(contents)
1295 f.close()
1297 f.close()
1296 return name
1298 return name
1297
1299
1298 problems = 0
1300 problems = 0
1299
1301
1300 # encoding
1302 # encoding
1301 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1303 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1302 try:
1304 try:
1303 encoding.fromlocal("test")
1305 encoding.fromlocal("test")
1304 except util.Abort, inst:
1306 except util.Abort, inst:
1305 ui.write(" %s\n" % inst)
1307 ui.write(" %s\n" % inst)
1306 ui.write(_(" (check that your locale is properly set)\n"))
1308 ui.write(_(" (check that your locale is properly set)\n"))
1307 problems += 1
1309 problems += 1
1308
1310
1309 # compiled modules
1311 # compiled modules
1310 ui.status(_("Checking installed modules (%s)...\n")
1312 ui.status(_("Checking installed modules (%s)...\n")
1311 % os.path.dirname(__file__))
1313 % os.path.dirname(__file__))
1312 try:
1314 try:
1313 import bdiff, mpatch, base85, osutil
1315 import bdiff, mpatch, base85, osutil
1314 except Exception, inst:
1316 except Exception, inst:
1315 ui.write(" %s\n" % inst)
1317 ui.write(" %s\n" % inst)
1316 ui.write(_(" One or more extensions could not be found"))
1318 ui.write(_(" One or more extensions could not be found"))
1317 ui.write(_(" (check that you compiled the extensions)\n"))
1319 ui.write(_(" (check that you compiled the extensions)\n"))
1318 problems += 1
1320 problems += 1
1319
1321
1320 # templates
1322 # templates
1321 ui.status(_("Checking templates...\n"))
1323 ui.status(_("Checking templates...\n"))
1322 try:
1324 try:
1323 import templater
1325 import templater
1324 templater.templater(templater.templatepath("map-cmdline.default"))
1326 templater.templater(templater.templatepath("map-cmdline.default"))
1325 except Exception, inst:
1327 except Exception, inst:
1326 ui.write(" %s\n" % inst)
1328 ui.write(" %s\n" % inst)
1327 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1329 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1328 problems += 1
1330 problems += 1
1329
1331
1330 # patch
1332 # patch
1331 ui.status(_("Checking patch...\n"))
1333 ui.status(_("Checking patch...\n"))
1332 patchproblems = 0
1334 patchproblems = 0
1333 a = "1\n2\n3\n4\n"
1335 a = "1\n2\n3\n4\n"
1334 b = "1\n2\n3\ninsert\n4\n"
1336 b = "1\n2\n3\ninsert\n4\n"
1335 fa = writetemp(a)
1337 fa = writetemp(a)
1336 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
1338 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
1337 os.path.basename(fa))
1339 os.path.basename(fa))
1338 fd = writetemp(d)
1340 fd = writetemp(d)
1339
1341
1340 files = {}
1342 files = {}
1341 try:
1343 try:
1342 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
1344 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
1343 except util.Abort, e:
1345 except util.Abort, e:
1344 ui.write(_(" patch call failed:\n"))
1346 ui.write(_(" patch call failed:\n"))
1345 ui.write(" " + str(e) + "\n")
1347 ui.write(" " + str(e) + "\n")
1346 patchproblems += 1
1348 patchproblems += 1
1347 else:
1349 else:
1348 if list(files) != [os.path.basename(fa)]:
1350 if list(files) != [os.path.basename(fa)]:
1349 ui.write(_(" unexpected patch output!\n"))
1351 ui.write(_(" unexpected patch output!\n"))
1350 patchproblems += 1
1352 patchproblems += 1
1351 a = open(fa).read()
1353 a = open(fa).read()
1352 if a != b:
1354 if a != b:
1353 ui.write(_(" patch test failed!\n"))
1355 ui.write(_(" patch test failed!\n"))
1354 patchproblems += 1
1356 patchproblems += 1
1355
1357
1356 if patchproblems:
1358 if patchproblems:
1357 if ui.config('ui', 'patch'):
1359 if ui.config('ui', 'patch'):
1358 ui.write(_(" (Current patch tool may be incompatible with patch,"
1360 ui.write(_(" (Current patch tool may be incompatible with patch,"
1359 " or misconfigured. Please check your configuration"
1361 " or misconfigured. Please check your configuration"
1360 " file)\n"))
1362 " file)\n"))
1361 else:
1363 else:
1362 ui.write(_(" Internal patcher failure, please report this error"
1364 ui.write(_(" Internal patcher failure, please report this error"
1363 " to http://mercurial.selenic.com/bts/\n"))
1365 " to http://mercurial.selenic.com/bts/\n"))
1364 problems += patchproblems
1366 problems += patchproblems
1365
1367
1366 os.unlink(fa)
1368 os.unlink(fa)
1367 os.unlink(fd)
1369 os.unlink(fd)
1368
1370
1369 # editor
1371 # editor
1370 ui.status(_("Checking commit editor...\n"))
1372 ui.status(_("Checking commit editor...\n"))
1371 editor = ui.geteditor()
1373 editor = ui.geteditor()
1372 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1374 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1373 if not cmdpath:
1375 if not cmdpath:
1374 if editor == 'vi':
1376 if editor == 'vi':
1375 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1377 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1376 ui.write(_(" (specify a commit editor in your configuration"
1378 ui.write(_(" (specify a commit editor in your configuration"
1377 " file)\n"))
1379 " file)\n"))
1378 else:
1380 else:
1379 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1381 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1380 ui.write(_(" (specify a commit editor in your configuration"
1382 ui.write(_(" (specify a commit editor in your configuration"
1381 " file)\n"))
1383 " file)\n"))
1382 problems += 1
1384 problems += 1
1383
1385
1384 # check username
1386 # check username
1385 ui.status(_("Checking username...\n"))
1387 ui.status(_("Checking username...\n"))
1386 try:
1388 try:
1387 ui.username()
1389 ui.username()
1388 except util.Abort, e:
1390 except util.Abort, e:
1389 ui.write(" %s\n" % e)
1391 ui.write(" %s\n" % e)
1390 ui.write(_(" (specify a username in your configuration file)\n"))
1392 ui.write(_(" (specify a username in your configuration file)\n"))
1391 problems += 1
1393 problems += 1
1392
1394
1393 if not problems:
1395 if not problems:
1394 ui.status(_("No problems detected\n"))
1396 ui.status(_("No problems detected\n"))
1395 else:
1397 else:
1396 ui.write(_("%s problems detected,"
1398 ui.write(_("%s problems detected,"
1397 " please check your install!\n") % problems)
1399 " please check your install!\n") % problems)
1398
1400
1399 return problems
1401 return problems
1400
1402
1401 def debugrename(ui, repo, file1, *pats, **opts):
1403 def debugrename(ui, repo, file1, *pats, **opts):
1402 """dump rename information"""
1404 """dump rename information"""
1403
1405
1404 ctx = repo[opts.get('rev')]
1406 ctx = repo[opts.get('rev')]
1405 m = cmdutil.match(repo, (file1,) + pats, opts)
1407 m = cmdutil.match(repo, (file1,) + pats, opts)
1406 for abs in ctx.walk(m):
1408 for abs in ctx.walk(m):
1407 fctx = ctx[abs]
1409 fctx = ctx[abs]
1408 o = fctx.filelog().renamed(fctx.filenode())
1410 o = fctx.filelog().renamed(fctx.filenode())
1409 rel = m.rel(abs)
1411 rel = m.rel(abs)
1410 if o:
1412 if o:
1411 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1413 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1412 else:
1414 else:
1413 ui.write(_("%s not renamed\n") % rel)
1415 ui.write(_("%s not renamed\n") % rel)
1414
1416
1415 def debugwalk(ui, repo, *pats, **opts):
1417 def debugwalk(ui, repo, *pats, **opts):
1416 """show how files match on given patterns"""
1418 """show how files match on given patterns"""
1417 m = cmdutil.match(repo, pats, opts)
1419 m = cmdutil.match(repo, pats, opts)
1418 items = list(repo.walk(m))
1420 items = list(repo.walk(m))
1419 if not items:
1421 if not items:
1420 return
1422 return
1421 fmt = 'f %%-%ds %%-%ds %%s' % (
1423 fmt = 'f %%-%ds %%-%ds %%s' % (
1422 max([len(abs) for abs in items]),
1424 max([len(abs) for abs in items]),
1423 max([len(m.rel(abs)) for abs in items]))
1425 max([len(m.rel(abs)) for abs in items]))
1424 for abs in items:
1426 for abs in items:
1425 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1427 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1426 ui.write("%s\n" % line.rstrip())
1428 ui.write("%s\n" % line.rstrip())
1427
1429
1428 def diff(ui, repo, *pats, **opts):
1430 def diff(ui, repo, *pats, **opts):
1429 """diff repository (or selected files)
1431 """diff repository (or selected files)
1430
1432
1431 Show differences between revisions for the specified files.
1433 Show differences between revisions for the specified files.
1432
1434
1433 Differences between files are shown using the unified diff format.
1435 Differences between files are shown using the unified diff format.
1434
1436
1435 .. note::
1437 .. note::
1436 diff may generate unexpected results for merges, as it will
1438 diff may generate unexpected results for merges, as it will
1437 default to comparing against the working directory's first
1439 default to comparing against the working directory's first
1438 parent changeset if no revisions are specified.
1440 parent changeset if no revisions are specified.
1439
1441
1440 When two revision arguments are given, then changes are shown
1442 When two revision arguments are given, then changes are shown
1441 between those revisions. If only one revision is specified then
1443 between those revisions. If only one revision is specified then
1442 that revision is compared to the working directory, and, when no
1444 that revision is compared to the working directory, and, when no
1443 revisions are specified, the working directory files are compared
1445 revisions are specified, the working directory files are compared
1444 to its parent.
1446 to its parent.
1445
1447
1446 Alternatively you can specify -c/--change with a revision to see
1448 Alternatively you can specify -c/--change with a revision to see
1447 the changes in that changeset relative to its first parent.
1449 the changes in that changeset relative to its first parent.
1448
1450
1449 Without the -a/--text option, diff will avoid generating diffs of
1451 Without the -a/--text option, diff will avoid generating diffs of
1450 files it detects as binary. With -a, diff will generate a diff
1452 files it detects as binary. With -a, diff will generate a diff
1451 anyway, probably with undesirable results.
1453 anyway, probably with undesirable results.
1452
1454
1453 Use the -g/--git option to generate diffs in the git extended diff
1455 Use the -g/--git option to generate diffs in the git extended diff
1454 format. For more information, read :hg:`help diffs`.
1456 format. For more information, read :hg:`help diffs`.
1455
1457
1456 Returns 0 on success.
1458 Returns 0 on success.
1457 """
1459 """
1458
1460
1459 revs = opts.get('rev')
1461 revs = opts.get('rev')
1460 change = opts.get('change')
1462 change = opts.get('change')
1461 stat = opts.get('stat')
1463 stat = opts.get('stat')
1462 reverse = opts.get('reverse')
1464 reverse = opts.get('reverse')
1463
1465
1464 if revs and change:
1466 if revs and change:
1465 msg = _('cannot specify --rev and --change at the same time')
1467 msg = _('cannot specify --rev and --change at the same time')
1466 raise util.Abort(msg)
1468 raise util.Abort(msg)
1467 elif change:
1469 elif change:
1468 node2 = repo.lookup(change)
1470 node2 = repo.lookup(change)
1469 node1 = repo[node2].parents()[0].node()
1471 node1 = repo[node2].parents()[0].node()
1470 else:
1472 else:
1471 node1, node2 = cmdutil.revpair(repo, revs)
1473 node1, node2 = cmdutil.revpair(repo, revs)
1472
1474
1473 if reverse:
1475 if reverse:
1474 node1, node2 = node2, node1
1476 node1, node2 = node2, node1
1475
1477
1476 diffopts = patch.diffopts(ui, opts)
1478 diffopts = patch.diffopts(ui, opts)
1477 m = cmdutil.match(repo, pats, opts)
1479 m = cmdutil.match(repo, pats, opts)
1478 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1480 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1479 listsubrepos=opts.get('subrepos'))
1481 listsubrepos=opts.get('subrepos'))
1480
1482
1481 def export(ui, repo, *changesets, **opts):
1483 def export(ui, repo, *changesets, **opts):
1482 """dump the header and diffs for one or more changesets
1484 """dump the header and diffs for one or more changesets
1483
1485
1484 Print the changeset header and diffs for one or more revisions.
1486 Print the changeset header and diffs for one or more revisions.
1485
1487
1486 The information shown in the changeset header is: author, date,
1488 The information shown in the changeset header is: author, date,
1487 branch name (if non-default), changeset hash, parent(s) and commit
1489 branch name (if non-default), changeset hash, parent(s) and commit
1488 comment.
1490 comment.
1489
1491
1490 .. note::
1492 .. note::
1491 export may generate unexpected diff output for merge
1493 export may generate unexpected diff output for merge
1492 changesets, as it will compare the merge changeset against its
1494 changesets, as it will compare the merge changeset against its
1493 first parent only.
1495 first parent only.
1494
1496
1495 Output may be to a file, in which case the name of the file is
1497 Output may be to a file, in which case the name of the file is
1496 given using a format string. The formatting rules are as follows:
1498 given using a format string. The formatting rules are as follows:
1497
1499
1498 :``%%``: literal "%" character
1500 :``%%``: literal "%" character
1499 :``%H``: changeset hash (40 hexadecimal digits)
1501 :``%H``: changeset hash (40 hexadecimal digits)
1500 :``%N``: number of patches being generated
1502 :``%N``: number of patches being generated
1501 :``%R``: changeset revision number
1503 :``%R``: changeset revision number
1502 :``%b``: basename of the exporting repository
1504 :``%b``: basename of the exporting repository
1503 :``%h``: short-form changeset hash (12 hexadecimal digits)
1505 :``%h``: short-form changeset hash (12 hexadecimal digits)
1504 :``%n``: zero-padded sequence number, starting at 1
1506 :``%n``: zero-padded sequence number, starting at 1
1505 :``%r``: zero-padded changeset revision number
1507 :``%r``: zero-padded changeset revision number
1506
1508
1507 Without the -a/--text option, export will avoid generating diffs
1509 Without the -a/--text option, export will avoid generating diffs
1508 of files it detects as binary. With -a, export will generate a
1510 of files it detects as binary. With -a, export will generate a
1509 diff anyway, probably with undesirable results.
1511 diff anyway, probably with undesirable results.
1510
1512
1511 Use the -g/--git option to generate diffs in the git extended diff
1513 Use the -g/--git option to generate diffs in the git extended diff
1512 format. See :hg:`help diffs` for more information.
1514 format. See :hg:`help diffs` for more information.
1513
1515
1514 With the --switch-parent option, the diff will be against the
1516 With the --switch-parent option, the diff will be against the
1515 second parent. It can be useful to review a merge.
1517 second parent. It can be useful to review a merge.
1516
1518
1517 Returns 0 on success.
1519 Returns 0 on success.
1518 """
1520 """
1519 changesets += tuple(opts.get('rev', []))
1521 changesets += tuple(opts.get('rev', []))
1520 if not changesets:
1522 if not changesets:
1521 raise util.Abort(_("export requires at least one changeset"))
1523 raise util.Abort(_("export requires at least one changeset"))
1522 revs = cmdutil.revrange(repo, changesets)
1524 revs = cmdutil.revrange(repo, changesets)
1523 if len(revs) > 1:
1525 if len(revs) > 1:
1524 ui.note(_('exporting patches:\n'))
1526 ui.note(_('exporting patches:\n'))
1525 else:
1527 else:
1526 ui.note(_('exporting patch:\n'))
1528 ui.note(_('exporting patch:\n'))
1527 cmdutil.export(repo, revs, template=opts.get('output'),
1529 cmdutil.export(repo, revs, template=opts.get('output'),
1528 switch_parent=opts.get('switch_parent'),
1530 switch_parent=opts.get('switch_parent'),
1529 opts=patch.diffopts(ui, opts))
1531 opts=patch.diffopts(ui, opts))
1530
1532
1531 def forget(ui, repo, *pats, **opts):
1533 def forget(ui, repo, *pats, **opts):
1532 """forget the specified files on the next commit
1534 """forget the specified files on the next commit
1533
1535
1534 Mark the specified files so they will no longer be tracked
1536 Mark the specified files so they will no longer be tracked
1535 after the next commit.
1537 after the next commit.
1536
1538
1537 This only removes files from the current branch, not from the
1539 This only removes files from the current branch, not from the
1538 entire project history, and it does not delete them from the
1540 entire project history, and it does not delete them from the
1539 working directory.
1541 working directory.
1540
1542
1541 To undo a forget before the next commit, see :hg:`add`.
1543 To undo a forget before the next commit, see :hg:`add`.
1542
1544
1543 Returns 0 on success.
1545 Returns 0 on success.
1544 """
1546 """
1545
1547
1546 if not pats:
1548 if not pats:
1547 raise util.Abort(_('no files specified'))
1549 raise util.Abort(_('no files specified'))
1548
1550
1549 m = cmdutil.match(repo, pats, opts)
1551 m = cmdutil.match(repo, pats, opts)
1550 s = repo.status(match=m, clean=True)
1552 s = repo.status(match=m, clean=True)
1551 forget = sorted(s[0] + s[1] + s[3] + s[6])
1553 forget = sorted(s[0] + s[1] + s[3] + s[6])
1552 errs = 0
1554 errs = 0
1553
1555
1554 for f in m.files():
1556 for f in m.files():
1555 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1557 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1556 ui.warn(_('not removing %s: file is already untracked\n')
1558 ui.warn(_('not removing %s: file is already untracked\n')
1557 % m.rel(f))
1559 % m.rel(f))
1558 errs = 1
1560 errs = 1
1559
1561
1560 for f in forget:
1562 for f in forget:
1561 if ui.verbose or not m.exact(f):
1563 if ui.verbose or not m.exact(f):
1562 ui.status(_('removing %s\n') % m.rel(f))
1564 ui.status(_('removing %s\n') % m.rel(f))
1563
1565
1564 repo[None].remove(forget, unlink=False)
1566 repo[None].remove(forget, unlink=False)
1565 return errs
1567 return errs
1566
1568
1567 def grep(ui, repo, pattern, *pats, **opts):
1569 def grep(ui, repo, pattern, *pats, **opts):
1568 """search for a pattern in specified files and revisions
1570 """search for a pattern in specified files and revisions
1569
1571
1570 Search revisions of files for a regular expression.
1572 Search revisions of files for a regular expression.
1571
1573
1572 This command behaves differently than Unix grep. It only accepts
1574 This command behaves differently than Unix grep. It only accepts
1573 Python/Perl regexps. It searches repository history, not the
1575 Python/Perl regexps. It searches repository history, not the
1574 working directory. It always prints the revision number in which a
1576 working directory. It always prints the revision number in which a
1575 match appears.
1577 match appears.
1576
1578
1577 By default, grep only prints output for the first revision of a
1579 By default, grep only prints output for the first revision of a
1578 file in which it finds a match. To get it to print every revision
1580 file in which it finds a match. To get it to print every revision
1579 that contains a change in match status ("-" for a match that
1581 that contains a change in match status ("-" for a match that
1580 becomes a non-match, or "+" for a non-match that becomes a match),
1582 becomes a non-match, or "+" for a non-match that becomes a match),
1581 use the --all flag.
1583 use the --all flag.
1582
1584
1583 Returns 0 if a match is found, 1 otherwise.
1585 Returns 0 if a match is found, 1 otherwise.
1584 """
1586 """
1585 reflags = 0
1587 reflags = 0
1586 if opts.get('ignore_case'):
1588 if opts.get('ignore_case'):
1587 reflags |= re.I
1589 reflags |= re.I
1588 try:
1590 try:
1589 regexp = re.compile(pattern, reflags)
1591 regexp = re.compile(pattern, reflags)
1590 except re.error, inst:
1592 except re.error, inst:
1591 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1593 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1592 return 1
1594 return 1
1593 sep, eol = ':', '\n'
1595 sep, eol = ':', '\n'
1594 if opts.get('print0'):
1596 if opts.get('print0'):
1595 sep = eol = '\0'
1597 sep = eol = '\0'
1596
1598
1597 getfile = util.lrucachefunc(repo.file)
1599 getfile = util.lrucachefunc(repo.file)
1598
1600
1599 def matchlines(body):
1601 def matchlines(body):
1600 begin = 0
1602 begin = 0
1601 linenum = 0
1603 linenum = 0
1602 while True:
1604 while True:
1603 match = regexp.search(body, begin)
1605 match = regexp.search(body, begin)
1604 if not match:
1606 if not match:
1605 break
1607 break
1606 mstart, mend = match.span()
1608 mstart, mend = match.span()
1607 linenum += body.count('\n', begin, mstart) + 1
1609 linenum += body.count('\n', begin, mstart) + 1
1608 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1610 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1609 begin = body.find('\n', mend) + 1 or len(body)
1611 begin = body.find('\n', mend) + 1 or len(body)
1610 lend = begin - 1
1612 lend = begin - 1
1611 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1613 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1612
1614
1613 class linestate(object):
1615 class linestate(object):
1614 def __init__(self, line, linenum, colstart, colend):
1616 def __init__(self, line, linenum, colstart, colend):
1615 self.line = line
1617 self.line = line
1616 self.linenum = linenum
1618 self.linenum = linenum
1617 self.colstart = colstart
1619 self.colstart = colstart
1618 self.colend = colend
1620 self.colend = colend
1619
1621
1620 def __hash__(self):
1622 def __hash__(self):
1621 return hash((self.linenum, self.line))
1623 return hash((self.linenum, self.line))
1622
1624
1623 def __eq__(self, other):
1625 def __eq__(self, other):
1624 return self.line == other.line
1626 return self.line == other.line
1625
1627
1626 matches = {}
1628 matches = {}
1627 copies = {}
1629 copies = {}
1628 def grepbody(fn, rev, body):
1630 def grepbody(fn, rev, body):
1629 matches[rev].setdefault(fn, [])
1631 matches[rev].setdefault(fn, [])
1630 m = matches[rev][fn]
1632 m = matches[rev][fn]
1631 for lnum, cstart, cend, line in matchlines(body):
1633 for lnum, cstart, cend, line in matchlines(body):
1632 s = linestate(line, lnum, cstart, cend)
1634 s = linestate(line, lnum, cstart, cend)
1633 m.append(s)
1635 m.append(s)
1634
1636
1635 def difflinestates(a, b):
1637 def difflinestates(a, b):
1636 sm = difflib.SequenceMatcher(None, a, b)
1638 sm = difflib.SequenceMatcher(None, a, b)
1637 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1639 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1638 if tag == 'insert':
1640 if tag == 'insert':
1639 for i in xrange(blo, bhi):
1641 for i in xrange(blo, bhi):
1640 yield ('+', b[i])
1642 yield ('+', b[i])
1641 elif tag == 'delete':
1643 elif tag == 'delete':
1642 for i in xrange(alo, ahi):
1644 for i in xrange(alo, ahi):
1643 yield ('-', a[i])
1645 yield ('-', a[i])
1644 elif tag == 'replace':
1646 elif tag == 'replace':
1645 for i in xrange(alo, ahi):
1647 for i in xrange(alo, ahi):
1646 yield ('-', a[i])
1648 yield ('-', a[i])
1647 for i in xrange(blo, bhi):
1649 for i in xrange(blo, bhi):
1648 yield ('+', b[i])
1650 yield ('+', b[i])
1649
1651
1650 def display(fn, ctx, pstates, states):
1652 def display(fn, ctx, pstates, states):
1651 rev = ctx.rev()
1653 rev = ctx.rev()
1652 datefunc = ui.quiet and util.shortdate or util.datestr
1654 datefunc = ui.quiet and util.shortdate or util.datestr
1653 found = False
1655 found = False
1654 filerevmatches = {}
1656 filerevmatches = {}
1655 if opts.get('all'):
1657 if opts.get('all'):
1656 iter = difflinestates(pstates, states)
1658 iter = difflinestates(pstates, states)
1657 else:
1659 else:
1658 iter = [('', l) for l in states]
1660 iter = [('', l) for l in states]
1659 for change, l in iter:
1661 for change, l in iter:
1660 cols = [fn, str(rev)]
1662 cols = [fn, str(rev)]
1661 before, match, after = None, None, None
1663 before, match, after = None, None, None
1662 if opts.get('line_number'):
1664 if opts.get('line_number'):
1663 cols.append(str(l.linenum))
1665 cols.append(str(l.linenum))
1664 if opts.get('all'):
1666 if opts.get('all'):
1665 cols.append(change)
1667 cols.append(change)
1666 if opts.get('user'):
1668 if opts.get('user'):
1667 cols.append(ui.shortuser(ctx.user()))
1669 cols.append(ui.shortuser(ctx.user()))
1668 if opts.get('date'):
1670 if opts.get('date'):
1669 cols.append(datefunc(ctx.date()))
1671 cols.append(datefunc(ctx.date()))
1670 if opts.get('files_with_matches'):
1672 if opts.get('files_with_matches'):
1671 c = (fn, rev)
1673 c = (fn, rev)
1672 if c in filerevmatches:
1674 if c in filerevmatches:
1673 continue
1675 continue
1674 filerevmatches[c] = 1
1676 filerevmatches[c] = 1
1675 else:
1677 else:
1676 before = l.line[:l.colstart]
1678 before = l.line[:l.colstart]
1677 match = l.line[l.colstart:l.colend]
1679 match = l.line[l.colstart:l.colend]
1678 after = l.line[l.colend:]
1680 after = l.line[l.colend:]
1679 ui.write(sep.join(cols))
1681 ui.write(sep.join(cols))
1680 if before is not None:
1682 if before is not None:
1681 ui.write(sep + before)
1683 ui.write(sep + before)
1682 ui.write(match, label='grep.match')
1684 ui.write(match, label='grep.match')
1683 ui.write(after)
1685 ui.write(after)
1684 ui.write(eol)
1686 ui.write(eol)
1685 found = True
1687 found = True
1686 return found
1688 return found
1687
1689
1688 skip = {}
1690 skip = {}
1689 revfiles = {}
1691 revfiles = {}
1690 matchfn = cmdutil.match(repo, pats, opts)
1692 matchfn = cmdutil.match(repo, pats, opts)
1691 found = False
1693 found = False
1692 follow = opts.get('follow')
1694 follow = opts.get('follow')
1693
1695
1694 def prep(ctx, fns):
1696 def prep(ctx, fns):
1695 rev = ctx.rev()
1697 rev = ctx.rev()
1696 pctx = ctx.parents()[0]
1698 pctx = ctx.parents()[0]
1697 parent = pctx.rev()
1699 parent = pctx.rev()
1698 matches.setdefault(rev, {})
1700 matches.setdefault(rev, {})
1699 matches.setdefault(parent, {})
1701 matches.setdefault(parent, {})
1700 files = revfiles.setdefault(rev, [])
1702 files = revfiles.setdefault(rev, [])
1701 for fn in fns:
1703 for fn in fns:
1702 flog = getfile(fn)
1704 flog = getfile(fn)
1703 try:
1705 try:
1704 fnode = ctx.filenode(fn)
1706 fnode = ctx.filenode(fn)
1705 except error.LookupError:
1707 except error.LookupError:
1706 continue
1708 continue
1707
1709
1708 copied = flog.renamed(fnode)
1710 copied = flog.renamed(fnode)
1709 copy = follow and copied and copied[0]
1711 copy = follow and copied and copied[0]
1710 if copy:
1712 if copy:
1711 copies.setdefault(rev, {})[fn] = copy
1713 copies.setdefault(rev, {})[fn] = copy
1712 if fn in skip:
1714 if fn in skip:
1713 if copy:
1715 if copy:
1714 skip[copy] = True
1716 skip[copy] = True
1715 continue
1717 continue
1716 files.append(fn)
1718 files.append(fn)
1717
1719
1718 if fn not in matches[rev]:
1720 if fn not in matches[rev]:
1719 grepbody(fn, rev, flog.read(fnode))
1721 grepbody(fn, rev, flog.read(fnode))
1720
1722
1721 pfn = copy or fn
1723 pfn = copy or fn
1722 if pfn not in matches[parent]:
1724 if pfn not in matches[parent]:
1723 try:
1725 try:
1724 fnode = pctx.filenode(pfn)
1726 fnode = pctx.filenode(pfn)
1725 grepbody(pfn, parent, flog.read(fnode))
1727 grepbody(pfn, parent, flog.read(fnode))
1726 except error.LookupError:
1728 except error.LookupError:
1727 pass
1729 pass
1728
1730
1729 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1731 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1730 rev = ctx.rev()
1732 rev = ctx.rev()
1731 parent = ctx.parents()[0].rev()
1733 parent = ctx.parents()[0].rev()
1732 for fn in sorted(revfiles.get(rev, [])):
1734 for fn in sorted(revfiles.get(rev, [])):
1733 states = matches[rev][fn]
1735 states = matches[rev][fn]
1734 copy = copies.get(rev, {}).get(fn)
1736 copy = copies.get(rev, {}).get(fn)
1735 if fn in skip:
1737 if fn in skip:
1736 if copy:
1738 if copy:
1737 skip[copy] = True
1739 skip[copy] = True
1738 continue
1740 continue
1739 pstates = matches.get(parent, {}).get(copy or fn, [])
1741 pstates = matches.get(parent, {}).get(copy or fn, [])
1740 if pstates or states:
1742 if pstates or states:
1741 r = display(fn, ctx, pstates, states)
1743 r = display(fn, ctx, pstates, states)
1742 found = found or r
1744 found = found or r
1743 if r and not opts.get('all'):
1745 if r and not opts.get('all'):
1744 skip[fn] = True
1746 skip[fn] = True
1745 if copy:
1747 if copy:
1746 skip[copy] = True
1748 skip[copy] = True
1747 del matches[rev]
1749 del matches[rev]
1748 del revfiles[rev]
1750 del revfiles[rev]
1749
1751
1750 return not found
1752 return not found
1751
1753
1752 def heads(ui, repo, *branchrevs, **opts):
1754 def heads(ui, repo, *branchrevs, **opts):
1753 """show current repository heads or show branch heads
1755 """show current repository heads or show branch heads
1754
1756
1755 With no arguments, show all repository branch heads.
1757 With no arguments, show all repository branch heads.
1756
1758
1757 Repository "heads" are changesets with no child changesets. They are
1759 Repository "heads" are changesets with no child changesets. They are
1758 where development generally takes place and are the usual targets
1760 where development generally takes place and are the usual targets
1759 for update and merge operations. Branch heads are changesets that have
1761 for update and merge operations. Branch heads are changesets that have
1760 no child changeset on the same branch.
1762 no child changeset on the same branch.
1761
1763
1762 If one or more REVs are given, only branch heads on the branches
1764 If one or more REVs are given, only branch heads on the branches
1763 associated with the specified changesets are shown.
1765 associated with the specified changesets are shown.
1764
1766
1765 If -c/--closed is specified, also show branch heads marked closed
1767 If -c/--closed is specified, also show branch heads marked closed
1766 (see :hg:`commit --close-branch`).
1768 (see :hg:`commit --close-branch`).
1767
1769
1768 If STARTREV is specified, only those heads that are descendants of
1770 If STARTREV is specified, only those heads that are descendants of
1769 STARTREV will be displayed.
1771 STARTREV will be displayed.
1770
1772
1771 If -t/--topo is specified, named branch mechanics will be ignored and only
1773 If -t/--topo is specified, named branch mechanics will be ignored and only
1772 changesets without children will be shown.
1774 changesets without children will be shown.
1773
1775
1774 Returns 0 if matching heads are found, 1 if not.
1776 Returns 0 if matching heads are found, 1 if not.
1775 """
1777 """
1776
1778
1777 if opts.get('rev'):
1779 if opts.get('rev'):
1778 start = repo.lookup(opts['rev'])
1780 start = repo.lookup(opts['rev'])
1779 else:
1781 else:
1780 start = None
1782 start = None
1781
1783
1782 if opts.get('topo'):
1784 if opts.get('topo'):
1783 heads = [repo[h] for h in repo.heads(start)]
1785 heads = [repo[h] for h in repo.heads(start)]
1784 else:
1786 else:
1785 heads = []
1787 heads = []
1786 for b, ls in repo.branchmap().iteritems():
1788 for b, ls in repo.branchmap().iteritems():
1787 if start is None:
1789 if start is None:
1788 heads += [repo[h] for h in ls]
1790 heads += [repo[h] for h in ls]
1789 continue
1791 continue
1790 startrev = repo.changelog.rev(start)
1792 startrev = repo.changelog.rev(start)
1791 descendants = set(repo.changelog.descendants(startrev))
1793 descendants = set(repo.changelog.descendants(startrev))
1792 descendants.add(startrev)
1794 descendants.add(startrev)
1793 rev = repo.changelog.rev
1795 rev = repo.changelog.rev
1794 heads += [repo[h] for h in ls if rev(h) in descendants]
1796 heads += [repo[h] for h in ls if rev(h) in descendants]
1795
1797
1796 if branchrevs:
1798 if branchrevs:
1797 decode, encode = encoding.fromlocal, encoding.tolocal
1799 decode, encode = encoding.fromlocal, encoding.tolocal
1798 branches = set(repo[decode(br)].branch() for br in branchrevs)
1800 branches = set(repo[decode(br)].branch() for br in branchrevs)
1799 heads = [h for h in heads if h.branch() in branches]
1801 heads = [h for h in heads if h.branch() in branches]
1800
1802
1801 if not opts.get('closed'):
1803 if not opts.get('closed'):
1802 heads = [h for h in heads if not h.extra().get('close')]
1804 heads = [h for h in heads if not h.extra().get('close')]
1803
1805
1804 if opts.get('active') and branchrevs:
1806 if opts.get('active') and branchrevs:
1805 dagheads = repo.heads(start)
1807 dagheads = repo.heads(start)
1806 heads = [h for h in heads if h.node() in dagheads]
1808 heads = [h for h in heads if h.node() in dagheads]
1807
1809
1808 if branchrevs:
1810 if branchrevs:
1809 haveheads = set(h.branch() for h in heads)
1811 haveheads = set(h.branch() for h in heads)
1810 if branches - haveheads:
1812 if branches - haveheads:
1811 headless = ', '.join(encode(b) for b in branches - haveheads)
1813 headless = ', '.join(encode(b) for b in branches - haveheads)
1812 msg = _('no open branch heads found on branches %s')
1814 msg = _('no open branch heads found on branches %s')
1813 if opts.get('rev'):
1815 if opts.get('rev'):
1814 msg += _(' (started at %s)' % opts['rev'])
1816 msg += _(' (started at %s)' % opts['rev'])
1815 ui.warn((msg + '\n') % headless)
1817 ui.warn((msg + '\n') % headless)
1816
1818
1817 if not heads:
1819 if not heads:
1818 return 1
1820 return 1
1819
1821
1820 heads = sorted(heads, key=lambda x: -x.rev())
1822 heads = sorted(heads, key=lambda x: -x.rev())
1821 displayer = cmdutil.show_changeset(ui, repo, opts)
1823 displayer = cmdutil.show_changeset(ui, repo, opts)
1822 for ctx in heads:
1824 for ctx in heads:
1823 displayer.show(ctx)
1825 displayer.show(ctx)
1824 displayer.close()
1826 displayer.close()
1825
1827
1826 def help_(ui, name=None, with_version=False, unknowncmd=False):
1828 def help_(ui, name=None, with_version=False, unknowncmd=False):
1827 """show help for a given topic or a help overview
1829 """show help for a given topic or a help overview
1828
1830
1829 With no arguments, print a list of commands with short help messages.
1831 With no arguments, print a list of commands with short help messages.
1830
1832
1831 Given a topic, extension, or command name, print help for that
1833 Given a topic, extension, or command name, print help for that
1832 topic.
1834 topic.
1833
1835
1834 Returns 0 if successful.
1836 Returns 0 if successful.
1835 """
1837 """
1836 option_lists = []
1838 option_lists = []
1837 textwidth = ui.termwidth() - 2
1839 textwidth = ui.termwidth() - 2
1838
1840
1839 def addglobalopts(aliases):
1841 def addglobalopts(aliases):
1840 if ui.verbose:
1842 if ui.verbose:
1841 option_lists.append((_("global options:"), globalopts))
1843 option_lists.append((_("global options:"), globalopts))
1842 if name == 'shortlist':
1844 if name == 'shortlist':
1843 option_lists.append((_('use "hg help" for the full list '
1845 option_lists.append((_('use "hg help" for the full list '
1844 'of commands'), ()))
1846 'of commands'), ()))
1845 else:
1847 else:
1846 if name == 'shortlist':
1848 if name == 'shortlist':
1847 msg = _('use "hg help" for the full list of commands '
1849 msg = _('use "hg help" for the full list of commands '
1848 'or "hg -v" for details')
1850 'or "hg -v" for details')
1849 elif aliases:
1851 elif aliases:
1850 msg = _('use "hg -v help%s" to show aliases and '
1852 msg = _('use "hg -v help%s" to show aliases and '
1851 'global options') % (name and " " + name or "")
1853 'global options') % (name and " " + name or "")
1852 else:
1854 else:
1853 msg = _('use "hg -v help %s" to show global options') % name
1855 msg = _('use "hg -v help %s" to show global options') % name
1854 option_lists.append((msg, ()))
1856 option_lists.append((msg, ()))
1855
1857
1856 def helpcmd(name):
1858 def helpcmd(name):
1857 if with_version:
1859 if with_version:
1858 version_(ui)
1860 version_(ui)
1859 ui.write('\n')
1861 ui.write('\n')
1860
1862
1861 try:
1863 try:
1862 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1864 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1863 except error.AmbiguousCommand, inst:
1865 except error.AmbiguousCommand, inst:
1864 # py3k fix: except vars can't be used outside the scope of the
1866 # py3k fix: except vars can't be used outside the scope of the
1865 # except block, nor can be used inside a lambda. python issue4617
1867 # except block, nor can be used inside a lambda. python issue4617
1866 prefix = inst.args[0]
1868 prefix = inst.args[0]
1867 select = lambda c: c.lstrip('^').startswith(prefix)
1869 select = lambda c: c.lstrip('^').startswith(prefix)
1868 helplist(_('list of commands:\n\n'), select)
1870 helplist(_('list of commands:\n\n'), select)
1869 return
1871 return
1870
1872
1871 # check if it's an invalid alias and display its error if it is
1873 # check if it's an invalid alias and display its error if it is
1872 if getattr(entry[0], 'badalias', False):
1874 if getattr(entry[0], 'badalias', False):
1873 if not unknowncmd:
1875 if not unknowncmd:
1874 entry[0](ui)
1876 entry[0](ui)
1875 return
1877 return
1876
1878
1877 # synopsis
1879 # synopsis
1878 if len(entry) > 2:
1880 if len(entry) > 2:
1879 if entry[2].startswith('hg'):
1881 if entry[2].startswith('hg'):
1880 ui.write("%s\n" % entry[2])
1882 ui.write("%s\n" % entry[2])
1881 else:
1883 else:
1882 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
1884 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
1883 else:
1885 else:
1884 ui.write('hg %s\n' % aliases[0])
1886 ui.write('hg %s\n' % aliases[0])
1885
1887
1886 # aliases
1888 # aliases
1887 if not ui.quiet and len(aliases) > 1:
1889 if not ui.quiet and len(aliases) > 1:
1888 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1890 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1889
1891
1890 # description
1892 # description
1891 doc = gettext(entry[0].__doc__)
1893 doc = gettext(entry[0].__doc__)
1892 if not doc:
1894 if not doc:
1893 doc = _("(no help text available)")
1895 doc = _("(no help text available)")
1894 if hasattr(entry[0], 'definition'): # aliased command
1896 if hasattr(entry[0], 'definition'): # aliased command
1895 if entry[0].definition.startswith('!'): # shell alias
1897 if entry[0].definition.startswith('!'): # shell alias
1896 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
1898 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
1897 else:
1899 else:
1898 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
1900 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
1899 if ui.quiet:
1901 if ui.quiet:
1900 doc = doc.splitlines()[0]
1902 doc = doc.splitlines()[0]
1901 keep = ui.verbose and ['verbose'] or []
1903 keep = ui.verbose and ['verbose'] or []
1902 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
1904 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
1903 ui.write("\n%s\n" % formatted)
1905 ui.write("\n%s\n" % formatted)
1904 if pruned:
1906 if pruned:
1905 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
1907 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
1906
1908
1907 if not ui.quiet:
1909 if not ui.quiet:
1908 # options
1910 # options
1909 if entry[1]:
1911 if entry[1]:
1910 option_lists.append((_("options:\n"), entry[1]))
1912 option_lists.append((_("options:\n"), entry[1]))
1911
1913
1912 addglobalopts(False)
1914 addglobalopts(False)
1913
1915
1914 def helplist(header, select=None):
1916 def helplist(header, select=None):
1915 h = {}
1917 h = {}
1916 cmds = {}
1918 cmds = {}
1917 for c, e in table.iteritems():
1919 for c, e in table.iteritems():
1918 f = c.split("|", 1)[0]
1920 f = c.split("|", 1)[0]
1919 if select and not select(f):
1921 if select and not select(f):
1920 continue
1922 continue
1921 if (not select and name != 'shortlist' and
1923 if (not select and name != 'shortlist' and
1922 e[0].__module__ != __name__):
1924 e[0].__module__ != __name__):
1923 continue
1925 continue
1924 if name == "shortlist" and not f.startswith("^"):
1926 if name == "shortlist" and not f.startswith("^"):
1925 continue
1927 continue
1926 f = f.lstrip("^")
1928 f = f.lstrip("^")
1927 if not ui.debugflag and f.startswith("debug"):
1929 if not ui.debugflag and f.startswith("debug"):
1928 continue
1930 continue
1929 doc = e[0].__doc__
1931 doc = e[0].__doc__
1930 if doc and 'DEPRECATED' in doc and not ui.verbose:
1932 if doc and 'DEPRECATED' in doc and not ui.verbose:
1931 continue
1933 continue
1932 doc = gettext(doc)
1934 doc = gettext(doc)
1933 if not doc:
1935 if not doc:
1934 doc = _("(no help text available)")
1936 doc = _("(no help text available)")
1935 h[f] = doc.splitlines()[0].rstrip()
1937 h[f] = doc.splitlines()[0].rstrip()
1936 cmds[f] = c.lstrip("^")
1938 cmds[f] = c.lstrip("^")
1937
1939
1938 if not h:
1940 if not h:
1939 ui.status(_('no commands defined\n'))
1941 ui.status(_('no commands defined\n'))
1940 return
1942 return
1941
1943
1942 ui.status(header)
1944 ui.status(header)
1943 fns = sorted(h)
1945 fns = sorted(h)
1944 m = max(map(len, fns))
1946 m = max(map(len, fns))
1945 for f in fns:
1947 for f in fns:
1946 if ui.verbose:
1948 if ui.verbose:
1947 commands = cmds[f].replace("|",", ")
1949 commands = cmds[f].replace("|",", ")
1948 ui.write(" %s:\n %s\n"%(commands, h[f]))
1950 ui.write(" %s:\n %s\n"%(commands, h[f]))
1949 else:
1951 else:
1950 ui.write('%s\n' % (util.wrap(h[f],
1952 ui.write('%s\n' % (util.wrap(h[f],
1951 initindent=' %-*s ' % (m, f),
1953 initindent=' %-*s ' % (m, f),
1952 hangindent=' ' * (m + 4))))
1954 hangindent=' ' * (m + 4))))
1953
1955
1954 if not ui.quiet:
1956 if not ui.quiet:
1955 addglobalopts(True)
1957 addglobalopts(True)
1956
1958
1957 def helptopic(name):
1959 def helptopic(name):
1958 for names, header, doc in help.helptable:
1960 for names, header, doc in help.helptable:
1959 if name in names:
1961 if name in names:
1960 break
1962 break
1961 else:
1963 else:
1962 raise error.UnknownCommand(name)
1964 raise error.UnknownCommand(name)
1963
1965
1964 # description
1966 # description
1965 if not doc:
1967 if not doc:
1966 doc = _("(no help text available)")
1968 doc = _("(no help text available)")
1967 if hasattr(doc, '__call__'):
1969 if hasattr(doc, '__call__'):
1968 doc = doc()
1970 doc = doc()
1969
1971
1970 ui.write("%s\n\n" % header)
1972 ui.write("%s\n\n" % header)
1971 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
1973 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
1972
1974
1973 def helpext(name):
1975 def helpext(name):
1974 try:
1976 try:
1975 mod = extensions.find(name)
1977 mod = extensions.find(name)
1976 doc = gettext(mod.__doc__) or _('no help text available')
1978 doc = gettext(mod.__doc__) or _('no help text available')
1977 except KeyError:
1979 except KeyError:
1978 mod = None
1980 mod = None
1979 doc = extensions.disabledext(name)
1981 doc = extensions.disabledext(name)
1980 if not doc:
1982 if not doc:
1981 raise error.UnknownCommand(name)
1983 raise error.UnknownCommand(name)
1982
1984
1983 if '\n' not in doc:
1985 if '\n' not in doc:
1984 head, tail = doc, ""
1986 head, tail = doc, ""
1985 else:
1987 else:
1986 head, tail = doc.split('\n', 1)
1988 head, tail = doc.split('\n', 1)
1987 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
1989 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
1988 if tail:
1990 if tail:
1989 ui.write(minirst.format(tail, textwidth))
1991 ui.write(minirst.format(tail, textwidth))
1990 ui.status('\n\n')
1992 ui.status('\n\n')
1991
1993
1992 if mod:
1994 if mod:
1993 try:
1995 try:
1994 ct = mod.cmdtable
1996 ct = mod.cmdtable
1995 except AttributeError:
1997 except AttributeError:
1996 ct = {}
1998 ct = {}
1997 modcmds = set([c.split('|', 1)[0] for c in ct])
1999 modcmds = set([c.split('|', 1)[0] for c in ct])
1998 helplist(_('list of commands:\n\n'), modcmds.__contains__)
2000 helplist(_('list of commands:\n\n'), modcmds.__contains__)
1999 else:
2001 else:
2000 ui.write(_('use "hg help extensions" for information on enabling '
2002 ui.write(_('use "hg help extensions" for information on enabling '
2001 'extensions\n'))
2003 'extensions\n'))
2002
2004
2003 def helpextcmd(name):
2005 def helpextcmd(name):
2004 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
2006 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
2005 doc = gettext(mod.__doc__).splitlines()[0]
2007 doc = gettext(mod.__doc__).splitlines()[0]
2006
2008
2007 msg = help.listexts(_("'%s' is provided by the following "
2009 msg = help.listexts(_("'%s' is provided by the following "
2008 "extension:") % cmd, {ext: doc}, len(ext),
2010 "extension:") % cmd, {ext: doc}, len(ext),
2009 indent=4)
2011 indent=4)
2010 ui.write(minirst.format(msg, textwidth))
2012 ui.write(minirst.format(msg, textwidth))
2011 ui.write('\n\n')
2013 ui.write('\n\n')
2012 ui.write(_('use "hg help extensions" for information on enabling '
2014 ui.write(_('use "hg help extensions" for information on enabling '
2013 'extensions\n'))
2015 'extensions\n'))
2014
2016
2015 if name and name != 'shortlist':
2017 if name and name != 'shortlist':
2016 i = None
2018 i = None
2017 if unknowncmd:
2019 if unknowncmd:
2018 queries = (helpextcmd,)
2020 queries = (helpextcmd,)
2019 else:
2021 else:
2020 queries = (helptopic, helpcmd, helpext, helpextcmd)
2022 queries = (helptopic, helpcmd, helpext, helpextcmd)
2021 for f in queries:
2023 for f in queries:
2022 try:
2024 try:
2023 f(name)
2025 f(name)
2024 i = None
2026 i = None
2025 break
2027 break
2026 except error.UnknownCommand, inst:
2028 except error.UnknownCommand, inst:
2027 i = inst
2029 i = inst
2028 if i:
2030 if i:
2029 raise i
2031 raise i
2030
2032
2031 else:
2033 else:
2032 # program name
2034 # program name
2033 if ui.verbose or with_version:
2035 if ui.verbose or with_version:
2034 version_(ui)
2036 version_(ui)
2035 else:
2037 else:
2036 ui.status(_("Mercurial Distributed SCM\n"))
2038 ui.status(_("Mercurial Distributed SCM\n"))
2037 ui.status('\n')
2039 ui.status('\n')
2038
2040
2039 # list of commands
2041 # list of commands
2040 if name == "shortlist":
2042 if name == "shortlist":
2041 header = _('basic commands:\n\n')
2043 header = _('basic commands:\n\n')
2042 else:
2044 else:
2043 header = _('list of commands:\n\n')
2045 header = _('list of commands:\n\n')
2044
2046
2045 helplist(header)
2047 helplist(header)
2046 if name != 'shortlist':
2048 if name != 'shortlist':
2047 exts, maxlength = extensions.enabled()
2049 exts, maxlength = extensions.enabled()
2048 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2050 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2049 if text:
2051 if text:
2050 ui.write("\n%s\n" % minirst.format(text, textwidth))
2052 ui.write("\n%s\n" % minirst.format(text, textwidth))
2051
2053
2052 # list all option lists
2054 # list all option lists
2053 opt_output = []
2055 opt_output = []
2054 multioccur = False
2056 multioccur = False
2055 for title, options in option_lists:
2057 for title, options in option_lists:
2056 opt_output.append(("\n%s" % title, None))
2058 opt_output.append(("\n%s" % title, None))
2057 for option in options:
2059 for option in options:
2058 if len(option) == 5:
2060 if len(option) == 5:
2059 shortopt, longopt, default, desc, optlabel = option
2061 shortopt, longopt, default, desc, optlabel = option
2060 else:
2062 else:
2061 shortopt, longopt, default, desc = option
2063 shortopt, longopt, default, desc = option
2062 optlabel = _("VALUE") # default label
2064 optlabel = _("VALUE") # default label
2063
2065
2064 if _("DEPRECATED") in desc and not ui.verbose:
2066 if _("DEPRECATED") in desc and not ui.verbose:
2065 continue
2067 continue
2066 if isinstance(default, list):
2068 if isinstance(default, list):
2067 numqualifier = " %s [+]" % optlabel
2069 numqualifier = " %s [+]" % optlabel
2068 multioccur = True
2070 multioccur = True
2069 elif (default is not None) and not isinstance(default, bool):
2071 elif (default is not None) and not isinstance(default, bool):
2070 numqualifier = " %s" % optlabel
2072 numqualifier = " %s" % optlabel
2071 else:
2073 else:
2072 numqualifier = ""
2074 numqualifier = ""
2073 opt_output.append(("%2s%s" %
2075 opt_output.append(("%2s%s" %
2074 (shortopt and "-%s" % shortopt,
2076 (shortopt and "-%s" % shortopt,
2075 longopt and " --%s%s" %
2077 longopt and " --%s%s" %
2076 (longopt, numqualifier)),
2078 (longopt, numqualifier)),
2077 "%s%s" % (desc,
2079 "%s%s" % (desc,
2078 default
2080 default
2079 and _(" (default: %s)") % default
2081 and _(" (default: %s)") % default
2080 or "")))
2082 or "")))
2081 if multioccur:
2083 if multioccur:
2082 msg = _("\n[+] marked option can be specified multiple times")
2084 msg = _("\n[+] marked option can be specified multiple times")
2083 if ui.verbose and name != 'shortlist':
2085 if ui.verbose and name != 'shortlist':
2084 opt_output.append((msg, None))
2086 opt_output.append((msg, None))
2085 else:
2087 else:
2086 opt_output.insert(-1, (msg, None))
2088 opt_output.insert(-1, (msg, None))
2087
2089
2088 if not name:
2090 if not name:
2089 ui.write(_("\nadditional help topics:\n\n"))
2091 ui.write(_("\nadditional help topics:\n\n"))
2090 topics = []
2092 topics = []
2091 for names, header, doc in help.helptable:
2093 for names, header, doc in help.helptable:
2092 topics.append((sorted(names, key=len, reverse=True)[0], header))
2094 topics.append((sorted(names, key=len, reverse=True)[0], header))
2093 topics_len = max([len(s[0]) for s in topics])
2095 topics_len = max([len(s[0]) for s in topics])
2094 for t, desc in topics:
2096 for t, desc in topics:
2095 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2097 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2096
2098
2097 if opt_output:
2099 if opt_output:
2098 colwidth = encoding.colwidth
2100 colwidth = encoding.colwidth
2099 # normalize: (opt or message, desc or None, width of opt)
2101 # normalize: (opt or message, desc or None, width of opt)
2100 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2102 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2101 for opt, desc in opt_output]
2103 for opt, desc in opt_output]
2102 hanging = max([e[2] for e in entries])
2104 hanging = max([e[2] for e in entries])
2103 for opt, desc, width in entries:
2105 for opt, desc, width in entries:
2104 if desc:
2106 if desc:
2105 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2107 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2106 hangindent = ' ' * (hanging + 3)
2108 hangindent = ' ' * (hanging + 3)
2107 ui.write('%s\n' % (util.wrap(desc,
2109 ui.write('%s\n' % (util.wrap(desc,
2108 initindent=initindent,
2110 initindent=initindent,
2109 hangindent=hangindent)))
2111 hangindent=hangindent)))
2110 else:
2112 else:
2111 ui.write("%s\n" % opt)
2113 ui.write("%s\n" % opt)
2112
2114
2113 def identify(ui, repo, source=None,
2115 def identify(ui, repo, source=None,
2114 rev=None, num=None, id=None, branch=None, tags=None):
2116 rev=None, num=None, id=None, branch=None, tags=None):
2115 """identify the working copy or specified revision
2117 """identify the working copy or specified revision
2116
2118
2117 With no revision, print a summary of the current state of the
2119 With no revision, print a summary of the current state of the
2118 repository.
2120 repository.
2119
2121
2120 Specifying a path to a repository root or Mercurial bundle will
2122 Specifying a path to a repository root or Mercurial bundle will
2121 cause lookup to operate on that repository/bundle.
2123 cause lookup to operate on that repository/bundle.
2122
2124
2123 This summary identifies the repository state using one or two
2125 This summary identifies the repository state using one or two
2124 parent hash identifiers, followed by a "+" if there are
2126 parent hash identifiers, followed by a "+" if there are
2125 uncommitted changes in the working directory, a list of tags for
2127 uncommitted changes in the working directory, a list of tags for
2126 this revision and a branch name for non-default branches.
2128 this revision and a branch name for non-default branches.
2127
2129
2128 Returns 0 if successful.
2130 Returns 0 if successful.
2129 """
2131 """
2130
2132
2131 if not repo and not source:
2133 if not repo and not source:
2132 raise util.Abort(_("there is no Mercurial repository here "
2134 raise util.Abort(_("there is no Mercurial repository here "
2133 "(.hg not found)"))
2135 "(.hg not found)"))
2134
2136
2135 hexfunc = ui.debugflag and hex or short
2137 hexfunc = ui.debugflag and hex or short
2136 default = not (num or id or branch or tags)
2138 default = not (num or id or branch or tags)
2137 output = []
2139 output = []
2138
2140
2139 revs = []
2141 revs = []
2140 if source:
2142 if source:
2141 source, branches = hg.parseurl(ui.expandpath(source))
2143 source, branches = hg.parseurl(ui.expandpath(source))
2142 repo = hg.repository(ui, source)
2144 repo = hg.repository(ui, source)
2143 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2145 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2144
2146
2145 if not repo.local():
2147 if not repo.local():
2146 if not rev and revs:
2148 if not rev and revs:
2147 rev = revs[0]
2149 rev = revs[0]
2148 if not rev:
2150 if not rev:
2149 rev = "tip"
2151 rev = "tip"
2150 if num or branch or tags:
2152 if num or branch or tags:
2151 raise util.Abort(
2153 raise util.Abort(
2152 "can't query remote revision number, branch, or tags")
2154 "can't query remote revision number, branch, or tags")
2153 output = [hexfunc(repo.lookup(rev))]
2155 output = [hexfunc(repo.lookup(rev))]
2154 elif not rev:
2156 elif not rev:
2155 ctx = repo[None]
2157 ctx = repo[None]
2156 parents = ctx.parents()
2158 parents = ctx.parents()
2157 changed = False
2159 changed = False
2158 if default or id or num:
2160 if default or id or num:
2159 changed = util.any(repo.status())
2161 changed = util.any(repo.status())
2160 if default or id:
2162 if default or id:
2161 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2163 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2162 (changed) and "+" or "")]
2164 (changed) and "+" or "")]
2163 if num:
2165 if num:
2164 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
2166 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
2165 (changed) and "+" or ""))
2167 (changed) and "+" or ""))
2166 else:
2168 else:
2167 ctx = repo[rev]
2169 ctx = repo[rev]
2168 if default or id:
2170 if default or id:
2169 output = [hexfunc(ctx.node())]
2171 output = [hexfunc(ctx.node())]
2170 if num:
2172 if num:
2171 output.append(str(ctx.rev()))
2173 output.append(str(ctx.rev()))
2172
2174
2173 if repo.local() and default and not ui.quiet:
2175 if repo.local() and default and not ui.quiet:
2174 b = encoding.tolocal(ctx.branch())
2176 b = encoding.tolocal(ctx.branch())
2175 if b != 'default':
2177 if b != 'default':
2176 output.append("(%s)" % b)
2178 output.append("(%s)" % b)
2177
2179
2178 # multiple tags for a single parent separated by '/'
2180 # multiple tags for a single parent separated by '/'
2179 t = "/".join(ctx.tags())
2181 t = "/".join(ctx.tags())
2180 if t:
2182 if t:
2181 output.append(t)
2183 output.append(t)
2182
2184
2183 if branch:
2185 if branch:
2184 output.append(encoding.tolocal(ctx.branch()))
2186 output.append(encoding.tolocal(ctx.branch()))
2185
2187
2186 if tags:
2188 if tags:
2187 output.extend(ctx.tags())
2189 output.extend(ctx.tags())
2188
2190
2189 ui.write("%s\n" % ' '.join(output))
2191 ui.write("%s\n" % ' '.join(output))
2190
2192
2191 def import_(ui, repo, patch1, *patches, **opts):
2193 def import_(ui, repo, patch1, *patches, **opts):
2192 """import an ordered set of patches
2194 """import an ordered set of patches
2193
2195
2194 Import a list of patches and commit them individually (unless
2196 Import a list of patches and commit them individually (unless
2195 --no-commit is specified).
2197 --no-commit is specified).
2196
2198
2197 If there are outstanding changes in the working directory, import
2199 If there are outstanding changes in the working directory, import
2198 will abort unless given the -f/--force flag.
2200 will abort unless given the -f/--force flag.
2199
2201
2200 You can import a patch straight from a mail message. Even patches
2202 You can import a patch straight from a mail message. Even patches
2201 as attachments work (to use the body part, it must have type
2203 as attachments work (to use the body part, it must have type
2202 text/plain or text/x-patch). From and Subject headers of email
2204 text/plain or text/x-patch). From and Subject headers of email
2203 message are used as default committer and commit message. All
2205 message are used as default committer and commit message. All
2204 text/plain body parts before first diff are added to commit
2206 text/plain body parts before first diff are added to commit
2205 message.
2207 message.
2206
2208
2207 If the imported patch was generated by :hg:`export`, user and
2209 If the imported patch was generated by :hg:`export`, user and
2208 description from patch override values from message headers and
2210 description from patch override values from message headers and
2209 body. Values given on command line with -m/--message and -u/--user
2211 body. Values given on command line with -m/--message and -u/--user
2210 override these.
2212 override these.
2211
2213
2212 If --exact is specified, import will set the working directory to
2214 If --exact is specified, import will set the working directory to
2213 the parent of each patch before applying it, and will abort if the
2215 the parent of each patch before applying it, and will abort if the
2214 resulting changeset has a different ID than the one recorded in
2216 resulting changeset has a different ID than the one recorded in
2215 the patch. This may happen due to character set problems or other
2217 the patch. This may happen due to character set problems or other
2216 deficiencies in the text patch format.
2218 deficiencies in the text patch format.
2217
2219
2218 With -s/--similarity, hg will attempt to discover renames and
2220 With -s/--similarity, hg will attempt to discover renames and
2219 copies in the patch in the same way as 'addremove'.
2221 copies in the patch in the same way as 'addremove'.
2220
2222
2221 To read a patch from standard input, use "-" as the patch name. If
2223 To read a patch from standard input, use "-" as the patch name. If
2222 a URL is specified, the patch will be downloaded from it.
2224 a URL is specified, the patch will be downloaded from it.
2223 See :hg:`help dates` for a list of formats valid for -d/--date.
2225 See :hg:`help dates` for a list of formats valid for -d/--date.
2224
2226
2225 Returns 0 on success.
2227 Returns 0 on success.
2226 """
2228 """
2227 patches = (patch1,) + patches
2229 patches = (patch1,) + patches
2228
2230
2229 date = opts.get('date')
2231 date = opts.get('date')
2230 if date:
2232 if date:
2231 opts['date'] = util.parsedate(date)
2233 opts['date'] = util.parsedate(date)
2232
2234
2233 try:
2235 try:
2234 sim = float(opts.get('similarity') or 0)
2236 sim = float(opts.get('similarity') or 0)
2235 except ValueError:
2237 except ValueError:
2236 raise util.Abort(_('similarity must be a number'))
2238 raise util.Abort(_('similarity must be a number'))
2237 if sim < 0 or sim > 100:
2239 if sim < 0 or sim > 100:
2238 raise util.Abort(_('similarity must be between 0 and 100'))
2240 raise util.Abort(_('similarity must be between 0 and 100'))
2239
2241
2240 if opts.get('exact') or not opts.get('force'):
2242 if opts.get('exact') or not opts.get('force'):
2241 cmdutil.bail_if_changed(repo)
2243 cmdutil.bail_if_changed(repo)
2242
2244
2243 d = opts["base"]
2245 d = opts["base"]
2244 strip = opts["strip"]
2246 strip = opts["strip"]
2245 wlock = lock = None
2247 wlock = lock = None
2246
2248
2247 def tryone(ui, hunk):
2249 def tryone(ui, hunk):
2248 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2250 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2249 patch.extract(ui, hunk)
2251 patch.extract(ui, hunk)
2250
2252
2251 if not tmpname:
2253 if not tmpname:
2252 return None
2254 return None
2253 commitid = _('to working directory')
2255 commitid = _('to working directory')
2254
2256
2255 try:
2257 try:
2256 cmdline_message = cmdutil.logmessage(opts)
2258 cmdline_message = cmdutil.logmessage(opts)
2257 if cmdline_message:
2259 if cmdline_message:
2258 # pickup the cmdline msg
2260 # pickup the cmdline msg
2259 message = cmdline_message
2261 message = cmdline_message
2260 elif message:
2262 elif message:
2261 # pickup the patch msg
2263 # pickup the patch msg
2262 message = message.strip()
2264 message = message.strip()
2263 else:
2265 else:
2264 # launch the editor
2266 # launch the editor
2265 message = None
2267 message = None
2266 ui.debug('message:\n%s\n' % message)
2268 ui.debug('message:\n%s\n' % message)
2267
2269
2268 wp = repo.parents()
2270 wp = repo.parents()
2269 if opts.get('exact'):
2271 if opts.get('exact'):
2270 if not nodeid or not p1:
2272 if not nodeid or not p1:
2271 raise util.Abort(_('not a Mercurial patch'))
2273 raise util.Abort(_('not a Mercurial patch'))
2272 p1 = repo.lookup(p1)
2274 p1 = repo.lookup(p1)
2273 p2 = repo.lookup(p2 or hex(nullid))
2275 p2 = repo.lookup(p2 or hex(nullid))
2274
2276
2275 if p1 != wp[0].node():
2277 if p1 != wp[0].node():
2276 hg.clean(repo, p1)
2278 hg.clean(repo, p1)
2277 repo.dirstate.setparents(p1, p2)
2279 repo.dirstate.setparents(p1, p2)
2278 elif p2:
2280 elif p2:
2279 try:
2281 try:
2280 p1 = repo.lookup(p1)
2282 p1 = repo.lookup(p1)
2281 p2 = repo.lookup(p2)
2283 p2 = repo.lookup(p2)
2282 if p1 == wp[0].node():
2284 if p1 == wp[0].node():
2283 repo.dirstate.setparents(p1, p2)
2285 repo.dirstate.setparents(p1, p2)
2284 except error.RepoError:
2286 except error.RepoError:
2285 pass
2287 pass
2286 if opts.get('exact') or opts.get('import_branch'):
2288 if opts.get('exact') or opts.get('import_branch'):
2287 repo.dirstate.setbranch(branch or 'default')
2289 repo.dirstate.setbranch(branch or 'default')
2288
2290
2289 files = {}
2291 files = {}
2290 try:
2292 try:
2291 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2293 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2292 files=files, eolmode=None)
2294 files=files, eolmode=None)
2293 finally:
2295 finally:
2294 files = cmdutil.updatedir(ui, repo, files,
2296 files = cmdutil.updatedir(ui, repo, files,
2295 similarity=sim / 100.0)
2297 similarity=sim / 100.0)
2296 if not opts.get('no_commit'):
2298 if not opts.get('no_commit'):
2297 if opts.get('exact'):
2299 if opts.get('exact'):
2298 m = None
2300 m = None
2299 else:
2301 else:
2300 m = cmdutil.matchfiles(repo, files or [])
2302 m = cmdutil.matchfiles(repo, files or [])
2301 n = repo.commit(message, opts.get('user') or user,
2303 n = repo.commit(message, opts.get('user') or user,
2302 opts.get('date') or date, match=m,
2304 opts.get('date') or date, match=m,
2303 editor=cmdutil.commiteditor)
2305 editor=cmdutil.commiteditor)
2304 if opts.get('exact'):
2306 if opts.get('exact'):
2305 if hex(n) != nodeid:
2307 if hex(n) != nodeid:
2306 repo.rollback()
2308 repo.rollback()
2307 raise util.Abort(_('patch is damaged'
2309 raise util.Abort(_('patch is damaged'
2308 ' or loses information'))
2310 ' or loses information'))
2309 # Force a dirstate write so that the next transaction
2311 # Force a dirstate write so that the next transaction
2310 # backups an up-do-date file.
2312 # backups an up-do-date file.
2311 repo.dirstate.write()
2313 repo.dirstate.write()
2312 if n:
2314 if n:
2313 commitid = short(n)
2315 commitid = short(n)
2314
2316
2315 return commitid
2317 return commitid
2316 finally:
2318 finally:
2317 os.unlink(tmpname)
2319 os.unlink(tmpname)
2318
2320
2319 try:
2321 try:
2320 wlock = repo.wlock()
2322 wlock = repo.wlock()
2321 lock = repo.lock()
2323 lock = repo.lock()
2322 lastcommit = None
2324 lastcommit = None
2323 for p in patches:
2325 for p in patches:
2324 pf = os.path.join(d, p)
2326 pf = os.path.join(d, p)
2325
2327
2326 if pf == '-':
2328 if pf == '-':
2327 ui.status(_("applying patch from stdin\n"))
2329 ui.status(_("applying patch from stdin\n"))
2328 pf = sys.stdin
2330 pf = sys.stdin
2329 else:
2331 else:
2330 ui.status(_("applying %s\n") % p)
2332 ui.status(_("applying %s\n") % p)
2331 pf = url.open(ui, pf)
2333 pf = url.open(ui, pf)
2332
2334
2333 haspatch = False
2335 haspatch = False
2334 for hunk in patch.split(pf):
2336 for hunk in patch.split(pf):
2335 commitid = tryone(ui, hunk)
2337 commitid = tryone(ui, hunk)
2336 if commitid:
2338 if commitid:
2337 haspatch = True
2339 haspatch = True
2338 if lastcommit:
2340 if lastcommit:
2339 ui.status(_('applied %s\n') % lastcommit)
2341 ui.status(_('applied %s\n') % lastcommit)
2340 lastcommit = commitid
2342 lastcommit = commitid
2341
2343
2342 if not haspatch:
2344 if not haspatch:
2343 raise util.Abort(_('no diffs found'))
2345 raise util.Abort(_('no diffs found'))
2344
2346
2345 finally:
2347 finally:
2346 release(lock, wlock)
2348 release(lock, wlock)
2347
2349
2348 def incoming(ui, repo, source="default", **opts):
2350 def incoming(ui, repo, source="default", **opts):
2349 """show new changesets found in source
2351 """show new changesets found in source
2350
2352
2351 Show new changesets found in the specified path/URL or the default
2353 Show new changesets found in the specified path/URL or the default
2352 pull location. These are the changesets that would have been pulled
2354 pull location. These are the changesets that would have been pulled
2353 if a pull at the time you issued this command.
2355 if a pull at the time you issued this command.
2354
2356
2355 For remote repository, using --bundle avoids downloading the
2357 For remote repository, using --bundle avoids downloading the
2356 changesets twice if the incoming is followed by a pull.
2358 changesets twice if the incoming is followed by a pull.
2357
2359
2358 See pull for valid source format details.
2360 See pull for valid source format details.
2359
2361
2360 Returns 0 if there are incoming changes, 1 otherwise.
2362 Returns 0 if there are incoming changes, 1 otherwise.
2361 """
2363 """
2362 if opts.get('bundle') and opts.get('subrepos'):
2364 if opts.get('bundle') and opts.get('subrepos'):
2363 raise util.Abort(_('cannot combine --bundle and --subrepos'))
2365 raise util.Abort(_('cannot combine --bundle and --subrepos'))
2364
2366
2365 ret = hg.incoming(ui, repo, source, opts)
2367 ret = hg.incoming(ui, repo, source, opts)
2366 return ret
2368 return ret
2367
2369
2368 def init(ui, dest=".", **opts):
2370 def init(ui, dest=".", **opts):
2369 """create a new repository in the given directory
2371 """create a new repository in the given directory
2370
2372
2371 Initialize a new repository in the given directory. If the given
2373 Initialize a new repository in the given directory. If the given
2372 directory does not exist, it will be created.
2374 directory does not exist, it will be created.
2373
2375
2374 If no directory is given, the current directory is used.
2376 If no directory is given, the current directory is used.
2375
2377
2376 It is possible to specify an ``ssh://`` URL as the destination.
2378 It is possible to specify an ``ssh://`` URL as the destination.
2377 See :hg:`help urls` for more information.
2379 See :hg:`help urls` for more information.
2378
2380
2379 Returns 0 on success.
2381 Returns 0 on success.
2380 """
2382 """
2381 hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
2383 hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
2382
2384
2383 def locate(ui, repo, *pats, **opts):
2385 def locate(ui, repo, *pats, **opts):
2384 """locate files matching specific patterns
2386 """locate files matching specific patterns
2385
2387
2386 Print files under Mercurial control in the working directory whose
2388 Print files under Mercurial control in the working directory whose
2387 names match the given patterns.
2389 names match the given patterns.
2388
2390
2389 By default, this command searches all directories in the working
2391 By default, this command searches all directories in the working
2390 directory. To search just the current directory and its
2392 directory. To search just the current directory and its
2391 subdirectories, use "--include .".
2393 subdirectories, use "--include .".
2392
2394
2393 If no patterns are given to match, this command prints the names
2395 If no patterns are given to match, this command prints the names
2394 of all files under Mercurial control in the working directory.
2396 of all files under Mercurial control in the working directory.
2395
2397
2396 If you want to feed the output of this command into the "xargs"
2398 If you want to feed the output of this command into the "xargs"
2397 command, use the -0 option to both this command and "xargs". This
2399 command, use the -0 option to both this command and "xargs". This
2398 will avoid the problem of "xargs" treating single filenames that
2400 will avoid the problem of "xargs" treating single filenames that
2399 contain whitespace as multiple filenames.
2401 contain whitespace as multiple filenames.
2400
2402
2401 Returns 0 if a match is found, 1 otherwise.
2403 Returns 0 if a match is found, 1 otherwise.
2402 """
2404 """
2403 end = opts.get('print0') and '\0' or '\n'
2405 end = opts.get('print0') and '\0' or '\n'
2404 rev = opts.get('rev') or None
2406 rev = opts.get('rev') or None
2405
2407
2406 ret = 1
2408 ret = 1
2407 m = cmdutil.match(repo, pats, opts, default='relglob')
2409 m = cmdutil.match(repo, pats, opts, default='relglob')
2408 m.bad = lambda x, y: False
2410 m.bad = lambda x, y: False
2409 for abs in repo[rev].walk(m):
2411 for abs in repo[rev].walk(m):
2410 if not rev and abs not in repo.dirstate:
2412 if not rev and abs not in repo.dirstate:
2411 continue
2413 continue
2412 if opts.get('fullpath'):
2414 if opts.get('fullpath'):
2413 ui.write(repo.wjoin(abs), end)
2415 ui.write(repo.wjoin(abs), end)
2414 else:
2416 else:
2415 ui.write(((pats and m.rel(abs)) or abs), end)
2417 ui.write(((pats and m.rel(abs)) or abs), end)
2416 ret = 0
2418 ret = 0
2417
2419
2418 return ret
2420 return ret
2419
2421
2420 def log(ui, repo, *pats, **opts):
2422 def log(ui, repo, *pats, **opts):
2421 """show revision history of entire repository or files
2423 """show revision history of entire repository or files
2422
2424
2423 Print the revision history of the specified files or the entire
2425 Print the revision history of the specified files or the entire
2424 project.
2426 project.
2425
2427
2426 File history is shown without following rename or copy history of
2428 File history is shown without following rename or copy history of
2427 files. Use -f/--follow with a filename to follow history across
2429 files. Use -f/--follow with a filename to follow history across
2428 renames and copies. --follow without a filename will only show
2430 renames and copies. --follow without a filename will only show
2429 ancestors or descendants of the starting revision. --follow-first
2431 ancestors or descendants of the starting revision. --follow-first
2430 only follows the first parent of merge revisions.
2432 only follows the first parent of merge revisions.
2431
2433
2432 If no revision range is specified, the default is tip:0 unless
2434 If no revision range is specified, the default is tip:0 unless
2433 --follow is set, in which case the working directory parent is
2435 --follow is set, in which case the working directory parent is
2434 used as the starting revision. You can specify a revision set for
2436 used as the starting revision. You can specify a revision set for
2435 log, see :hg:`help revsets` for more information.
2437 log, see :hg:`help revsets` for more information.
2436
2438
2437 See :hg:`help dates` for a list of formats valid for -d/--date.
2439 See :hg:`help dates` for a list of formats valid for -d/--date.
2438
2440
2439 By default this command prints revision number and changeset id,
2441 By default this command prints revision number and changeset id,
2440 tags, non-trivial parents, user, date and time, and a summary for
2442 tags, non-trivial parents, user, date and time, and a summary for
2441 each commit. When the -v/--verbose switch is used, the list of
2443 each commit. When the -v/--verbose switch is used, the list of
2442 changed files and full commit message are shown.
2444 changed files and full commit message are shown.
2443
2445
2444 .. note::
2446 .. note::
2445 log -p/--patch may generate unexpected diff output for merge
2447 log -p/--patch may generate unexpected diff output for merge
2446 changesets, as it will only compare the merge changeset against
2448 changesets, as it will only compare the merge changeset against
2447 its first parent. Also, only files different from BOTH parents
2449 its first parent. Also, only files different from BOTH parents
2448 will appear in files:.
2450 will appear in files:.
2449
2451
2450 Returns 0 on success.
2452 Returns 0 on success.
2451 """
2453 """
2452
2454
2453 matchfn = cmdutil.match(repo, pats, opts)
2455 matchfn = cmdutil.match(repo, pats, opts)
2454 limit = cmdutil.loglimit(opts)
2456 limit = cmdutil.loglimit(opts)
2455 count = 0
2457 count = 0
2456
2458
2457 endrev = None
2459 endrev = None
2458 if opts.get('copies') and opts.get('rev'):
2460 if opts.get('copies') and opts.get('rev'):
2459 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2461 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2460
2462
2461 df = False
2463 df = False
2462 if opts["date"]:
2464 if opts["date"]:
2463 df = util.matchdate(opts["date"])
2465 df = util.matchdate(opts["date"])
2464
2466
2465 branches = opts.get('branch', []) + opts.get('only_branch', [])
2467 branches = opts.get('branch', []) + opts.get('only_branch', [])
2466 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2468 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2467
2469
2468 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2470 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2469 def prep(ctx, fns):
2471 def prep(ctx, fns):
2470 rev = ctx.rev()
2472 rev = ctx.rev()
2471 parents = [p for p in repo.changelog.parentrevs(rev)
2473 parents = [p for p in repo.changelog.parentrevs(rev)
2472 if p != nullrev]
2474 if p != nullrev]
2473 if opts.get('no_merges') and len(parents) == 2:
2475 if opts.get('no_merges') and len(parents) == 2:
2474 return
2476 return
2475 if opts.get('only_merges') and len(parents) != 2:
2477 if opts.get('only_merges') and len(parents) != 2:
2476 return
2478 return
2477 if opts.get('branch') and ctx.branch() not in opts['branch']:
2479 if opts.get('branch') and ctx.branch() not in opts['branch']:
2478 return
2480 return
2479 if df and not df(ctx.date()[0]):
2481 if df and not df(ctx.date()[0]):
2480 return
2482 return
2481 if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
2483 if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
2482 return
2484 return
2483 if opts.get('keyword'):
2485 if opts.get('keyword'):
2484 for k in [kw.lower() for kw in opts['keyword']]:
2486 for k in [kw.lower() for kw in opts['keyword']]:
2485 if (k in ctx.user().lower() or
2487 if (k in ctx.user().lower() or
2486 k in ctx.description().lower() or
2488 k in ctx.description().lower() or
2487 k in " ".join(ctx.files()).lower()):
2489 k in " ".join(ctx.files()).lower()):
2488 break
2490 break
2489 else:
2491 else:
2490 return
2492 return
2491
2493
2492 copies = None
2494 copies = None
2493 if opts.get('copies') and rev:
2495 if opts.get('copies') and rev:
2494 copies = []
2496 copies = []
2495 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2497 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2496 for fn in ctx.files():
2498 for fn in ctx.files():
2497 rename = getrenamed(fn, rev)
2499 rename = getrenamed(fn, rev)
2498 if rename:
2500 if rename:
2499 copies.append((fn, rename[0]))
2501 copies.append((fn, rename[0]))
2500
2502
2501 revmatchfn = None
2503 revmatchfn = None
2502 if opts.get('patch') or opts.get('stat'):
2504 if opts.get('patch') or opts.get('stat'):
2503 if opts.get('follow') or opts.get('follow_first'):
2505 if opts.get('follow') or opts.get('follow_first'):
2504 # note: this might be wrong when following through merges
2506 # note: this might be wrong when following through merges
2505 revmatchfn = cmdutil.match(repo, fns, default='path')
2507 revmatchfn = cmdutil.match(repo, fns, default='path')
2506 else:
2508 else:
2507 revmatchfn = matchfn
2509 revmatchfn = matchfn
2508
2510
2509 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2511 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2510
2512
2511 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2513 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2512 if count == limit:
2514 if count == limit:
2513 break
2515 break
2514 if displayer.flush(ctx.rev()):
2516 if displayer.flush(ctx.rev()):
2515 count += 1
2517 count += 1
2516 displayer.close()
2518 displayer.close()
2517
2519
2518 def manifest(ui, repo, node=None, rev=None):
2520 def manifest(ui, repo, node=None, rev=None):
2519 """output the current or given revision of the project manifest
2521 """output the current or given revision of the project manifest
2520
2522
2521 Print a list of version controlled files for the given revision.
2523 Print a list of version controlled files for the given revision.
2522 If no revision is given, the first parent of the working directory
2524 If no revision is given, the first parent of the working directory
2523 is used, or the null revision if no revision is checked out.
2525 is used, or the null revision if no revision is checked out.
2524
2526
2525 With -v, print file permissions, symlink and executable bits.
2527 With -v, print file permissions, symlink and executable bits.
2526 With --debug, print file revision hashes.
2528 With --debug, print file revision hashes.
2527
2529
2528 Returns 0 on success.
2530 Returns 0 on success.
2529 """
2531 """
2530
2532
2531 if rev and node:
2533 if rev and node:
2532 raise util.Abort(_("please specify just one revision"))
2534 raise util.Abort(_("please specify just one revision"))
2533
2535
2534 if not node:
2536 if not node:
2535 node = rev
2537 node = rev
2536
2538
2537 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2539 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2538 ctx = repo[node]
2540 ctx = repo[node]
2539 for f in ctx:
2541 for f in ctx:
2540 if ui.debugflag:
2542 if ui.debugflag:
2541 ui.write("%40s " % hex(ctx.manifest()[f]))
2543 ui.write("%40s " % hex(ctx.manifest()[f]))
2542 if ui.verbose:
2544 if ui.verbose:
2543 ui.write(decor[ctx.flags(f)])
2545 ui.write(decor[ctx.flags(f)])
2544 ui.write("%s\n" % f)
2546 ui.write("%s\n" % f)
2545
2547
2546 def merge(ui, repo, node=None, **opts):
2548 def merge(ui, repo, node=None, **opts):
2547 """merge working directory with another revision
2549 """merge working directory with another revision
2548
2550
2549 The current working directory is updated with all changes made in
2551 The current working directory is updated with all changes made in
2550 the requested revision since the last common predecessor revision.
2552 the requested revision since the last common predecessor revision.
2551
2553
2552 Files that changed between either parent are marked as changed for
2554 Files that changed between either parent are marked as changed for
2553 the next commit and a commit must be performed before any further
2555 the next commit and a commit must be performed before any further
2554 updates to the repository are allowed. The next commit will have
2556 updates to the repository are allowed. The next commit will have
2555 two parents.
2557 two parents.
2556
2558
2557 If no revision is specified, the working directory's parent is a
2559 If no revision is specified, the working directory's parent is a
2558 head revision, and the current branch contains exactly one other
2560 head revision, and the current branch contains exactly one other
2559 head, the other head is merged with by default. Otherwise, an
2561 head, the other head is merged with by default. Otherwise, an
2560 explicit revision with which to merge with must be provided.
2562 explicit revision with which to merge with must be provided.
2561
2563
2562 To undo an uncommitted merge, use :hg:`update --clean .` which
2564 To undo an uncommitted merge, use :hg:`update --clean .` which
2563 will check out a clean copy of the original merge parent, losing
2565 will check out a clean copy of the original merge parent, losing
2564 all changes.
2566 all changes.
2565
2567
2566 Returns 0 on success, 1 if there are unresolved files.
2568 Returns 0 on success, 1 if there are unresolved files.
2567 """
2569 """
2568
2570
2569 if opts.get('rev') and node:
2571 if opts.get('rev') and node:
2570 raise util.Abort(_("please specify just one revision"))
2572 raise util.Abort(_("please specify just one revision"))
2571 if not node:
2573 if not node:
2572 node = opts.get('rev')
2574 node = opts.get('rev')
2573
2575
2574 if not node:
2576 if not node:
2575 branch = repo.changectx(None).branch()
2577 branch = repo.changectx(None).branch()
2576 bheads = repo.branchheads(branch)
2578 bheads = repo.branchheads(branch)
2577 if len(bheads) > 2:
2579 if len(bheads) > 2:
2578 raise util.Abort(_(
2580 raise util.Abort(_(
2579 'branch \'%s\' has %d heads - '
2581 'branch \'%s\' has %d heads - '
2580 'please merge with an explicit rev\n'
2582 'please merge with an explicit rev\n'
2581 '(run \'hg heads .\' to see heads)')
2583 '(run \'hg heads .\' to see heads)')
2582 % (branch, len(bheads)))
2584 % (branch, len(bheads)))
2583
2585
2584 parent = repo.dirstate.parents()[0]
2586 parent = repo.dirstate.parents()[0]
2585 if len(bheads) == 1:
2587 if len(bheads) == 1:
2586 if len(repo.heads()) > 1:
2588 if len(repo.heads()) > 1:
2587 raise util.Abort(_(
2589 raise util.Abort(_(
2588 'branch \'%s\' has one head - '
2590 'branch \'%s\' has one head - '
2589 'please merge with an explicit rev\n'
2591 'please merge with an explicit rev\n'
2590 '(run \'hg heads\' to see all heads)')
2592 '(run \'hg heads\' to see all heads)')
2591 % branch)
2593 % branch)
2592 msg = _('there is nothing to merge')
2594 msg = _('there is nothing to merge')
2593 if parent != repo.lookup(repo[None].branch()):
2595 if parent != repo.lookup(repo[None].branch()):
2594 msg = _('%s - use "hg update" instead') % msg
2596 msg = _('%s - use "hg update" instead') % msg
2595 raise util.Abort(msg)
2597 raise util.Abort(msg)
2596
2598
2597 if parent not in bheads:
2599 if parent not in bheads:
2598 raise util.Abort(_('working dir not at a head rev - '
2600 raise util.Abort(_('working dir not at a head rev - '
2599 'use "hg update" or merge with an explicit rev'))
2601 'use "hg update" or merge with an explicit rev'))
2600 node = parent == bheads[0] and bheads[-1] or bheads[0]
2602 node = parent == bheads[0] and bheads[-1] or bheads[0]
2601
2603
2602 if opts.get('preview'):
2604 if opts.get('preview'):
2603 # find nodes that are ancestors of p2 but not of p1
2605 # find nodes that are ancestors of p2 but not of p1
2604 p1 = repo.lookup('.')
2606 p1 = repo.lookup('.')
2605 p2 = repo.lookup(node)
2607 p2 = repo.lookup(node)
2606 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2608 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2607
2609
2608 displayer = cmdutil.show_changeset(ui, repo, opts)
2610 displayer = cmdutil.show_changeset(ui, repo, opts)
2609 for node in nodes:
2611 for node in nodes:
2610 displayer.show(repo[node])
2612 displayer.show(repo[node])
2611 displayer.close()
2613 displayer.close()
2612 return 0
2614 return 0
2613
2615
2614 return hg.merge(repo, node, force=opts.get('force'))
2616 return hg.merge(repo, node, force=opts.get('force'))
2615
2617
2616 def outgoing(ui, repo, dest=None, **opts):
2618 def outgoing(ui, repo, dest=None, **opts):
2617 """show changesets not found in the destination
2619 """show changesets not found in the destination
2618
2620
2619 Show changesets not found in the specified destination repository
2621 Show changesets not found in the specified destination repository
2620 or the default push location. These are the changesets that would
2622 or the default push location. These are the changesets that would
2621 be pushed if a push was requested.
2623 be pushed if a push was requested.
2622
2624
2623 See pull for details of valid destination formats.
2625 See pull for details of valid destination formats.
2624
2626
2625 Returns 0 if there are outgoing changes, 1 otherwise.
2627 Returns 0 if there are outgoing changes, 1 otherwise.
2626 """
2628 """
2627 ret = hg.outgoing(ui, repo, dest, opts)
2629 ret = hg.outgoing(ui, repo, dest, opts)
2628 return ret
2630 return ret
2629
2631
2630 def parents(ui, repo, file_=None, **opts):
2632 def parents(ui, repo, file_=None, **opts):
2631 """show the parents of the working directory or revision
2633 """show the parents of the working directory or revision
2632
2634
2633 Print the working directory's parent revisions. If a revision is
2635 Print the working directory's parent revisions. If a revision is
2634 given via -r/--rev, the parent of that revision will be printed.
2636 given via -r/--rev, the parent of that revision will be printed.
2635 If a file argument is given, the revision in which the file was
2637 If a file argument is given, the revision in which the file was
2636 last changed (before the working directory revision or the
2638 last changed (before the working directory revision or the
2637 argument to --rev if given) is printed.
2639 argument to --rev if given) is printed.
2638
2640
2639 Returns 0 on success.
2641 Returns 0 on success.
2640 """
2642 """
2641 rev = opts.get('rev')
2643 rev = opts.get('rev')
2642 if rev:
2644 if rev:
2643 ctx = repo[rev]
2645 ctx = repo[rev]
2644 else:
2646 else:
2645 ctx = repo[None]
2647 ctx = repo[None]
2646
2648
2647 if file_:
2649 if file_:
2648 m = cmdutil.match(repo, (file_,), opts)
2650 m = cmdutil.match(repo, (file_,), opts)
2649 if m.anypats() or len(m.files()) != 1:
2651 if m.anypats() or len(m.files()) != 1:
2650 raise util.Abort(_('can only specify an explicit filename'))
2652 raise util.Abort(_('can only specify an explicit filename'))
2651 file_ = m.files()[0]
2653 file_ = m.files()[0]
2652 filenodes = []
2654 filenodes = []
2653 for cp in ctx.parents():
2655 for cp in ctx.parents():
2654 if not cp:
2656 if not cp:
2655 continue
2657 continue
2656 try:
2658 try:
2657 filenodes.append(cp.filenode(file_))
2659 filenodes.append(cp.filenode(file_))
2658 except error.LookupError:
2660 except error.LookupError:
2659 pass
2661 pass
2660 if not filenodes:
2662 if not filenodes:
2661 raise util.Abort(_("'%s' not found in manifest!") % file_)
2663 raise util.Abort(_("'%s' not found in manifest!") % file_)
2662 fl = repo.file(file_)
2664 fl = repo.file(file_)
2663 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2665 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2664 else:
2666 else:
2665 p = [cp.node() for cp in ctx.parents()]
2667 p = [cp.node() for cp in ctx.parents()]
2666
2668
2667 displayer = cmdutil.show_changeset(ui, repo, opts)
2669 displayer = cmdutil.show_changeset(ui, repo, opts)
2668 for n in p:
2670 for n in p:
2669 if n != nullid:
2671 if n != nullid:
2670 displayer.show(repo[n])
2672 displayer.show(repo[n])
2671 displayer.close()
2673 displayer.close()
2672
2674
2673 def paths(ui, repo, search=None):
2675 def paths(ui, repo, search=None):
2674 """show aliases for remote repositories
2676 """show aliases for remote repositories
2675
2677
2676 Show definition of symbolic path name NAME. If no name is given,
2678 Show definition of symbolic path name NAME. If no name is given,
2677 show definition of all available names.
2679 show definition of all available names.
2678
2680
2679 Path names are defined in the [paths] section of your
2681 Path names are defined in the [paths] section of your
2680 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
2682 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
2681 repository, ``.hg/hgrc`` is used, too.
2683 repository, ``.hg/hgrc`` is used, too.
2682
2684
2683 The path names ``default`` and ``default-push`` have a special
2685 The path names ``default`` and ``default-push`` have a special
2684 meaning. When performing a push or pull operation, they are used
2686 meaning. When performing a push or pull operation, they are used
2685 as fallbacks if no location is specified on the command-line.
2687 as fallbacks if no location is specified on the command-line.
2686 When ``default-push`` is set, it will be used for push and
2688 When ``default-push`` is set, it will be used for push and
2687 ``default`` will be used for pull; otherwise ``default`` is used
2689 ``default`` will be used for pull; otherwise ``default`` is used
2688 as the fallback for both. When cloning a repository, the clone
2690 as the fallback for both. When cloning a repository, the clone
2689 source is written as ``default`` in ``.hg/hgrc``. Note that
2691 source is written as ``default`` in ``.hg/hgrc``. Note that
2690 ``default`` and ``default-push`` apply to all inbound (e.g.
2692 ``default`` and ``default-push`` apply to all inbound (e.g.
2691 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2693 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2692 :hg:`bundle`) operations.
2694 :hg:`bundle`) operations.
2693
2695
2694 See :hg:`help urls` for more information.
2696 See :hg:`help urls` for more information.
2695
2697
2696 Returns 0 on success.
2698 Returns 0 on success.
2697 """
2699 """
2698 if search:
2700 if search:
2699 for name, path in ui.configitems("paths"):
2701 for name, path in ui.configitems("paths"):
2700 if name == search:
2702 if name == search:
2701 ui.write("%s\n" % url.hidepassword(path))
2703 ui.write("%s\n" % url.hidepassword(path))
2702 return
2704 return
2703 ui.warn(_("not found!\n"))
2705 ui.warn(_("not found!\n"))
2704 return 1
2706 return 1
2705 else:
2707 else:
2706 for name, path in ui.configitems("paths"):
2708 for name, path in ui.configitems("paths"):
2707 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2709 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2708
2710
2709 def postincoming(ui, repo, modheads, optupdate, checkout):
2711 def postincoming(ui, repo, modheads, optupdate, checkout):
2710 if modheads == 0:
2712 if modheads == 0:
2711 return
2713 return
2712 if optupdate:
2714 if optupdate:
2713 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2715 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2714 return hg.update(repo, checkout)
2716 return hg.update(repo, checkout)
2715 else:
2717 else:
2716 ui.status(_("not updating, since new heads added\n"))
2718 ui.status(_("not updating, since new heads added\n"))
2717 if modheads > 1:
2719 if modheads > 1:
2718 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2720 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2719 else:
2721 else:
2720 ui.status(_("(run 'hg update' to get a working copy)\n"))
2722 ui.status(_("(run 'hg update' to get a working copy)\n"))
2721
2723
2722 def pull(ui, repo, source="default", **opts):
2724 def pull(ui, repo, source="default", **opts):
2723 """pull changes from the specified source
2725 """pull changes from the specified source
2724
2726
2725 Pull changes from a remote repository to a local one.
2727 Pull changes from a remote repository to a local one.
2726
2728
2727 This finds all changes from the repository at the specified path
2729 This finds all changes from the repository at the specified path
2728 or URL and adds them to a local repository (the current one unless
2730 or URL and adds them to a local repository (the current one unless
2729 -R is specified). By default, this does not update the copy of the
2731 -R is specified). By default, this does not update the copy of the
2730 project in the working directory.
2732 project in the working directory.
2731
2733
2732 Use :hg:`incoming` if you want to see what would have been added
2734 Use :hg:`incoming` if you want to see what would have been added
2733 by a pull at the time you issued this command. If you then decide
2735 by a pull at the time you issued this command. If you then decide
2734 to add those changes to the repository, you should use :hg:`pull
2736 to add those changes to the repository, you should use :hg:`pull
2735 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
2737 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
2736
2738
2737 If SOURCE is omitted, the 'default' path will be used.
2739 If SOURCE is omitted, the 'default' path will be used.
2738 See :hg:`help urls` for more information.
2740 See :hg:`help urls` for more information.
2739
2741
2740 Returns 0 on success, 1 if an update had unresolved files.
2742 Returns 0 on success, 1 if an update had unresolved files.
2741 """
2743 """
2742 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2744 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2743 other = hg.repository(hg.remoteui(repo, opts), source)
2745 other = hg.repository(hg.remoteui(repo, opts), source)
2744 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2746 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2745 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2747 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2746 if revs:
2748 if revs:
2747 try:
2749 try:
2748 revs = [other.lookup(rev) for rev in revs]
2750 revs = [other.lookup(rev) for rev in revs]
2749 except error.CapabilityError:
2751 except error.CapabilityError:
2750 err = _("other repository doesn't support revision lookup, "
2752 err = _("other repository doesn't support revision lookup, "
2751 "so a rev cannot be specified.")
2753 "so a rev cannot be specified.")
2752 raise util.Abort(err)
2754 raise util.Abort(err)
2753
2755
2754 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2756 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2755 if checkout:
2757 if checkout:
2756 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2758 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2757 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2759 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2758
2760
2759 def push(ui, repo, dest=None, **opts):
2761 def push(ui, repo, dest=None, **opts):
2760 """push changes to the specified destination
2762 """push changes to the specified destination
2761
2763
2762 Push changesets from the local repository to the specified
2764 Push changesets from the local repository to the specified
2763 destination.
2765 destination.
2764
2766
2765 This operation is symmetrical to pull: it is identical to a pull
2767 This operation is symmetrical to pull: it is identical to a pull
2766 in the destination repository from the current one.
2768 in the destination repository from the current one.
2767
2769
2768 By default, push will not allow creation of new heads at the
2770 By default, push will not allow creation of new heads at the
2769 destination, since multiple heads would make it unclear which head
2771 destination, since multiple heads would make it unclear which head
2770 to use. In this situation, it is recommended to pull and merge
2772 to use. In this situation, it is recommended to pull and merge
2771 before pushing.
2773 before pushing.
2772
2774
2773 Use --new-branch if you want to allow push to create a new named
2775 Use --new-branch if you want to allow push to create a new named
2774 branch that is not present at the destination. This allows you to
2776 branch that is not present at the destination. This allows you to
2775 only create a new branch without forcing other changes.
2777 only create a new branch without forcing other changes.
2776
2778
2777 Use -f/--force to override the default behavior and push all
2779 Use -f/--force to override the default behavior and push all
2778 changesets on all branches.
2780 changesets on all branches.
2779
2781
2780 If -r/--rev is used, the specified revision and all its ancestors
2782 If -r/--rev is used, the specified revision and all its ancestors
2781 will be pushed to the remote repository.
2783 will be pushed to the remote repository.
2782
2784
2783 Please see :hg:`help urls` for important details about ``ssh://``
2785 Please see :hg:`help urls` for important details about ``ssh://``
2784 URLs. If DESTINATION is omitted, a default path will be used.
2786 URLs. If DESTINATION is omitted, a default path will be used.
2785
2787
2786 Returns 0 if push was successful, 1 if nothing to push.
2788 Returns 0 if push was successful, 1 if nothing to push.
2787 """
2789 """
2788 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2790 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2789 dest, branches = hg.parseurl(dest, opts.get('branch'))
2791 dest, branches = hg.parseurl(dest, opts.get('branch'))
2790 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2792 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2791 other = hg.repository(hg.remoteui(repo, opts), dest)
2793 other = hg.repository(hg.remoteui(repo, opts), dest)
2792 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2794 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2793 if revs:
2795 if revs:
2794 revs = [repo.lookup(rev) for rev in revs]
2796 revs = [repo.lookup(rev) for rev in revs]
2795
2797
2796 # push subrepos depth-first for coherent ordering
2798 # push subrepos depth-first for coherent ordering
2797 c = repo['']
2799 c = repo['']
2798 subs = c.substate # only repos that are committed
2800 subs = c.substate # only repos that are committed
2799 for s in sorted(subs):
2801 for s in sorted(subs):
2800 if not c.sub(s).push(opts.get('force')):
2802 if not c.sub(s).push(opts.get('force')):
2801 return False
2803 return False
2802
2804
2803 r = repo.push(other, opts.get('force'), revs=revs,
2805 r = repo.push(other, opts.get('force'), revs=revs,
2804 newbranch=opts.get('new_branch'))
2806 newbranch=opts.get('new_branch'))
2805 return r == 0
2807 return r == 0
2806
2808
2807 def recover(ui, repo):
2809 def recover(ui, repo):
2808 """roll back an interrupted transaction
2810 """roll back an interrupted transaction
2809
2811
2810 Recover from an interrupted commit or pull.
2812 Recover from an interrupted commit or pull.
2811
2813
2812 This command tries to fix the repository status after an
2814 This command tries to fix the repository status after an
2813 interrupted operation. It should only be necessary when Mercurial
2815 interrupted operation. It should only be necessary when Mercurial
2814 suggests it.
2816 suggests it.
2815
2817
2816 Returns 0 if successful, 1 if nothing to recover or verify fails.
2818 Returns 0 if successful, 1 if nothing to recover or verify fails.
2817 """
2819 """
2818 if repo.recover():
2820 if repo.recover():
2819 return hg.verify(repo)
2821 return hg.verify(repo)
2820 return 1
2822 return 1
2821
2823
2822 def remove(ui, repo, *pats, **opts):
2824 def remove(ui, repo, *pats, **opts):
2823 """remove the specified files on the next commit
2825 """remove the specified files on the next commit
2824
2826
2825 Schedule the indicated files for removal from the repository.
2827 Schedule the indicated files for removal from the repository.
2826
2828
2827 This only removes files from the current branch, not from the
2829 This only removes files from the current branch, not from the
2828 entire project history. -A/--after can be used to remove only
2830 entire project history. -A/--after can be used to remove only
2829 files that have already been deleted, -f/--force can be used to
2831 files that have already been deleted, -f/--force can be used to
2830 force deletion, and -Af can be used to remove files from the next
2832 force deletion, and -Af can be used to remove files from the next
2831 revision without deleting them from the working directory.
2833 revision without deleting them from the working directory.
2832
2834
2833 The following table details the behavior of remove for different
2835 The following table details the behavior of remove for different
2834 file states (columns) and option combinations (rows). The file
2836 file states (columns) and option combinations (rows). The file
2835 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
2837 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
2836 reported by :hg:`status`). The actions are Warn, Remove (from
2838 reported by :hg:`status`). The actions are Warn, Remove (from
2837 branch) and Delete (from disk)::
2839 branch) and Delete (from disk)::
2838
2840
2839 A C M !
2841 A C M !
2840 none W RD W R
2842 none W RD W R
2841 -f R RD RD R
2843 -f R RD RD R
2842 -A W W W R
2844 -A W W W R
2843 -Af R R R R
2845 -Af R R R R
2844
2846
2845 This command schedules the files to be removed at the next commit.
2847 This command schedules the files to be removed at the next commit.
2846 To undo a remove before that, see :hg:`revert`.
2848 To undo a remove before that, see :hg:`revert`.
2847
2849
2848 Returns 0 on success, 1 if any warnings encountered.
2850 Returns 0 on success, 1 if any warnings encountered.
2849 """
2851 """
2850
2852
2851 ret = 0
2853 ret = 0
2852 after, force = opts.get('after'), opts.get('force')
2854 after, force = opts.get('after'), opts.get('force')
2853 if not pats and not after:
2855 if not pats and not after:
2854 raise util.Abort(_('no files specified'))
2856 raise util.Abort(_('no files specified'))
2855
2857
2856 m = cmdutil.match(repo, pats, opts)
2858 m = cmdutil.match(repo, pats, opts)
2857 s = repo.status(match=m, clean=True)
2859 s = repo.status(match=m, clean=True)
2858 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2860 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2859
2861
2860 for f in m.files():
2862 for f in m.files():
2861 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2863 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2862 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2864 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2863 ret = 1
2865 ret = 1
2864
2866
2865 if force:
2867 if force:
2866 remove, forget = modified + deleted + clean, added
2868 remove, forget = modified + deleted + clean, added
2867 elif after:
2869 elif after:
2868 remove, forget = deleted, []
2870 remove, forget = deleted, []
2869 for f in modified + added + clean:
2871 for f in modified + added + clean:
2870 ui.warn(_('not removing %s: file still exists (use -f'
2872 ui.warn(_('not removing %s: file still exists (use -f'
2871 ' to force removal)\n') % m.rel(f))
2873 ' to force removal)\n') % m.rel(f))
2872 ret = 1
2874 ret = 1
2873 else:
2875 else:
2874 remove, forget = deleted + clean, []
2876 remove, forget = deleted + clean, []
2875 for f in modified:
2877 for f in modified:
2876 ui.warn(_('not removing %s: file is modified (use -f'
2878 ui.warn(_('not removing %s: file is modified (use -f'
2877 ' to force removal)\n') % m.rel(f))
2879 ' to force removal)\n') % m.rel(f))
2878 ret = 1
2880 ret = 1
2879 for f in added:
2881 for f in added:
2880 ui.warn(_('not removing %s: file has been marked for add (use -f'
2882 ui.warn(_('not removing %s: file has been marked for add (use -f'
2881 ' to force removal)\n') % m.rel(f))
2883 ' to force removal)\n') % m.rel(f))
2882 ret = 1
2884 ret = 1
2883
2885
2884 for f in sorted(remove + forget):
2886 for f in sorted(remove + forget):
2885 if ui.verbose or not m.exact(f):
2887 if ui.verbose or not m.exact(f):
2886 ui.status(_('removing %s\n') % m.rel(f))
2888 ui.status(_('removing %s\n') % m.rel(f))
2887
2889
2888 repo[None].forget(forget)
2890 repo[None].forget(forget)
2889 repo[None].remove(remove, unlink=not after)
2891 repo[None].remove(remove, unlink=not after)
2890 return ret
2892 return ret
2891
2893
2892 def rename(ui, repo, *pats, **opts):
2894 def rename(ui, repo, *pats, **opts):
2893 """rename files; equivalent of copy + remove
2895 """rename files; equivalent of copy + remove
2894
2896
2895 Mark dest as copies of sources; mark sources for deletion. If dest
2897 Mark dest as copies of sources; mark sources for deletion. If dest
2896 is a directory, copies are put in that directory. If dest is a
2898 is a directory, copies are put in that directory. If dest is a
2897 file, there can only be one source.
2899 file, there can only be one source.
2898
2900
2899 By default, this command copies the contents of files as they
2901 By default, this command copies the contents of files as they
2900 exist in the working directory. If invoked with -A/--after, the
2902 exist in the working directory. If invoked with -A/--after, the
2901 operation is recorded, but no copying is performed.
2903 operation is recorded, but no copying is performed.
2902
2904
2903 This command takes effect at the next commit. To undo a rename
2905 This command takes effect at the next commit. To undo a rename
2904 before that, see :hg:`revert`.
2906 before that, see :hg:`revert`.
2905
2907
2906 Returns 0 on success, 1 if errors are encountered.
2908 Returns 0 on success, 1 if errors are encountered.
2907 """
2909 """
2908 wlock = repo.wlock(False)
2910 wlock = repo.wlock(False)
2909 try:
2911 try:
2910 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2912 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2911 finally:
2913 finally:
2912 wlock.release()
2914 wlock.release()
2913
2915
2914 def resolve(ui, repo, *pats, **opts):
2916 def resolve(ui, repo, *pats, **opts):
2915 """redo merges or set/view the merge status of files
2917 """redo merges or set/view the merge status of files
2916
2918
2917 Merges with unresolved conflicts are often the result of
2919 Merges with unresolved conflicts are often the result of
2918 non-interactive merging using the ``internal:merge`` configuration
2920 non-interactive merging using the ``internal:merge`` configuration
2919 setting, or a command-line merge tool like ``diff3``. The resolve
2921 setting, or a command-line merge tool like ``diff3``. The resolve
2920 command is used to manage the files involved in a merge, after
2922 command is used to manage the files involved in a merge, after
2921 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
2923 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
2922 working directory must have two parents).
2924 working directory must have two parents).
2923
2925
2924 The resolve command can be used in the following ways:
2926 The resolve command can be used in the following ways:
2925
2927
2926 - :hg:`resolve FILE...`: attempt to re-merge the specified files,
2928 - :hg:`resolve FILE...`: attempt to re-merge the specified files,
2927 discarding any previous merge attempts. Re-merging is not
2929 discarding any previous merge attempts. Re-merging is not
2928 performed for files already marked as resolved. Use ``--all/-a``
2930 performed for files already marked as resolved. Use ``--all/-a``
2929 to selects all unresolved files.
2931 to selects all unresolved files.
2930
2932
2931 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
2933 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
2932 (e.g. after having manually fixed-up the files). The default is
2934 (e.g. after having manually fixed-up the files). The default is
2933 to mark all unresolved files.
2935 to mark all unresolved files.
2934
2936
2935 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
2937 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
2936 default is to mark all resolved files.
2938 default is to mark all resolved files.
2937
2939
2938 - :hg:`resolve -l`: list files which had or still have conflicts.
2940 - :hg:`resolve -l`: list files which had or still have conflicts.
2939 In the printed list, ``U`` = unresolved and ``R`` = resolved.
2941 In the printed list, ``U`` = unresolved and ``R`` = resolved.
2940
2942
2941 Note that Mercurial will not let you commit files with unresolved
2943 Note that Mercurial will not let you commit files with unresolved
2942 merge conflicts. You must use :hg:`resolve -m ...` before you can
2944 merge conflicts. You must use :hg:`resolve -m ...` before you can
2943 commit after a conflicting merge.
2945 commit after a conflicting merge.
2944
2946
2945 Returns 0 on success, 1 if any files fail a resolve attempt.
2947 Returns 0 on success, 1 if any files fail a resolve attempt.
2946 """
2948 """
2947
2949
2948 all, mark, unmark, show, nostatus = \
2950 all, mark, unmark, show, nostatus = \
2949 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
2951 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
2950
2952
2951 if (show and (mark or unmark)) or (mark and unmark):
2953 if (show and (mark or unmark)) or (mark and unmark):
2952 raise util.Abort(_("too many options specified"))
2954 raise util.Abort(_("too many options specified"))
2953 if pats and all:
2955 if pats and all:
2954 raise util.Abort(_("can't specify --all and patterns"))
2956 raise util.Abort(_("can't specify --all and patterns"))
2955 if not (all or pats or show or mark or unmark):
2957 if not (all or pats or show or mark or unmark):
2956 raise util.Abort(_('no files or directories specified; '
2958 raise util.Abort(_('no files or directories specified; '
2957 'use --all to remerge all files'))
2959 'use --all to remerge all files'))
2958
2960
2959 ms = mergemod.mergestate(repo)
2961 ms = mergemod.mergestate(repo)
2960 m = cmdutil.match(repo, pats, opts)
2962 m = cmdutil.match(repo, pats, opts)
2961 ret = 0
2963 ret = 0
2962
2964
2963 for f in ms:
2965 for f in ms:
2964 if m(f):
2966 if m(f):
2965 if show:
2967 if show:
2966 if nostatus:
2968 if nostatus:
2967 ui.write("%s\n" % f)
2969 ui.write("%s\n" % f)
2968 else:
2970 else:
2969 ui.write("%s %s\n" % (ms[f].upper(), f),
2971 ui.write("%s %s\n" % (ms[f].upper(), f),
2970 label='resolve.' +
2972 label='resolve.' +
2971 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
2973 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
2972 elif mark:
2974 elif mark:
2973 ms.mark(f, "r")
2975 ms.mark(f, "r")
2974 elif unmark:
2976 elif unmark:
2975 ms.mark(f, "u")
2977 ms.mark(f, "u")
2976 else:
2978 else:
2977 wctx = repo[None]
2979 wctx = repo[None]
2978 mctx = wctx.parents()[-1]
2980 mctx = wctx.parents()[-1]
2979
2981
2980 # backup pre-resolve (merge uses .orig for its own purposes)
2982 # backup pre-resolve (merge uses .orig for its own purposes)
2981 a = repo.wjoin(f)
2983 a = repo.wjoin(f)
2982 util.copyfile(a, a + ".resolve")
2984 util.copyfile(a, a + ".resolve")
2983
2985
2984 # resolve file
2986 # resolve file
2985 if ms.resolve(f, wctx, mctx):
2987 if ms.resolve(f, wctx, mctx):
2986 ret = 1
2988 ret = 1
2987
2989
2988 # replace filemerge's .orig file with our resolve file
2990 # replace filemerge's .orig file with our resolve file
2989 util.rename(a + ".resolve", a + ".orig")
2991 util.rename(a + ".resolve", a + ".orig")
2990
2992
2991 ms.commit()
2993 ms.commit()
2992 return ret
2994 return ret
2993
2995
2994 def revert(ui, repo, *pats, **opts):
2996 def revert(ui, repo, *pats, **opts):
2995 """restore individual files or directories to an earlier state
2997 """restore individual files or directories to an earlier state
2996
2998
2997 .. note::
2999 .. note::
2998 This command is most likely not what you are looking for.
3000 This command is most likely not what you are looking for.
2999 revert will partially overwrite content in the working
3001 revert will partially overwrite content in the working
3000 directory without changing the working directory parents. Use
3002 directory without changing the working directory parents. Use
3001 :hg:`update -r rev` to check out earlier revisions, or
3003 :hg:`update -r rev` to check out earlier revisions, or
3002 :hg:`update --clean .` to undo a merge which has added another
3004 :hg:`update --clean .` to undo a merge which has added another
3003 parent.
3005 parent.
3004
3006
3005 With no revision specified, revert the named files or directories
3007 With no revision specified, revert the named files or directories
3006 to the contents they had in the parent of the working directory.
3008 to the contents they had in the parent of the working directory.
3007 This restores the contents of the affected files to an unmodified
3009 This restores the contents of the affected files to an unmodified
3008 state and unschedules adds, removes, copies, and renames. If the
3010 state and unschedules adds, removes, copies, and renames. If the
3009 working directory has two parents, you must explicitly specify a
3011 working directory has two parents, you must explicitly specify a
3010 revision.
3012 revision.
3011
3013
3012 Using the -r/--rev option, revert the given files or directories
3014 Using the -r/--rev option, revert the given files or directories
3013 to their contents as of a specific revision. This can be helpful
3015 to their contents as of a specific revision. This can be helpful
3014 to "roll back" some or all of an earlier change. See :hg:`help
3016 to "roll back" some or all of an earlier change. See :hg:`help
3015 dates` for a list of formats valid for -d/--date.
3017 dates` for a list of formats valid for -d/--date.
3016
3018
3017 Revert modifies the working directory. It does not commit any
3019 Revert modifies the working directory. It does not commit any
3018 changes, or change the parent of the working directory. If you
3020 changes, or change the parent of the working directory. If you
3019 revert to a revision other than the parent of the working
3021 revert to a revision other than the parent of the working
3020 directory, the reverted files will thus appear modified
3022 directory, the reverted files will thus appear modified
3021 afterwards.
3023 afterwards.
3022
3024
3023 If a file has been deleted, it is restored. If the executable mode
3025 If a file has been deleted, it is restored. If the executable mode
3024 of a file was changed, it is reset.
3026 of a file was changed, it is reset.
3025
3027
3026 If names are given, all files matching the names are reverted.
3028 If names are given, all files matching the names are reverted.
3027 If no arguments are given, no files are reverted.
3029 If no arguments are given, no files are reverted.
3028
3030
3029 Modified files are saved with a .orig suffix before reverting.
3031 Modified files are saved with a .orig suffix before reverting.
3030 To disable these backups, use --no-backup.
3032 To disable these backups, use --no-backup.
3031
3033
3032 Returns 0 on success.
3034 Returns 0 on success.
3033 """
3035 """
3034
3036
3035 if opts.get("date"):
3037 if opts.get("date"):
3036 if opts.get("rev"):
3038 if opts.get("rev"):
3037 raise util.Abort(_("you can't specify a revision and a date"))
3039 raise util.Abort(_("you can't specify a revision and a date"))
3038 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3040 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3039
3041
3040 if not pats and not opts.get('all'):
3042 if not pats and not opts.get('all'):
3041 raise util.Abort(_('no files or directories specified; '
3043 raise util.Abort(_('no files or directories specified; '
3042 'use --all to revert the whole repo'))
3044 'use --all to revert the whole repo'))
3043
3045
3044 parent, p2 = repo.dirstate.parents()
3046 parent, p2 = repo.dirstate.parents()
3045 if not opts.get('rev') and p2 != nullid:
3047 if not opts.get('rev') and p2 != nullid:
3046 raise util.Abort(_('uncommitted merge - please provide a '
3048 raise util.Abort(_('uncommitted merge - please provide a '
3047 'specific revision'))
3049 'specific revision'))
3048 ctx = repo[opts.get('rev')]
3050 ctx = repo[opts.get('rev')]
3049 node = ctx.node()
3051 node = ctx.node()
3050 mf = ctx.manifest()
3052 mf = ctx.manifest()
3051 if node == parent:
3053 if node == parent:
3052 pmf = mf
3054 pmf = mf
3053 else:
3055 else:
3054 pmf = None
3056 pmf = None
3055
3057
3056 # need all matching names in dirstate and manifest of target rev,
3058 # need all matching names in dirstate and manifest of target rev,
3057 # so have to walk both. do not print errors if files exist in one
3059 # so have to walk both. do not print errors if files exist in one
3058 # but not other.
3060 # but not other.
3059
3061
3060 names = {}
3062 names = {}
3061
3063
3062 wlock = repo.wlock()
3064 wlock = repo.wlock()
3063 try:
3065 try:
3064 # walk dirstate.
3066 # walk dirstate.
3065
3067
3066 m = cmdutil.match(repo, pats, opts)
3068 m = cmdutil.match(repo, pats, opts)
3067 m.bad = lambda x, y: False
3069 m.bad = lambda x, y: False
3068 for abs in repo.walk(m):
3070 for abs in repo.walk(m):
3069 names[abs] = m.rel(abs), m.exact(abs)
3071 names[abs] = m.rel(abs), m.exact(abs)
3070
3072
3071 # walk target manifest.
3073 # walk target manifest.
3072
3074
3073 def badfn(path, msg):
3075 def badfn(path, msg):
3074 if path in names:
3076 if path in names:
3075 return
3077 return
3076 path_ = path + '/'
3078 path_ = path + '/'
3077 for f in names:
3079 for f in names:
3078 if f.startswith(path_):
3080 if f.startswith(path_):
3079 return
3081 return
3080 ui.warn("%s: %s\n" % (m.rel(path), msg))
3082 ui.warn("%s: %s\n" % (m.rel(path), msg))
3081
3083
3082 m = cmdutil.match(repo, pats, opts)
3084 m = cmdutil.match(repo, pats, opts)
3083 m.bad = badfn
3085 m.bad = badfn
3084 for abs in repo[node].walk(m):
3086 for abs in repo[node].walk(m):
3085 if abs not in names:
3087 if abs not in names:
3086 names[abs] = m.rel(abs), m.exact(abs)
3088 names[abs] = m.rel(abs), m.exact(abs)
3087
3089
3088 m = cmdutil.matchfiles(repo, names)
3090 m = cmdutil.matchfiles(repo, names)
3089 changes = repo.status(match=m)[:4]
3091 changes = repo.status(match=m)[:4]
3090 modified, added, removed, deleted = map(set, changes)
3092 modified, added, removed, deleted = map(set, changes)
3091
3093
3092 # if f is a rename, also revert the source
3094 # if f is a rename, also revert the source
3093 cwd = repo.getcwd()
3095 cwd = repo.getcwd()
3094 for f in added:
3096 for f in added:
3095 src = repo.dirstate.copied(f)
3097 src = repo.dirstate.copied(f)
3096 if src and src not in names and repo.dirstate[src] == 'r':
3098 if src and src not in names and repo.dirstate[src] == 'r':
3097 removed.add(src)
3099 removed.add(src)
3098 names[src] = (repo.pathto(src, cwd), True)
3100 names[src] = (repo.pathto(src, cwd), True)
3099
3101
3100 def removeforget(abs):
3102 def removeforget(abs):
3101 if repo.dirstate[abs] == 'a':
3103 if repo.dirstate[abs] == 'a':
3102 return _('forgetting %s\n')
3104 return _('forgetting %s\n')
3103 return _('removing %s\n')
3105 return _('removing %s\n')
3104
3106
3105 revert = ([], _('reverting %s\n'))
3107 revert = ([], _('reverting %s\n'))
3106 add = ([], _('adding %s\n'))
3108 add = ([], _('adding %s\n'))
3107 remove = ([], removeforget)
3109 remove = ([], removeforget)
3108 undelete = ([], _('undeleting %s\n'))
3110 undelete = ([], _('undeleting %s\n'))
3109
3111
3110 disptable = (
3112 disptable = (
3111 # dispatch table:
3113 # dispatch table:
3112 # file state
3114 # file state
3113 # action if in target manifest
3115 # action if in target manifest
3114 # action if not in target manifest
3116 # action if not in target manifest
3115 # make backup if in target manifest
3117 # make backup if in target manifest
3116 # make backup if not in target manifest
3118 # make backup if not in target manifest
3117 (modified, revert, remove, True, True),
3119 (modified, revert, remove, True, True),
3118 (added, revert, remove, True, False),
3120 (added, revert, remove, True, False),
3119 (removed, undelete, None, False, False),
3121 (removed, undelete, None, False, False),
3120 (deleted, revert, remove, False, False),
3122 (deleted, revert, remove, False, False),
3121 )
3123 )
3122
3124
3123 for abs, (rel, exact) in sorted(names.items()):
3125 for abs, (rel, exact) in sorted(names.items()):
3124 mfentry = mf.get(abs)
3126 mfentry = mf.get(abs)
3125 target = repo.wjoin(abs)
3127 target = repo.wjoin(abs)
3126 def handle(xlist, dobackup):
3128 def handle(xlist, dobackup):
3127 xlist[0].append(abs)
3129 xlist[0].append(abs)
3128 if (dobackup and not opts.get('no_backup') and
3130 if (dobackup and not opts.get('no_backup') and
3129 os.path.lexists(target)):
3131 os.path.lexists(target)):
3130 bakname = "%s.orig" % rel
3132 bakname = "%s.orig" % rel
3131 ui.note(_('saving current version of %s as %s\n') %
3133 ui.note(_('saving current version of %s as %s\n') %
3132 (rel, bakname))
3134 (rel, bakname))
3133 if not opts.get('dry_run'):
3135 if not opts.get('dry_run'):
3134 util.rename(target, bakname)
3136 util.rename(target, bakname)
3135 if ui.verbose or not exact:
3137 if ui.verbose or not exact:
3136 msg = xlist[1]
3138 msg = xlist[1]
3137 if not isinstance(msg, basestring):
3139 if not isinstance(msg, basestring):
3138 msg = msg(abs)
3140 msg = msg(abs)
3139 ui.status(msg % rel)
3141 ui.status(msg % rel)
3140 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3142 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3141 if abs not in table:
3143 if abs not in table:
3142 continue
3144 continue
3143 # file has changed in dirstate
3145 # file has changed in dirstate
3144 if mfentry:
3146 if mfentry:
3145 handle(hitlist, backuphit)
3147 handle(hitlist, backuphit)
3146 elif misslist is not None:
3148 elif misslist is not None:
3147 handle(misslist, backupmiss)
3149 handle(misslist, backupmiss)
3148 break
3150 break
3149 else:
3151 else:
3150 if abs not in repo.dirstate:
3152 if abs not in repo.dirstate:
3151 if mfentry:
3153 if mfentry:
3152 handle(add, True)
3154 handle(add, True)
3153 elif exact:
3155 elif exact:
3154 ui.warn(_('file not managed: %s\n') % rel)
3156 ui.warn(_('file not managed: %s\n') % rel)
3155 continue
3157 continue
3156 # file has not changed in dirstate
3158 # file has not changed in dirstate
3157 if node == parent:
3159 if node == parent:
3158 if exact:
3160 if exact:
3159 ui.warn(_('no changes needed to %s\n') % rel)
3161 ui.warn(_('no changes needed to %s\n') % rel)
3160 continue
3162 continue
3161 if pmf is None:
3163 if pmf is None:
3162 # only need parent manifest in this unlikely case,
3164 # only need parent manifest in this unlikely case,
3163 # so do not read by default
3165 # so do not read by default
3164 pmf = repo[parent].manifest()
3166 pmf = repo[parent].manifest()
3165 if abs in pmf:
3167 if abs in pmf:
3166 if mfentry:
3168 if mfentry:
3167 # if version of file is same in parent and target
3169 # if version of file is same in parent and target
3168 # manifests, do nothing
3170 # manifests, do nothing
3169 if (pmf[abs] != mfentry or
3171 if (pmf[abs] != mfentry or
3170 pmf.flags(abs) != mf.flags(abs)):
3172 pmf.flags(abs) != mf.flags(abs)):
3171 handle(revert, False)
3173 handle(revert, False)
3172 else:
3174 else:
3173 handle(remove, False)
3175 handle(remove, False)
3174
3176
3175 if not opts.get('dry_run'):
3177 if not opts.get('dry_run'):
3176 def checkout(f):
3178 def checkout(f):
3177 fc = ctx[f]
3179 fc = ctx[f]
3178 repo.wwrite(f, fc.data(), fc.flags())
3180 repo.wwrite(f, fc.data(), fc.flags())
3179
3181
3180 audit_path = util.path_auditor(repo.root)
3182 audit_path = util.path_auditor(repo.root)
3181 for f in remove[0]:
3183 for f in remove[0]:
3182 if repo.dirstate[f] == 'a':
3184 if repo.dirstate[f] == 'a':
3183 repo.dirstate.forget(f)
3185 repo.dirstate.forget(f)
3184 continue
3186 continue
3185 audit_path(f)
3187 audit_path(f)
3186 try:
3188 try:
3187 util.unlink(repo.wjoin(f))
3189 util.unlink(repo.wjoin(f))
3188 except OSError:
3190 except OSError:
3189 pass
3191 pass
3190 repo.dirstate.remove(f)
3192 repo.dirstate.remove(f)
3191
3193
3192 normal = None
3194 normal = None
3193 if node == parent:
3195 if node == parent:
3194 # We're reverting to our parent. If possible, we'd like status
3196 # We're reverting to our parent. If possible, we'd like status
3195 # to report the file as clean. We have to use normallookup for
3197 # to report the file as clean. We have to use normallookup for
3196 # merges to avoid losing information about merged/dirty files.
3198 # merges to avoid losing information about merged/dirty files.
3197 if p2 != nullid:
3199 if p2 != nullid:
3198 normal = repo.dirstate.normallookup
3200 normal = repo.dirstate.normallookup
3199 else:
3201 else:
3200 normal = repo.dirstate.normal
3202 normal = repo.dirstate.normal
3201 for f in revert[0]:
3203 for f in revert[0]:
3202 checkout(f)
3204 checkout(f)
3203 if normal:
3205 if normal:
3204 normal(f)
3206 normal(f)
3205
3207
3206 for f in add[0]:
3208 for f in add[0]:
3207 checkout(f)
3209 checkout(f)
3208 repo.dirstate.add(f)
3210 repo.dirstate.add(f)
3209
3211
3210 normal = repo.dirstate.normallookup
3212 normal = repo.dirstate.normallookup
3211 if node == parent and p2 == nullid:
3213 if node == parent and p2 == nullid:
3212 normal = repo.dirstate.normal
3214 normal = repo.dirstate.normal
3213 for f in undelete[0]:
3215 for f in undelete[0]:
3214 checkout(f)
3216 checkout(f)
3215 normal(f)
3217 normal(f)
3216
3218
3217 finally:
3219 finally:
3218 wlock.release()
3220 wlock.release()
3219
3221
3220 def rollback(ui, repo, **opts):
3222 def rollback(ui, repo, **opts):
3221 """roll back the last transaction (dangerous)
3223 """roll back the last transaction (dangerous)
3222
3224
3223 This command should be used with care. There is only one level of
3225 This command should be used with care. There is only one level of
3224 rollback, and there is no way to undo a rollback. It will also
3226 rollback, and there is no way to undo a rollback. It will also
3225 restore the dirstate at the time of the last transaction, losing
3227 restore the dirstate at the time of the last transaction, losing
3226 any dirstate changes since that time. This command does not alter
3228 any dirstate changes since that time. This command does not alter
3227 the working directory.
3229 the working directory.
3228
3230
3229 Transactions are used to encapsulate the effects of all commands
3231 Transactions are used to encapsulate the effects of all commands
3230 that create new changesets or propagate existing changesets into a
3232 that create new changesets or propagate existing changesets into a
3231 repository. For example, the following commands are transactional,
3233 repository. For example, the following commands are transactional,
3232 and their effects can be rolled back:
3234 and their effects can be rolled back:
3233
3235
3234 - commit
3236 - commit
3235 - import
3237 - import
3236 - pull
3238 - pull
3237 - push (with this repository as the destination)
3239 - push (with this repository as the destination)
3238 - unbundle
3240 - unbundle
3239
3241
3240 This command is not intended for use on public repositories. Once
3242 This command is not intended for use on public repositories. Once
3241 changes are visible for pull by other users, rolling a transaction
3243 changes are visible for pull by other users, rolling a transaction
3242 back locally is ineffective (someone else may already have pulled
3244 back locally is ineffective (someone else may already have pulled
3243 the changes). Furthermore, a race is possible with readers of the
3245 the changes). Furthermore, a race is possible with readers of the
3244 repository; for example an in-progress pull from the repository
3246 repository; for example an in-progress pull from the repository
3245 may fail if a rollback is performed.
3247 may fail if a rollback is performed.
3246
3248
3247 Returns 0 on success, 1 if no rollback data is available.
3249 Returns 0 on success, 1 if no rollback data is available.
3248 """
3250 """
3249 return repo.rollback(opts.get('dry_run'))
3251 return repo.rollback(opts.get('dry_run'))
3250
3252
3251 def root(ui, repo):
3253 def root(ui, repo):
3252 """print the root (top) of the current working directory
3254 """print the root (top) of the current working directory
3253
3255
3254 Print the root directory of the current repository.
3256 Print the root directory of the current repository.
3255
3257
3256 Returns 0 on success.
3258 Returns 0 on success.
3257 """
3259 """
3258 ui.write(repo.root + "\n")
3260 ui.write(repo.root + "\n")
3259
3261
3260 def serve(ui, repo, **opts):
3262 def serve(ui, repo, **opts):
3261 """start stand-alone webserver
3263 """start stand-alone webserver
3262
3264
3263 Start a local HTTP repository browser and pull server. You can use
3265 Start a local HTTP repository browser and pull server. You can use
3264 this for ad-hoc sharing and browing of repositories. It is
3266 this for ad-hoc sharing and browing of repositories. It is
3265 recommended to use a real web server to serve a repository for
3267 recommended to use a real web server to serve a repository for
3266 longer periods of time.
3268 longer periods of time.
3267
3269
3268 Please note that the server does not implement access control.
3270 Please note that the server does not implement access control.
3269 This means that, by default, anybody can read from the server and
3271 This means that, by default, anybody can read from the server and
3270 nobody can write to it by default. Set the ``web.allow_push``
3272 nobody can write to it by default. Set the ``web.allow_push``
3271 option to ``*`` to allow everybody to push to the server. You
3273 option to ``*`` to allow everybody to push to the server. You
3272 should use a real web server if you need to authenticate users.
3274 should use a real web server if you need to authenticate users.
3273
3275
3274 By default, the server logs accesses to stdout and errors to
3276 By default, the server logs accesses to stdout and errors to
3275 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3277 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3276 files.
3278 files.
3277
3279
3278 To have the server choose a free port number to listen on, specify
3280 To have the server choose a free port number to listen on, specify
3279 a port number of 0; in this case, the server will print the port
3281 a port number of 0; in this case, the server will print the port
3280 number it uses.
3282 number it uses.
3281
3283
3282 Returns 0 on success.
3284 Returns 0 on success.
3283 """
3285 """
3284
3286
3285 if opts["stdio"]:
3287 if opts["stdio"]:
3286 if repo is None:
3288 if repo is None:
3287 raise error.RepoError(_("There is no Mercurial repository here"
3289 raise error.RepoError(_("There is no Mercurial repository here"
3288 " (.hg not found)"))
3290 " (.hg not found)"))
3289 s = sshserver.sshserver(ui, repo)
3291 s = sshserver.sshserver(ui, repo)
3290 s.serve_forever()
3292 s.serve_forever()
3291
3293
3292 # this way we can check if something was given in the command-line
3294 # this way we can check if something was given in the command-line
3293 if opts.get('port'):
3295 if opts.get('port'):
3294 opts['port'] = util.getport(opts.get('port'))
3296 opts['port'] = util.getport(opts.get('port'))
3295
3297
3296 baseui = repo and repo.baseui or ui
3298 baseui = repo and repo.baseui or ui
3297 optlist = ("name templates style address port prefix ipv6"
3299 optlist = ("name templates style address port prefix ipv6"
3298 " accesslog errorlog certificate encoding")
3300 " accesslog errorlog certificate encoding")
3299 for o in optlist.split():
3301 for o in optlist.split():
3300 val = opts.get(o, '')
3302 val = opts.get(o, '')
3301 if val in (None, ''): # should check against default options instead
3303 if val in (None, ''): # should check against default options instead
3302 continue
3304 continue
3303 baseui.setconfig("web", o, val)
3305 baseui.setconfig("web", o, val)
3304 if repo and repo.ui != baseui:
3306 if repo and repo.ui != baseui:
3305 repo.ui.setconfig("web", o, val)
3307 repo.ui.setconfig("web", o, val)
3306
3308
3307 o = opts.get('web_conf') or opts.get('webdir_conf')
3309 o = opts.get('web_conf') or opts.get('webdir_conf')
3308 if not o:
3310 if not o:
3309 if not repo:
3311 if not repo:
3310 raise error.RepoError(_("There is no Mercurial repository"
3312 raise error.RepoError(_("There is no Mercurial repository"
3311 " here (.hg not found)"))
3313 " here (.hg not found)"))
3312 o = repo.root
3314 o = repo.root
3313
3315
3314 app = hgweb.hgweb(o, baseui=ui)
3316 app = hgweb.hgweb(o, baseui=ui)
3315
3317
3316 class service(object):
3318 class service(object):
3317 def init(self):
3319 def init(self):
3318 util.set_signal_handler()
3320 util.set_signal_handler()
3319 self.httpd = hgweb.server.create_server(ui, app)
3321 self.httpd = hgweb.server.create_server(ui, app)
3320
3322
3321 if opts['port'] and not ui.verbose:
3323 if opts['port'] and not ui.verbose:
3322 return
3324 return
3323
3325
3324 if self.httpd.prefix:
3326 if self.httpd.prefix:
3325 prefix = self.httpd.prefix.strip('/') + '/'
3327 prefix = self.httpd.prefix.strip('/') + '/'
3326 else:
3328 else:
3327 prefix = ''
3329 prefix = ''
3328
3330
3329 port = ':%d' % self.httpd.port
3331 port = ':%d' % self.httpd.port
3330 if port == ':80':
3332 if port == ':80':
3331 port = ''
3333 port = ''
3332
3334
3333 bindaddr = self.httpd.addr
3335 bindaddr = self.httpd.addr
3334 if bindaddr == '0.0.0.0':
3336 if bindaddr == '0.0.0.0':
3335 bindaddr = '*'
3337 bindaddr = '*'
3336 elif ':' in bindaddr: # IPv6
3338 elif ':' in bindaddr: # IPv6
3337 bindaddr = '[%s]' % bindaddr
3339 bindaddr = '[%s]' % bindaddr
3338
3340
3339 fqaddr = self.httpd.fqaddr
3341 fqaddr = self.httpd.fqaddr
3340 if ':' in fqaddr:
3342 if ':' in fqaddr:
3341 fqaddr = '[%s]' % fqaddr
3343 fqaddr = '[%s]' % fqaddr
3342 if opts['port']:
3344 if opts['port']:
3343 write = ui.status
3345 write = ui.status
3344 else:
3346 else:
3345 write = ui.write
3347 write = ui.write
3346 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3348 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3347 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3349 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3348
3350
3349 def run(self):
3351 def run(self):
3350 self.httpd.serve_forever()
3352 self.httpd.serve_forever()
3351
3353
3352 service = service()
3354 service = service()
3353
3355
3354 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3356 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3355
3357
3356 def status(ui, repo, *pats, **opts):
3358 def status(ui, repo, *pats, **opts):
3357 """show changed files in the working directory
3359 """show changed files in the working directory
3358
3360
3359 Show status of files in the repository. If names are given, only
3361 Show status of files in the repository. If names are given, only
3360 files that match are shown. Files that are clean or ignored or
3362 files that match are shown. Files that are clean or ignored or
3361 the source of a copy/move operation, are not listed unless
3363 the source of a copy/move operation, are not listed unless
3362 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3364 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3363 Unless options described with "show only ..." are given, the
3365 Unless options described with "show only ..." are given, the
3364 options -mardu are used.
3366 options -mardu are used.
3365
3367
3366 Option -q/--quiet hides untracked (unknown and ignored) files
3368 Option -q/--quiet hides untracked (unknown and ignored) files
3367 unless explicitly requested with -u/--unknown or -i/--ignored.
3369 unless explicitly requested with -u/--unknown or -i/--ignored.
3368
3370
3369 .. note::
3371 .. note::
3370 status may appear to disagree with diff if permissions have
3372 status may appear to disagree with diff if permissions have
3371 changed or a merge has occurred. The standard diff format does
3373 changed or a merge has occurred. The standard diff format does
3372 not report permission changes and diff only reports changes
3374 not report permission changes and diff only reports changes
3373 relative to one merge parent.
3375 relative to one merge parent.
3374
3376
3375 If one revision is given, it is used as the base revision.
3377 If one revision is given, it is used as the base revision.
3376 If two revisions are given, the differences between them are
3378 If two revisions are given, the differences between them are
3377 shown. The --change option can also be used as a shortcut to list
3379 shown. The --change option can also be used as a shortcut to list
3378 the changed files of a revision from its first parent.
3380 the changed files of a revision from its first parent.
3379
3381
3380 The codes used to show the status of files are::
3382 The codes used to show the status of files are::
3381
3383
3382 M = modified
3384 M = modified
3383 A = added
3385 A = added
3384 R = removed
3386 R = removed
3385 C = clean
3387 C = clean
3386 ! = missing (deleted by non-hg command, but still tracked)
3388 ! = missing (deleted by non-hg command, but still tracked)
3387 ? = not tracked
3389 ? = not tracked
3388 I = ignored
3390 I = ignored
3389 = origin of the previous file listed as A (added)
3391 = origin of the previous file listed as A (added)
3390
3392
3391 Returns 0 on success.
3393 Returns 0 on success.
3392 """
3394 """
3393
3395
3394 revs = opts.get('rev')
3396 revs = opts.get('rev')
3395 change = opts.get('change')
3397 change = opts.get('change')
3396
3398
3397 if revs and change:
3399 if revs and change:
3398 msg = _('cannot specify --rev and --change at the same time')
3400 msg = _('cannot specify --rev and --change at the same time')
3399 raise util.Abort(msg)
3401 raise util.Abort(msg)
3400 elif change:
3402 elif change:
3401 node2 = repo.lookup(change)
3403 node2 = repo.lookup(change)
3402 node1 = repo[node2].parents()[0].node()
3404 node1 = repo[node2].parents()[0].node()
3403 else:
3405 else:
3404 node1, node2 = cmdutil.revpair(repo, revs)
3406 node1, node2 = cmdutil.revpair(repo, revs)
3405
3407
3406 cwd = (pats and repo.getcwd()) or ''
3408 cwd = (pats and repo.getcwd()) or ''
3407 end = opts.get('print0') and '\0' or '\n'
3409 end = opts.get('print0') and '\0' or '\n'
3408 copy = {}
3410 copy = {}
3409 states = 'modified added removed deleted unknown ignored clean'.split()
3411 states = 'modified added removed deleted unknown ignored clean'.split()
3410 show = [k for k in states if opts.get(k)]
3412 show = [k for k in states if opts.get(k)]
3411 if opts.get('all'):
3413 if opts.get('all'):
3412 show += ui.quiet and (states[:4] + ['clean']) or states
3414 show += ui.quiet and (states[:4] + ['clean']) or states
3413 if not show:
3415 if not show:
3414 show = ui.quiet and states[:4] or states[:5]
3416 show = ui.quiet and states[:4] or states[:5]
3415
3417
3416 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3418 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3417 'ignored' in show, 'clean' in show, 'unknown' in show,
3419 'ignored' in show, 'clean' in show, 'unknown' in show,
3418 opts.get('subrepos'))
3420 opts.get('subrepos'))
3419 changestates = zip(states, 'MAR!?IC', stat)
3421 changestates = zip(states, 'MAR!?IC', stat)
3420
3422
3421 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3423 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3422 ctxn = repo[nullid]
3424 ctxn = repo[nullid]
3423 ctx1 = repo[node1]
3425 ctx1 = repo[node1]
3424 ctx2 = repo[node2]
3426 ctx2 = repo[node2]
3425 added = stat[1]
3427 added = stat[1]
3426 if node2 is None:
3428 if node2 is None:
3427 added = stat[0] + stat[1] # merged?
3429 added = stat[0] + stat[1] # merged?
3428
3430
3429 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3431 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3430 if k in added:
3432 if k in added:
3431 copy[k] = v
3433 copy[k] = v
3432 elif v in added:
3434 elif v in added:
3433 copy[v] = k
3435 copy[v] = k
3434
3436
3435 for state, char, files in changestates:
3437 for state, char, files in changestates:
3436 if state in show:
3438 if state in show:
3437 format = "%s %%s%s" % (char, end)
3439 format = "%s %%s%s" % (char, end)
3438 if opts.get('no_status'):
3440 if opts.get('no_status'):
3439 format = "%%s%s" % end
3441 format = "%%s%s" % end
3440
3442
3441 for f in files:
3443 for f in files:
3442 ui.write(format % repo.pathto(f, cwd),
3444 ui.write(format % repo.pathto(f, cwd),
3443 label='status.' + state)
3445 label='status.' + state)
3444 if f in copy:
3446 if f in copy:
3445 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3447 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3446 label='status.copied')
3448 label='status.copied')
3447
3449
3448 def summary(ui, repo, **opts):
3450 def summary(ui, repo, **opts):
3449 """summarize working directory state
3451 """summarize working directory state
3450
3452
3451 This generates a brief summary of the working directory state,
3453 This generates a brief summary of the working directory state,
3452 including parents, branch, commit status, and available updates.
3454 including parents, branch, commit status, and available updates.
3453
3455
3454 With the --remote option, this will check the default paths for
3456 With the --remote option, this will check the default paths for
3455 incoming and outgoing changes. This can be time-consuming.
3457 incoming and outgoing changes. This can be time-consuming.
3456
3458
3457 Returns 0 on success.
3459 Returns 0 on success.
3458 """
3460 """
3459
3461
3460 ctx = repo[None]
3462 ctx = repo[None]
3461 parents = ctx.parents()
3463 parents = ctx.parents()
3462 pnode = parents[0].node()
3464 pnode = parents[0].node()
3463
3465
3464 for p in parents:
3466 for p in parents:
3465 # label with log.changeset (instead of log.parent) since this
3467 # label with log.changeset (instead of log.parent) since this
3466 # shows a working directory parent *changeset*:
3468 # shows a working directory parent *changeset*:
3467 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3469 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3468 label='log.changeset')
3470 label='log.changeset')
3469 ui.write(' '.join(p.tags()), label='log.tag')
3471 ui.write(' '.join(p.tags()), label='log.tag')
3470 if p.rev() == -1:
3472 if p.rev() == -1:
3471 if not len(repo):
3473 if not len(repo):
3472 ui.write(_(' (empty repository)'))
3474 ui.write(_(' (empty repository)'))
3473 else:
3475 else:
3474 ui.write(_(' (no revision checked out)'))
3476 ui.write(_(' (no revision checked out)'))
3475 ui.write('\n')
3477 ui.write('\n')
3476 if p.description():
3478 if p.description():
3477 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3479 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3478 label='log.summary')
3480 label='log.summary')
3479
3481
3480 branch = ctx.branch()
3482 branch = ctx.branch()
3481 bheads = repo.branchheads(branch)
3483 bheads = repo.branchheads(branch)
3482 m = _('branch: %s\n') % branch
3484 m = _('branch: %s\n') % branch
3483 if branch != 'default':
3485 if branch != 'default':
3484 ui.write(m, label='log.branch')
3486 ui.write(m, label='log.branch')
3485 else:
3487 else:
3486 ui.status(m, label='log.branch')
3488 ui.status(m, label='log.branch')
3487
3489
3488 st = list(repo.status(unknown=True))[:6]
3490 st = list(repo.status(unknown=True))[:6]
3489
3491
3490 c = repo.dirstate.copies()
3492 c = repo.dirstate.copies()
3491 copied, renamed = [], []
3493 copied, renamed = [], []
3492 for d, s in c.iteritems():
3494 for d, s in c.iteritems():
3493 if s in st[2]:
3495 if s in st[2]:
3494 st[2].remove(s)
3496 st[2].remove(s)
3495 renamed.append(d)
3497 renamed.append(d)
3496 else:
3498 else:
3497 copied.append(d)
3499 copied.append(d)
3498 if d in st[1]:
3500 if d in st[1]:
3499 st[1].remove(d)
3501 st[1].remove(d)
3500 st.insert(3, renamed)
3502 st.insert(3, renamed)
3501 st.insert(4, copied)
3503 st.insert(4, copied)
3502
3504
3503 ms = mergemod.mergestate(repo)
3505 ms = mergemod.mergestate(repo)
3504 st.append([f for f in ms if ms[f] == 'u'])
3506 st.append([f for f in ms if ms[f] == 'u'])
3505
3507
3506 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3508 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3507 st.append(subs)
3509 st.append(subs)
3508
3510
3509 labels = [ui.label(_('%d modified'), 'status.modified'),
3511 labels = [ui.label(_('%d modified'), 'status.modified'),
3510 ui.label(_('%d added'), 'status.added'),
3512 ui.label(_('%d added'), 'status.added'),
3511 ui.label(_('%d removed'), 'status.removed'),
3513 ui.label(_('%d removed'), 'status.removed'),
3512 ui.label(_('%d renamed'), 'status.copied'),
3514 ui.label(_('%d renamed'), 'status.copied'),
3513 ui.label(_('%d copied'), 'status.copied'),
3515 ui.label(_('%d copied'), 'status.copied'),
3514 ui.label(_('%d deleted'), 'status.deleted'),
3516 ui.label(_('%d deleted'), 'status.deleted'),
3515 ui.label(_('%d unknown'), 'status.unknown'),
3517 ui.label(_('%d unknown'), 'status.unknown'),
3516 ui.label(_('%d ignored'), 'status.ignored'),
3518 ui.label(_('%d ignored'), 'status.ignored'),
3517 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3519 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3518 ui.label(_('%d subrepos'), 'status.modified')]
3520 ui.label(_('%d subrepos'), 'status.modified')]
3519 t = []
3521 t = []
3520 for s, l in zip(st, labels):
3522 for s, l in zip(st, labels):
3521 if s:
3523 if s:
3522 t.append(l % len(s))
3524 t.append(l % len(s))
3523
3525
3524 t = ', '.join(t)
3526 t = ', '.join(t)
3525 cleanworkdir = False
3527 cleanworkdir = False
3526
3528
3527 if len(parents) > 1:
3529 if len(parents) > 1:
3528 t += _(' (merge)')
3530 t += _(' (merge)')
3529 elif branch != parents[0].branch():
3531 elif branch != parents[0].branch():
3530 t += _(' (new branch)')
3532 t += _(' (new branch)')
3531 elif (parents[0].extra().get('close') and
3533 elif (parents[0].extra().get('close') and
3532 pnode in repo.branchheads(branch, closed=True)):
3534 pnode in repo.branchheads(branch, closed=True)):
3533 t += _(' (head closed)')
3535 t += _(' (head closed)')
3534 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3536 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3535 t += _(' (clean)')
3537 t += _(' (clean)')
3536 cleanworkdir = True
3538 cleanworkdir = True
3537 elif pnode not in bheads:
3539 elif pnode not in bheads:
3538 t += _(' (new branch head)')
3540 t += _(' (new branch head)')
3539
3541
3540 if cleanworkdir:
3542 if cleanworkdir:
3541 ui.status(_('commit: %s\n') % t.strip())
3543 ui.status(_('commit: %s\n') % t.strip())
3542 else:
3544 else:
3543 ui.write(_('commit: %s\n') % t.strip())
3545 ui.write(_('commit: %s\n') % t.strip())
3544
3546
3545 # all ancestors of branch heads - all ancestors of parent = new csets
3547 # all ancestors of branch heads - all ancestors of parent = new csets
3546 new = [0] * len(repo)
3548 new = [0] * len(repo)
3547 cl = repo.changelog
3549 cl = repo.changelog
3548 for a in [cl.rev(n) for n in bheads]:
3550 for a in [cl.rev(n) for n in bheads]:
3549 new[a] = 1
3551 new[a] = 1
3550 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3552 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3551 new[a] = 1
3553 new[a] = 1
3552 for a in [p.rev() for p in parents]:
3554 for a in [p.rev() for p in parents]:
3553 if a >= 0:
3555 if a >= 0:
3554 new[a] = 0
3556 new[a] = 0
3555 for a in cl.ancestors(*[p.rev() for p in parents]):
3557 for a in cl.ancestors(*[p.rev() for p in parents]):
3556 new[a] = 0
3558 new[a] = 0
3557 new = sum(new)
3559 new = sum(new)
3558
3560
3559 if new == 0:
3561 if new == 0:
3560 ui.status(_('update: (current)\n'))
3562 ui.status(_('update: (current)\n'))
3561 elif pnode not in bheads:
3563 elif pnode not in bheads:
3562 ui.write(_('update: %d new changesets (update)\n') % new)
3564 ui.write(_('update: %d new changesets (update)\n') % new)
3563 else:
3565 else:
3564 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3566 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3565 (new, len(bheads)))
3567 (new, len(bheads)))
3566
3568
3567 if opts.get('remote'):
3569 if opts.get('remote'):
3568 t = []
3570 t = []
3569 source, branches = hg.parseurl(ui.expandpath('default'))
3571 source, branches = hg.parseurl(ui.expandpath('default'))
3570 other = hg.repository(hg.remoteui(repo, {}), source)
3572 other = hg.repository(hg.remoteui(repo, {}), source)
3571 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3573 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3572 ui.debug('comparing with %s\n' % url.hidepassword(source))
3574 ui.debug('comparing with %s\n' % url.hidepassword(source))
3573 repo.ui.pushbuffer()
3575 repo.ui.pushbuffer()
3574 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3576 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3575 repo.ui.popbuffer()
3577 repo.ui.popbuffer()
3576 if incoming:
3578 if incoming:
3577 t.append(_('1 or more incoming'))
3579 t.append(_('1 or more incoming'))
3578
3580
3579 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3581 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3580 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3582 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3581 other = hg.repository(hg.remoteui(repo, {}), dest)
3583 other = hg.repository(hg.remoteui(repo, {}), dest)
3582 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3584 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3583 repo.ui.pushbuffer()
3585 repo.ui.pushbuffer()
3584 o = discovery.findoutgoing(repo, other)
3586 o = discovery.findoutgoing(repo, other)
3585 repo.ui.popbuffer()
3587 repo.ui.popbuffer()
3586 o = repo.changelog.nodesbetween(o, None)[0]
3588 o = repo.changelog.nodesbetween(o, None)[0]
3587 if o:
3589 if o:
3588 t.append(_('%d outgoing') % len(o))
3590 t.append(_('%d outgoing') % len(o))
3589
3591
3590 if t:
3592 if t:
3591 ui.write(_('remote: %s\n') % (', '.join(t)))
3593 ui.write(_('remote: %s\n') % (', '.join(t)))
3592 else:
3594 else:
3593 ui.status(_('remote: (synced)\n'))
3595 ui.status(_('remote: (synced)\n'))
3594
3596
3595 def tag(ui, repo, name1, *names, **opts):
3597 def tag(ui, repo, name1, *names, **opts):
3596 """add one or more tags for the current or given revision
3598 """add one or more tags for the current or given revision
3597
3599
3598 Name a particular revision using <name>.
3600 Name a particular revision using <name>.
3599
3601
3600 Tags are used to name particular revisions of the repository and are
3602 Tags are used to name particular revisions of the repository and are
3601 very useful to compare different revisions, to go back to significant
3603 very useful to compare different revisions, to go back to significant
3602 earlier versions or to mark branch points as releases, etc.
3604 earlier versions or to mark branch points as releases, etc.
3603
3605
3604 If no revision is given, the parent of the working directory is
3606 If no revision is given, the parent of the working directory is
3605 used, or tip if no revision is checked out.
3607 used, or tip if no revision is checked out.
3606
3608
3607 To facilitate version control, distribution, and merging of tags,
3609 To facilitate version control, distribution, and merging of tags,
3608 they are stored as a file named ".hgtags" which is managed
3610 they are stored as a file named ".hgtags" which is managed
3609 similarly to other project files and can be hand-edited if
3611 similarly to other project files and can be hand-edited if
3610 necessary. The file '.hg/localtags' is used for local tags (not
3612 necessary. The file '.hg/localtags' is used for local tags (not
3611 shared among repositories).
3613 shared among repositories).
3612
3614
3613 See :hg:`help dates` for a list of formats valid for -d/--date.
3615 See :hg:`help dates` for a list of formats valid for -d/--date.
3614
3616
3615 Since tag names have priority over branch names during revision
3617 Since tag names have priority over branch names during revision
3616 lookup, using an existing branch name as a tag name is discouraged.
3618 lookup, using an existing branch name as a tag name is discouraged.
3617
3619
3618 Returns 0 on success.
3620 Returns 0 on success.
3619 """
3621 """
3620
3622
3621 rev_ = "."
3623 rev_ = "."
3622 names = [t.strip() for t in (name1,) + names]
3624 names = [t.strip() for t in (name1,) + names]
3623 if len(names) != len(set(names)):
3625 if len(names) != len(set(names)):
3624 raise util.Abort(_('tag names must be unique'))
3626 raise util.Abort(_('tag names must be unique'))
3625 for n in names:
3627 for n in names:
3626 if n in ['tip', '.', 'null']:
3628 if n in ['tip', '.', 'null']:
3627 raise util.Abort(_('the name \'%s\' is reserved') % n)
3629 raise util.Abort(_('the name \'%s\' is reserved') % n)
3628 if not n:
3630 if not n:
3629 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
3631 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
3630 if opts.get('rev') and opts.get('remove'):
3632 if opts.get('rev') and opts.get('remove'):
3631 raise util.Abort(_("--rev and --remove are incompatible"))
3633 raise util.Abort(_("--rev and --remove are incompatible"))
3632 if opts.get('rev'):
3634 if opts.get('rev'):
3633 rev_ = opts['rev']
3635 rev_ = opts['rev']
3634 message = opts.get('message')
3636 message = opts.get('message')
3635 if opts.get('remove'):
3637 if opts.get('remove'):
3636 expectedtype = opts.get('local') and 'local' or 'global'
3638 expectedtype = opts.get('local') and 'local' or 'global'
3637 for n in names:
3639 for n in names:
3638 if not repo.tagtype(n):
3640 if not repo.tagtype(n):
3639 raise util.Abort(_('tag \'%s\' does not exist') % n)
3641 raise util.Abort(_('tag \'%s\' does not exist') % n)
3640 if repo.tagtype(n) != expectedtype:
3642 if repo.tagtype(n) != expectedtype:
3641 if expectedtype == 'global':
3643 if expectedtype == 'global':
3642 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3644 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3643 else:
3645 else:
3644 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3646 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3645 rev_ = nullid
3647 rev_ = nullid
3646 if not message:
3648 if not message:
3647 # we don't translate commit messages
3649 # we don't translate commit messages
3648 message = 'Removed tag %s' % ', '.join(names)
3650 message = 'Removed tag %s' % ', '.join(names)
3649 elif not opts.get('force'):
3651 elif not opts.get('force'):
3650 for n in names:
3652 for n in names:
3651 if n in repo.tags():
3653 if n in repo.tags():
3652 raise util.Abort(_('tag \'%s\' already exists '
3654 raise util.Abort(_('tag \'%s\' already exists '
3653 '(use -f to force)') % n)
3655 '(use -f to force)') % n)
3654 if not rev_ and repo.dirstate.parents()[1] != nullid:
3656 if not rev_ and repo.dirstate.parents()[1] != nullid:
3655 raise util.Abort(_('uncommitted merge - please provide a '
3657 raise util.Abort(_('uncommitted merge - please provide a '
3656 'specific revision'))
3658 'specific revision'))
3657 r = repo[rev_].node()
3659 r = repo[rev_].node()
3658
3660
3659 if not message:
3661 if not message:
3660 # we don't translate commit messages
3662 # we don't translate commit messages
3661 message = ('Added tag %s for changeset %s' %
3663 message = ('Added tag %s for changeset %s' %
3662 (', '.join(names), short(r)))
3664 (', '.join(names), short(r)))
3663
3665
3664 date = opts.get('date')
3666 date = opts.get('date')
3665 if date:
3667 if date:
3666 date = util.parsedate(date)
3668 date = util.parsedate(date)
3667
3669
3668 if opts.get('edit'):
3670 if opts.get('edit'):
3669 message = ui.edit(message, ui.username())
3671 message = ui.edit(message, ui.username())
3670
3672
3671 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3673 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3672
3674
3673 def tags(ui, repo):
3675 def tags(ui, repo):
3674 """list repository tags
3676 """list repository tags
3675
3677
3676 This lists both regular and local tags. When the -v/--verbose
3678 This lists both regular and local tags. When the -v/--verbose
3677 switch is used, a third column "local" is printed for local tags.
3679 switch is used, a third column "local" is printed for local tags.
3678
3680
3679 Returns 0 on success.
3681 Returns 0 on success.
3680 """
3682 """
3681
3683
3682 hexfunc = ui.debugflag and hex or short
3684 hexfunc = ui.debugflag and hex or short
3683 tagtype = ""
3685 tagtype = ""
3684
3686
3685 for t, n in reversed(repo.tagslist()):
3687 for t, n in reversed(repo.tagslist()):
3686 if ui.quiet:
3688 if ui.quiet:
3687 ui.write("%s\n" % t)
3689 ui.write("%s\n" % t)
3688 continue
3690 continue
3689
3691
3690 try:
3692 try:
3691 hn = hexfunc(n)
3693 hn = hexfunc(n)
3692 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3694 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3693 except error.LookupError:
3695 except error.LookupError:
3694 r = " ?:%s" % hn
3696 r = " ?:%s" % hn
3695 else:
3697 else:
3696 spaces = " " * (30 - encoding.colwidth(t))
3698 spaces = " " * (30 - encoding.colwidth(t))
3697 if ui.verbose:
3699 if ui.verbose:
3698 if repo.tagtype(t) == 'local':
3700 if repo.tagtype(t) == 'local':
3699 tagtype = " local"
3701 tagtype = " local"
3700 else:
3702 else:
3701 tagtype = ""
3703 tagtype = ""
3702 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3704 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3703
3705
3704 def tip(ui, repo, **opts):
3706 def tip(ui, repo, **opts):
3705 """show the tip revision
3707 """show the tip revision
3706
3708
3707 The tip revision (usually just called the tip) is the changeset
3709 The tip revision (usually just called the tip) is the changeset
3708 most recently added to the repository (and therefore the most
3710 most recently added to the repository (and therefore the most
3709 recently changed head).
3711 recently changed head).
3710
3712
3711 If you have just made a commit, that commit will be the tip. If
3713 If you have just made a commit, that commit will be the tip. If
3712 you have just pulled changes from another repository, the tip of
3714 you have just pulled changes from another repository, the tip of
3713 that repository becomes the current tip. The "tip" tag is special
3715 that repository becomes the current tip. The "tip" tag is special
3714 and cannot be renamed or assigned to a different changeset.
3716 and cannot be renamed or assigned to a different changeset.
3715
3717
3716 Returns 0 on success.
3718 Returns 0 on success.
3717 """
3719 """
3718 displayer = cmdutil.show_changeset(ui, repo, opts)
3720 displayer = cmdutil.show_changeset(ui, repo, opts)
3719 displayer.show(repo[len(repo) - 1])
3721 displayer.show(repo[len(repo) - 1])
3720 displayer.close()
3722 displayer.close()
3721
3723
3722 def unbundle(ui, repo, fname1, *fnames, **opts):
3724 def unbundle(ui, repo, fname1, *fnames, **opts):
3723 """apply one or more changegroup files
3725 """apply one or more changegroup files
3724
3726
3725 Apply one or more compressed changegroup files generated by the
3727 Apply one or more compressed changegroup files generated by the
3726 bundle command.
3728 bundle command.
3727
3729
3728 Returns 0 on success, 1 if an update has unresolved files.
3730 Returns 0 on success, 1 if an update has unresolved files.
3729 """
3731 """
3730 fnames = (fname1,) + fnames
3732 fnames = (fname1,) + fnames
3731
3733
3732 lock = repo.lock()
3734 lock = repo.lock()
3733 try:
3735 try:
3734 for fname in fnames:
3736 for fname in fnames:
3735 f = url.open(ui, fname)
3737 f = url.open(ui, fname)
3736 gen = changegroup.readbundle(f, fname)
3738 gen = changegroup.readbundle(f, fname)
3737 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
3739 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
3738 lock=lock)
3740 lock=lock)
3739 finally:
3741 finally:
3740 lock.release()
3742 lock.release()
3741
3743
3742 return postincoming(ui, repo, modheads, opts.get('update'), None)
3744 return postincoming(ui, repo, modheads, opts.get('update'), None)
3743
3745
3744 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3746 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3745 """update working directory (or switch revisions)
3747 """update working directory (or switch revisions)
3746
3748
3747 Update the repository's working directory to the specified
3749 Update the repository's working directory to the specified
3748 changeset. If no changeset is specified, update to the tip of the
3750 changeset. If no changeset is specified, update to the tip of the
3749 current named branch.
3751 current named branch.
3750
3752
3751 If the changeset is not a descendant of the working directory's
3753 If the changeset is not a descendant of the working directory's
3752 parent, the update is aborted. With the -c/--check option, the
3754 parent, the update is aborted. With the -c/--check option, the
3753 working directory is checked for uncommitted changes; if none are
3755 working directory is checked for uncommitted changes; if none are
3754 found, the working directory is updated to the specified
3756 found, the working directory is updated to the specified
3755 changeset.
3757 changeset.
3756
3758
3757 The following rules apply when the working directory contains
3759 The following rules apply when the working directory contains
3758 uncommitted changes:
3760 uncommitted changes:
3759
3761
3760 1. If neither -c/--check nor -C/--clean is specified, and if
3762 1. If neither -c/--check nor -C/--clean is specified, and if
3761 the requested changeset is an ancestor or descendant of
3763 the requested changeset is an ancestor or descendant of
3762 the working directory's parent, the uncommitted changes
3764 the working directory's parent, the uncommitted changes
3763 are merged into the requested changeset and the merged
3765 are merged into the requested changeset and the merged
3764 result is left uncommitted. If the requested changeset is
3766 result is left uncommitted. If the requested changeset is
3765 not an ancestor or descendant (that is, it is on another
3767 not an ancestor or descendant (that is, it is on another
3766 branch), the update is aborted and the uncommitted changes
3768 branch), the update is aborted and the uncommitted changes
3767 are preserved.
3769 are preserved.
3768
3770
3769 2. With the -c/--check option, the update is aborted and the
3771 2. With the -c/--check option, the update is aborted and the
3770 uncommitted changes are preserved.
3772 uncommitted changes are preserved.
3771
3773
3772 3. With the -C/--clean option, uncommitted changes are discarded and
3774 3. With the -C/--clean option, uncommitted changes are discarded and
3773 the working directory is updated to the requested changeset.
3775 the working directory is updated to the requested changeset.
3774
3776
3775 Use null as the changeset to remove the working directory (like
3777 Use null as the changeset to remove the working directory (like
3776 :hg:`clone -U`).
3778 :hg:`clone -U`).
3777
3779
3778 If you want to update just one file to an older changeset, use
3780 If you want to update just one file to an older changeset, use
3779 :hg:`revert`.
3781 :hg:`revert`.
3780
3782
3781 See :hg:`help dates` for a list of formats valid for -d/--date.
3783 See :hg:`help dates` for a list of formats valid for -d/--date.
3782
3784
3783 Returns 0 on success, 1 if there are unresolved files.
3785 Returns 0 on success, 1 if there are unresolved files.
3784 """
3786 """
3785 if rev and node:
3787 if rev and node:
3786 raise util.Abort(_("please specify just one revision"))
3788 raise util.Abort(_("please specify just one revision"))
3787
3789
3788 if not rev:
3790 if not rev:
3789 rev = node
3791 rev = node
3790
3792
3791 if check and clean:
3793 if check and clean:
3792 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
3794 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
3793
3795
3794 if check:
3796 if check:
3795 # we could use dirty() but we can ignore merge and branch trivia
3797 # we could use dirty() but we can ignore merge and branch trivia
3796 c = repo[None]
3798 c = repo[None]
3797 if c.modified() or c.added() or c.removed():
3799 if c.modified() or c.added() or c.removed():
3798 raise util.Abort(_("uncommitted local changes"))
3800 raise util.Abort(_("uncommitted local changes"))
3799
3801
3800 if date:
3802 if date:
3801 if rev:
3803 if rev:
3802 raise util.Abort(_("you can't specify a revision and a date"))
3804 raise util.Abort(_("you can't specify a revision and a date"))
3803 rev = cmdutil.finddate(ui, repo, date)
3805 rev = cmdutil.finddate(ui, repo, date)
3804
3806
3805 if clean or check:
3807 if clean or check:
3806 return hg.clean(repo, rev)
3808 return hg.clean(repo, rev)
3807 else:
3809 else:
3808 return hg.update(repo, rev)
3810 return hg.update(repo, rev)
3809
3811
3810 def verify(ui, repo):
3812 def verify(ui, repo):
3811 """verify the integrity of the repository
3813 """verify the integrity of the repository
3812
3814
3813 Verify the integrity of the current repository.
3815 Verify the integrity of the current repository.
3814
3816
3815 This will perform an extensive check of the repository's
3817 This will perform an extensive check of the repository's
3816 integrity, validating the hashes and checksums of each entry in
3818 integrity, validating the hashes and checksums of each entry in
3817 the changelog, manifest, and tracked files, as well as the
3819 the changelog, manifest, and tracked files, as well as the
3818 integrity of their crosslinks and indices.
3820 integrity of their crosslinks and indices.
3819
3821
3820 Returns 0 on success, 1 if errors are encountered.
3822 Returns 0 on success, 1 if errors are encountered.
3821 """
3823 """
3822 return hg.verify(repo)
3824 return hg.verify(repo)
3823
3825
3824 def version_(ui):
3826 def version_(ui):
3825 """output version and copyright information"""
3827 """output version and copyright information"""
3826 ui.write(_("Mercurial Distributed SCM (version %s)\n")
3828 ui.write(_("Mercurial Distributed SCM (version %s)\n")
3827 % util.version())
3829 % util.version())
3828 ui.status(_(
3830 ui.status(_(
3829 "\nCopyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
3831 "\nCopyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
3830 "This is free software; see the source for copying conditions. "
3832 "This is free software; see the source for copying conditions. "
3831 "There is NO\nwarranty; "
3833 "There is NO\nwarranty; "
3832 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
3834 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
3833 ))
3835 ))
3834
3836
3835 # Command options and aliases are listed here, alphabetically
3837 # Command options and aliases are listed here, alphabetically
3836
3838
3837 globalopts = [
3839 globalopts = [
3838 ('R', 'repository', '',
3840 ('R', 'repository', '',
3839 _('repository root directory or name of overlay bundle file'),
3841 _('repository root directory or name of overlay bundle file'),
3840 _('REPO')),
3842 _('REPO')),
3841 ('', 'cwd', '',
3843 ('', 'cwd', '',
3842 _('change working directory'), _('DIR')),
3844 _('change working directory'), _('DIR')),
3843 ('y', 'noninteractive', None,
3845 ('y', 'noninteractive', None,
3844 _('do not prompt, assume \'yes\' for any required answers')),
3846 _('do not prompt, assume \'yes\' for any required answers')),
3845 ('q', 'quiet', None, _('suppress output')),
3847 ('q', 'quiet', None, _('suppress output')),
3846 ('v', 'verbose', None, _('enable additional output')),
3848 ('v', 'verbose', None, _('enable additional output')),
3847 ('', 'config', [],
3849 ('', 'config', [],
3848 _('set/override config option (use \'section.name=value\')'),
3850 _('set/override config option (use \'section.name=value\')'),
3849 _('CONFIG')),
3851 _('CONFIG')),
3850 ('', 'debug', None, _('enable debugging output')),
3852 ('', 'debug', None, _('enable debugging output')),
3851 ('', 'debugger', None, _('start debugger')),
3853 ('', 'debugger', None, _('start debugger')),
3852 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
3854 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
3853 _('ENCODE')),
3855 _('ENCODE')),
3854 ('', 'encodingmode', encoding.encodingmode,
3856 ('', 'encodingmode', encoding.encodingmode,
3855 _('set the charset encoding mode'), _('MODE')),
3857 _('set the charset encoding mode'), _('MODE')),
3856 ('', 'traceback', None, _('always print a traceback on exception')),
3858 ('', 'traceback', None, _('always print a traceback on exception')),
3857 ('', 'time', None, _('time how long the command takes')),
3859 ('', 'time', None, _('time how long the command takes')),
3858 ('', 'profile', None, _('print command execution profile')),
3860 ('', 'profile', None, _('print command execution profile')),
3859 ('', 'version', None, _('output version information and exit')),
3861 ('', 'version', None, _('output version information and exit')),
3860 ('h', 'help', None, _('display help and exit')),
3862 ('h', 'help', None, _('display help and exit')),
3861 ]
3863 ]
3862
3864
3863 dryrunopts = [('n', 'dry-run', None,
3865 dryrunopts = [('n', 'dry-run', None,
3864 _('do not perform actions, just print output'))]
3866 _('do not perform actions, just print output'))]
3865
3867
3866 remoteopts = [
3868 remoteopts = [
3867 ('e', 'ssh', '',
3869 ('e', 'ssh', '',
3868 _('specify ssh command to use'), _('CMD')),
3870 _('specify ssh command to use'), _('CMD')),
3869 ('', 'remotecmd', '',
3871 ('', 'remotecmd', '',
3870 _('specify hg command to run on the remote side'), _('CMD')),
3872 _('specify hg command to run on the remote side'), _('CMD')),
3871 ]
3873 ]
3872
3874
3873 walkopts = [
3875 walkopts = [
3874 ('I', 'include', [],
3876 ('I', 'include', [],
3875 _('include names matching the given patterns'), _('PATTERN')),
3877 _('include names matching the given patterns'), _('PATTERN')),
3876 ('X', 'exclude', [],
3878 ('X', 'exclude', [],
3877 _('exclude names matching the given patterns'), _('PATTERN')),
3879 _('exclude names matching the given patterns'), _('PATTERN')),
3878 ]
3880 ]
3879
3881
3880 commitopts = [
3882 commitopts = [
3881 ('m', 'message', '',
3883 ('m', 'message', '',
3882 _('use text as commit message'), _('TEXT')),
3884 _('use text as commit message'), _('TEXT')),
3883 ('l', 'logfile', '',
3885 ('l', 'logfile', '',
3884 _('read commit message from file'), _('FILE')),
3886 _('read commit message from file'), _('FILE')),
3885 ]
3887 ]
3886
3888
3887 commitopts2 = [
3889 commitopts2 = [
3888 ('d', 'date', '',
3890 ('d', 'date', '',
3889 _('record datecode as commit date'), _('DATE')),
3891 _('record datecode as commit date'), _('DATE')),
3890 ('u', 'user', '',
3892 ('u', 'user', '',
3891 _('record the specified user as committer'), _('USER')),
3893 _('record the specified user as committer'), _('USER')),
3892 ]
3894 ]
3893
3895
3894 templateopts = [
3896 templateopts = [
3895 ('', 'style', '',
3897 ('', 'style', '',
3896 _('display using template map file'), _('STYLE')),
3898 _('display using template map file'), _('STYLE')),
3897 ('', 'template', '',
3899 ('', 'template', '',
3898 _('display with template'), _('TEMPLATE')),
3900 _('display with template'), _('TEMPLATE')),
3899 ]
3901 ]
3900
3902
3901 logopts = [
3903 logopts = [
3902 ('p', 'patch', None, _('show patch')),
3904 ('p', 'patch', None, _('show patch')),
3903 ('g', 'git', None, _('use git extended diff format')),
3905 ('g', 'git', None, _('use git extended diff format')),
3904 ('l', 'limit', '',
3906 ('l', 'limit', '',
3905 _('limit number of changes displayed'), _('NUM')),
3907 _('limit number of changes displayed'), _('NUM')),
3906 ('M', 'no-merges', None, _('do not show merges')),
3908 ('M', 'no-merges', None, _('do not show merges')),
3907 ('', 'stat', None, _('output diffstat-style summary of changes')),
3909 ('', 'stat', None, _('output diffstat-style summary of changes')),
3908 ] + templateopts
3910 ] + templateopts
3909
3911
3910 diffopts = [
3912 diffopts = [
3911 ('a', 'text', None, _('treat all files as text')),
3913 ('a', 'text', None, _('treat all files as text')),
3912 ('g', 'git', None, _('use git extended diff format')),
3914 ('g', 'git', None, _('use git extended diff format')),
3913 ('', 'nodates', None, _('omit dates from diff headers'))
3915 ('', 'nodates', None, _('omit dates from diff headers'))
3914 ]
3916 ]
3915
3917
3916 diffopts2 = [
3918 diffopts2 = [
3917 ('p', 'show-function', None, _('show which function each change is in')),
3919 ('p', 'show-function', None, _('show which function each change is in')),
3918 ('', 'reverse', None, _('produce a diff that undoes the changes')),
3920 ('', 'reverse', None, _('produce a diff that undoes the changes')),
3919 ('w', 'ignore-all-space', None,
3921 ('w', 'ignore-all-space', None,
3920 _('ignore white space when comparing lines')),
3922 _('ignore white space when comparing lines')),
3921 ('b', 'ignore-space-change', None,
3923 ('b', 'ignore-space-change', None,
3922 _('ignore changes in the amount of white space')),
3924 _('ignore changes in the amount of white space')),
3923 ('B', 'ignore-blank-lines', None,
3925 ('B', 'ignore-blank-lines', None,
3924 _('ignore changes whose lines are all blank')),
3926 _('ignore changes whose lines are all blank')),
3925 ('U', 'unified', '',
3927 ('U', 'unified', '',
3926 _('number of lines of context to show'), _('NUM')),
3928 _('number of lines of context to show'), _('NUM')),
3927 ('', 'stat', None, _('output diffstat-style summary of changes')),
3929 ('', 'stat', None, _('output diffstat-style summary of changes')),
3928 ]
3930 ]
3929
3931
3930 similarityopts = [
3932 similarityopts = [
3931 ('s', 'similarity', '',
3933 ('s', 'similarity', '',
3932 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
3934 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
3933 ]
3935 ]
3934
3936
3935 subrepoopts = [
3937 subrepoopts = [
3936 ('S', 'subrepos', None,
3938 ('S', 'subrepos', None,
3937 _('recurse into subrepositories'))
3939 _('recurse into subrepositories'))
3938 ]
3940 ]
3939
3941
3940 table = {
3942 table = {
3941 "^add": (add, walkopts + subrepoopts + dryrunopts,
3943 "^add": (add, walkopts + subrepoopts + dryrunopts,
3942 _('[OPTION]... [FILE]...')),
3944 _('[OPTION]... [FILE]...')),
3943 "addremove":
3945 "addremove":
3944 (addremove, similarityopts + walkopts + dryrunopts,
3946 (addremove, similarityopts + walkopts + dryrunopts,
3945 _('[OPTION]... [FILE]...')),
3947 _('[OPTION]... [FILE]...')),
3946 "^annotate|blame":
3948 "^annotate|blame":
3947 (annotate,
3949 (annotate,
3948 [('r', 'rev', '',
3950 [('r', 'rev', '',
3949 _('annotate the specified revision'), _('REV')),
3951 _('annotate the specified revision'), _('REV')),
3950 ('', 'follow', None,
3952 ('', 'follow', None,
3951 _('follow copies/renames and list the filename (DEPRECATED)')),
3953 _('follow copies/renames and list the filename (DEPRECATED)')),
3952 ('', 'no-follow', None, _("don't follow copies and renames")),
3954 ('', 'no-follow', None, _("don't follow copies and renames")),
3953 ('a', 'text', None, _('treat all files as text')),
3955 ('a', 'text', None, _('treat all files as text')),
3954 ('u', 'user', None, _('list the author (long with -v)')),
3956 ('u', 'user', None, _('list the author (long with -v)')),
3955 ('f', 'file', None, _('list the filename')),
3957 ('f', 'file', None, _('list the filename')),
3956 ('d', 'date', None, _('list the date (short with -q)')),
3958 ('d', 'date', None, _('list the date (short with -q)')),
3957 ('n', 'number', None, _('list the revision number (default)')),
3959 ('n', 'number', None, _('list the revision number (default)')),
3958 ('c', 'changeset', None, _('list the changeset')),
3960 ('c', 'changeset', None, _('list the changeset')),
3959 ('l', 'line-number', None,
3961 ('l', 'line-number', None,
3960 _('show line number at the first appearance'))
3962 _('show line number at the first appearance'))
3961 ] + walkopts,
3963 ] + walkopts,
3962 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
3964 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
3963 "archive":
3965 "archive":
3964 (archive,
3966 (archive,
3965 [('', 'no-decode', None, _('do not pass files through decoders')),
3967 [('', 'no-decode', None, _('do not pass files through decoders')),
3966 ('p', 'prefix', '',
3968 ('p', 'prefix', '',
3967 _('directory prefix for files in archive'), _('PREFIX')),
3969 _('directory prefix for files in archive'), _('PREFIX')),
3968 ('r', 'rev', '',
3970 ('r', 'rev', '',
3969 _('revision to distribute'), _('REV')),
3971 _('revision to distribute'), _('REV')),
3970 ('t', 'type', '',
3972 ('t', 'type', '',
3971 _('type of distribution to create'), _('TYPE')),
3973 _('type of distribution to create'), _('TYPE')),
3972 ] + subrepoopts + walkopts,
3974 ] + subrepoopts + walkopts,
3973 _('[OPTION]... DEST')),
3975 _('[OPTION]... DEST')),
3974 "backout":
3976 "backout":
3975 (backout,
3977 (backout,
3976 [('', 'merge', None,
3978 [('', 'merge', None,
3977 _('merge with old dirstate parent after backout')),
3979 _('merge with old dirstate parent after backout')),
3978 ('', 'parent', '',
3980 ('', 'parent', '',
3979 _('parent to choose when backing out merge'), _('REV')),
3981 _('parent to choose when backing out merge'), _('REV')),
3980 ('r', 'rev', '',
3982 ('r', 'rev', '',
3981 _('revision to backout'), _('REV')),
3983 _('revision to backout'), _('REV')),
3982 ] + walkopts + commitopts + commitopts2,
3984 ] + walkopts + commitopts + commitopts2,
3983 _('[OPTION]... [-r] REV')),
3985 _('[OPTION]... [-r] REV')),
3984 "bisect":
3986 "bisect":
3985 (bisect,
3987 (bisect,
3986 [('r', 'reset', False, _('reset bisect state')),
3988 [('r', 'reset', False, _('reset bisect state')),
3987 ('g', 'good', False, _('mark changeset good')),
3989 ('g', 'good', False, _('mark changeset good')),
3988 ('b', 'bad', False, _('mark changeset bad')),
3990 ('b', 'bad', False, _('mark changeset bad')),
3989 ('s', 'skip', False, _('skip testing changeset')),
3991 ('s', 'skip', False, _('skip testing changeset')),
3990 ('c', 'command', '',
3992 ('c', 'command', '',
3991 _('use command to check changeset state'), _('CMD')),
3993 _('use command to check changeset state'), _('CMD')),
3992 ('U', 'noupdate', False, _('do not update to target'))],
3994 ('U', 'noupdate', False, _('do not update to target'))],
3993 _("[-gbsr] [-U] [-c CMD] [REV]")),
3995 _("[-gbsr] [-U] [-c CMD] [REV]")),
3994 "branch":
3996 "branch":
3995 (branch,
3997 (branch,
3996 [('f', 'force', None,
3998 [('f', 'force', None,
3997 _('set branch name even if it shadows an existing branch')),
3999 _('set branch name even if it shadows an existing branch')),
3998 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4000 ('C', 'clean', None, _('reset branch name to parent branch name'))],
3999 _('[-fC] [NAME]')),
4001 _('[-fC] [NAME]')),
4000 "branches":
4002 "branches":
4001 (branches,
4003 (branches,
4002 [('a', 'active', False,
4004 [('a', 'active', False,
4003 _('show only branches that have unmerged heads')),
4005 _('show only branches that have unmerged heads')),
4004 ('c', 'closed', False,
4006 ('c', 'closed', False,
4005 _('show normal and closed branches'))],
4007 _('show normal and closed branches'))],
4006 _('[-ac]')),
4008 _('[-ac]')),
4007 "bundle":
4009 "bundle":
4008 (bundle,
4010 (bundle,
4009 [('f', 'force', None,
4011 [('f', 'force', None,
4010 _('run even when the destination is unrelated')),
4012 _('run even when the destination is unrelated')),
4011 ('r', 'rev', [],
4013 ('r', 'rev', [],
4012 _('a changeset intended to be added to the destination'),
4014 _('a changeset intended to be added to the destination'),
4013 _('REV')),
4015 _('REV')),
4014 ('b', 'branch', [],
4016 ('b', 'branch', [],
4015 _('a specific branch you would like to bundle'),
4017 _('a specific branch you would like to bundle'),
4016 _('BRANCH')),
4018 _('BRANCH')),
4017 ('', 'base', [],
4019 ('', 'base', [],
4018 _('a base changeset assumed to be available at the destination'),
4020 _('a base changeset assumed to be available at the destination'),
4019 _('REV')),
4021 _('REV')),
4020 ('a', 'all', None, _('bundle all changesets in the repository')),
4022 ('a', 'all', None, _('bundle all changesets in the repository')),
4021 ('t', 'type', 'bzip2',
4023 ('t', 'type', 'bzip2',
4022 _('bundle compression type to use'), _('TYPE')),
4024 _('bundle compression type to use'), _('TYPE')),
4023 ] + remoteopts,
4025 ] + remoteopts,
4024 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4026 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4025 "cat":
4027 "cat":
4026 (cat,
4028 (cat,
4027 [('o', 'output', '',
4029 [('o', 'output', '',
4028 _('print output to file with formatted name'), _('FORMAT')),
4030 _('print output to file with formatted name'), _('FORMAT')),
4029 ('r', 'rev', '',
4031 ('r', 'rev', '',
4030 _('print the given revision'), _('REV')),
4032 _('print the given revision'), _('REV')),
4031 ('', 'decode', None, _('apply any matching decode filter')),
4033 ('', 'decode', None, _('apply any matching decode filter')),
4032 ] + walkopts,
4034 ] + walkopts,
4033 _('[OPTION]... FILE...')),
4035 _('[OPTION]... FILE...')),
4034 "^clone":
4036 "^clone":
4035 (clone,
4037 (clone,
4036 [('U', 'noupdate', None,
4038 [('U', 'noupdate', None,
4037 _('the clone will include an empty working copy (only a repository)')),
4039 _('the clone will include an empty working copy (only a repository)')),
4038 ('u', 'updaterev', '',
4040 ('u', 'updaterev', '',
4039 _('revision, tag or branch to check out'), _('REV')),
4041 _('revision, tag or branch to check out'), _('REV')),
4040 ('r', 'rev', [],
4042 ('r', 'rev', [],
4041 _('include the specified changeset'), _('REV')),
4043 _('include the specified changeset'), _('REV')),
4042 ('b', 'branch', [],
4044 ('b', 'branch', [],
4043 _('clone only the specified branch'), _('BRANCH')),
4045 _('clone only the specified branch'), _('BRANCH')),
4044 ('', 'pull', None, _('use pull protocol to copy metadata')),
4046 ('', 'pull', None, _('use pull protocol to copy metadata')),
4045 ('', 'uncompressed', None,
4047 ('', 'uncompressed', None,
4046 _('use uncompressed transfer (fast over LAN)')),
4048 _('use uncompressed transfer (fast over LAN)')),
4047 ] + remoteopts,
4049 ] + remoteopts,
4048 _('[OPTION]... SOURCE [DEST]')),
4050 _('[OPTION]... SOURCE [DEST]')),
4049 "^commit|ci":
4051 "^commit|ci":
4050 (commit,
4052 (commit,
4051 [('A', 'addremove', None,
4053 [('A', 'addremove', None,
4052 _('mark new/missing files as added/removed before committing')),
4054 _('mark new/missing files as added/removed before committing')),
4053 ('', 'close-branch', None,
4055 ('', 'close-branch', None,
4054 _('mark a branch as closed, hiding it from the branch list')),
4056 _('mark a branch as closed, hiding it from the branch list')),
4055 ] + walkopts + commitopts + commitopts2,
4057 ] + walkopts + commitopts + commitopts2,
4056 _('[OPTION]... [FILE]...')),
4058 _('[OPTION]... [FILE]...')),
4057 "copy|cp":
4059 "copy|cp":
4058 (copy,
4060 (copy,
4059 [('A', 'after', None, _('record a copy that has already occurred')),
4061 [('A', 'after', None, _('record a copy that has already occurred')),
4060 ('f', 'force', None,
4062 ('f', 'force', None,
4061 _('forcibly copy over an existing managed file')),
4063 _('forcibly copy over an existing managed file')),
4062 ] + walkopts + dryrunopts,
4064 ] + walkopts + dryrunopts,
4063 _('[OPTION]... [SOURCE]... DEST')),
4065 _('[OPTION]... [SOURCE]... DEST')),
4064 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4066 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4065 "debugbuilddag":
4067 "debugbuilddag":
4066 (debugbuilddag,
4068 (debugbuilddag,
4067 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4069 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4068 ('a', 'appended-file', None, _('add single file all revs append to')),
4070 ('a', 'appended-file', None, _('add single file all revs append to')),
4069 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4071 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4070 ('n', 'new-file', None, _('add new file at each rev')),
4072 ('n', 'new-file', None, _('add new file at each rev')),
4071 ],
4073 ],
4072 _('[OPTION]... TEXT')),
4074 _('[OPTION]... TEXT')),
4073 "debugcheckstate": (debugcheckstate, [], ''),
4075 "debugcheckstate": (debugcheckstate, [], ''),
4074 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4076 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4075 "debugcomplete":
4077 "debugcomplete":
4076 (debugcomplete,
4078 (debugcomplete,
4077 [('o', 'options', None, _('show the command options'))],
4079 [('o', 'options', None, _('show the command options'))],
4078 _('[-o] CMD')),
4080 _('[-o] CMD')),
4079 "debugdag":
4081 "debugdag":
4080 (debugdag,
4082 (debugdag,
4081 [('t', 'tags', None, _('use tags as labels')),
4083 [('t', 'tags', None, _('use tags as labels')),
4082 ('b', 'branches', None, _('annotate with branch names')),
4084 ('b', 'branches', None, _('annotate with branch names')),
4083 ('', 'dots', None, _('use dots for runs')),
4085 ('', 'dots', None, _('use dots for runs')),
4084 ('s', 'spaces', None, _('separate elements by spaces')),
4086 ('s', 'spaces', None, _('separate elements by spaces')),
4085 ],
4087 ],
4086 _('[OPTION]... [FILE [REV]...]')),
4088 _('[OPTION]... [FILE [REV]...]')),
4087 "debugdate":
4089 "debugdate":
4088 (debugdate,
4090 (debugdate,
4089 [('e', 'extended', None, _('try extended date formats'))],
4091 [('e', 'extended', None, _('try extended date formats'))],
4090 _('[-e] DATE [RANGE]')),
4092 _('[-e] DATE [RANGE]')),
4091 "debugdata": (debugdata, [], _('FILE REV')),
4093 "debugdata": (debugdata, [], _('FILE REV')),
4092 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4094 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4093 "debugindex": (debugindex, [], _('FILE')),
4095 "debugindex": (debugindex, [], _('FILE')),
4094 "debugindexdot": (debugindexdot, [], _('FILE')),
4096 "debugindexdot": (debugindexdot, [], _('FILE')),
4095 "debuginstall": (debuginstall, [], ''),
4097 "debuginstall": (debuginstall, [], ''),
4096 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4098 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4097 "debugrebuildstate":
4099 "debugrebuildstate":
4098 (debugrebuildstate,
4100 (debugrebuildstate,
4099 [('r', 'rev', '',
4101 [('r', 'rev', '',
4100 _('revision to rebuild to'), _('REV'))],
4102 _('revision to rebuild to'), _('REV'))],
4101 _('[-r REV] [REV]')),
4103 _('[-r REV] [REV]')),
4102 "debugrename":
4104 "debugrename":
4103 (debugrename,
4105 (debugrename,
4104 [('r', 'rev', '',
4106 [('r', 'rev', '',
4105 _('revision to debug'), _('REV'))],
4107 _('revision to debug'), _('REV'))],
4106 _('[-r REV] FILE')),
4108 _('[-r REV] FILE')),
4107 "debugrevspec":
4109 "debugrevspec":
4108 (debugrevspec, [], ('REVSPEC')),
4110 (debugrevspec, [], ('REVSPEC')),
4109 "debugsetparents":
4111 "debugsetparents":
4110 (debugsetparents, [], _('REV1 [REV2]')),
4112 (debugsetparents, [], _('REV1 [REV2]')),
4111 "debugstate":
4113 "debugstate":
4112 (debugstate,
4114 (debugstate,
4113 [('', 'nodates', None, _('do not display the saved mtime'))],
4115 [('', 'nodates', None, _('do not display the saved mtime'))],
4114 _('[OPTION]...')),
4116 _('[OPTION]...')),
4115 "debugsub":
4117 "debugsub":
4116 (debugsub,
4118 (debugsub,
4117 [('r', 'rev', '',
4119 [('r', 'rev', '',
4118 _('revision to check'), _('REV'))],
4120 _('revision to check'), _('REV'))],
4119 _('[-r REV] [REV]')),
4121 _('[-r REV] [REV]')),
4120 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4122 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4121 "^diff":
4123 "^diff":
4122 (diff,
4124 (diff,
4123 [('r', 'rev', [],
4125 [('r', 'rev', [],
4124 _('revision'), _('REV')),
4126 _('revision'), _('REV')),
4125 ('c', 'change', '',
4127 ('c', 'change', '',
4126 _('change made by revision'), _('REV'))
4128 _('change made by revision'), _('REV'))
4127 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4129 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4128 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4130 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4129 "^export":
4131 "^export":
4130 (export,
4132 (export,
4131 [('o', 'output', '',
4133 [('o', 'output', '',
4132 _('print output to file with formatted name'), _('FORMAT')),
4134 _('print output to file with formatted name'), _('FORMAT')),
4133 ('', 'switch-parent', None, _('diff against the second parent')),
4135 ('', 'switch-parent', None, _('diff against the second parent')),
4134 ('r', 'rev', [],
4136 ('r', 'rev', [],
4135 _('revisions to export'), _('REV')),
4137 _('revisions to export'), _('REV')),
4136 ] + diffopts,
4138 ] + diffopts,
4137 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4139 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4138 "^forget":
4140 "^forget":
4139 (forget,
4141 (forget,
4140 [] + walkopts,
4142 [] + walkopts,
4141 _('[OPTION]... FILE...')),
4143 _('[OPTION]... FILE...')),
4142 "grep":
4144 "grep":
4143 (grep,
4145 (grep,
4144 [('0', 'print0', None, _('end fields with NUL')),
4146 [('0', 'print0', None, _('end fields with NUL')),
4145 ('', 'all', None, _('print all revisions that match')),
4147 ('', 'all', None, _('print all revisions that match')),
4146 ('f', 'follow', None,
4148 ('f', 'follow', None,
4147 _('follow changeset history,'
4149 _('follow changeset history,'
4148 ' or file history across copies and renames')),
4150 ' or file history across copies and renames')),
4149 ('i', 'ignore-case', None, _('ignore case when matching')),
4151 ('i', 'ignore-case', None, _('ignore case when matching')),
4150 ('l', 'files-with-matches', None,
4152 ('l', 'files-with-matches', None,
4151 _('print only filenames and revisions that match')),
4153 _('print only filenames and revisions that match')),
4152 ('n', 'line-number', None, _('print matching line numbers')),
4154 ('n', 'line-number', None, _('print matching line numbers')),
4153 ('r', 'rev', [],
4155 ('r', 'rev', [],
4154 _('only search files changed within revision range'), _('REV')),
4156 _('only search files changed within revision range'), _('REV')),
4155 ('u', 'user', None, _('list the author (long with -v)')),
4157 ('u', 'user', None, _('list the author (long with -v)')),
4156 ('d', 'date', None, _('list the date (short with -q)')),
4158 ('d', 'date', None, _('list the date (short with -q)')),
4157 ] + walkopts,
4159 ] + walkopts,
4158 _('[OPTION]... PATTERN [FILE]...')),
4160 _('[OPTION]... PATTERN [FILE]...')),
4159 "heads":
4161 "heads":
4160 (heads,
4162 (heads,
4161 [('r', 'rev', '',
4163 [('r', 'rev', '',
4162 _('show only heads which are descendants of STARTREV'),
4164 _('show only heads which are descendants of STARTREV'),
4163 _('STARTREV')),
4165 _('STARTREV')),
4164 ('t', 'topo', False, _('show topological heads only')),
4166 ('t', 'topo', False, _('show topological heads only')),
4165 ('a', 'active', False,
4167 ('a', 'active', False,
4166 _('show active branchheads only (DEPRECATED)')),
4168 _('show active branchheads only (DEPRECATED)')),
4167 ('c', 'closed', False,
4169 ('c', 'closed', False,
4168 _('show normal and closed branch heads')),
4170 _('show normal and closed branch heads')),
4169 ] + templateopts,
4171 ] + templateopts,
4170 _('[-ac] [-r STARTREV] [REV]...')),
4172 _('[-ac] [-r STARTREV] [REV]...')),
4171 "help": (help_, [], _('[TOPIC]')),
4173 "help": (help_, [], _('[TOPIC]')),
4172 "identify|id":
4174 "identify|id":
4173 (identify,
4175 (identify,
4174 [('r', 'rev', '',
4176 [('r', 'rev', '',
4175 _('identify the specified revision'), _('REV')),
4177 _('identify the specified revision'), _('REV')),
4176 ('n', 'num', None, _('show local revision number')),
4178 ('n', 'num', None, _('show local revision number')),
4177 ('i', 'id', None, _('show global revision id')),
4179 ('i', 'id', None, _('show global revision id')),
4178 ('b', 'branch', None, _('show branch')),
4180 ('b', 'branch', None, _('show branch')),
4179 ('t', 'tags', None, _('show tags'))],
4181 ('t', 'tags', None, _('show tags'))],
4180 _('[-nibt] [-r REV] [SOURCE]')),
4182 _('[-nibt] [-r REV] [SOURCE]')),
4181 "import|patch":
4183 "import|patch":
4182 (import_,
4184 (import_,
4183 [('p', 'strip', 1,
4185 [('p', 'strip', 1,
4184 _('directory strip option for patch. This has the same '
4186 _('directory strip option for patch. This has the same '
4185 'meaning as the corresponding patch option'),
4187 'meaning as the corresponding patch option'),
4186 _('NUM')),
4188 _('NUM')),
4187 ('b', 'base', '',
4189 ('b', 'base', '',
4188 _('base path'), _('PATH')),
4190 _('base path'), _('PATH')),
4189 ('f', 'force', None,
4191 ('f', 'force', None,
4190 _('skip check for outstanding uncommitted changes')),
4192 _('skip check for outstanding uncommitted changes')),
4191 ('', 'no-commit', None,
4193 ('', 'no-commit', None,
4192 _("don't commit, just update the working directory")),
4194 _("don't commit, just update the working directory")),
4193 ('', 'exact', None,
4195 ('', 'exact', None,
4194 _('apply patch to the nodes from which it was generated')),
4196 _('apply patch to the nodes from which it was generated')),
4195 ('', 'import-branch', None,
4197 ('', 'import-branch', None,
4196 _('use any branch information in patch (implied by --exact)'))] +
4198 _('use any branch information in patch (implied by --exact)'))] +
4197 commitopts + commitopts2 + similarityopts,
4199 commitopts + commitopts2 + similarityopts,
4198 _('[OPTION]... PATCH...')),
4200 _('[OPTION]... PATCH...')),
4199 "incoming|in":
4201 "incoming|in":
4200 (incoming,
4202 (incoming,
4201 [('f', 'force', None,
4203 [('f', 'force', None,
4202 _('run even if remote repository is unrelated')),
4204 _('run even if remote repository is unrelated')),
4203 ('n', 'newest-first', None, _('show newest record first')),
4205 ('n', 'newest-first', None, _('show newest record first')),
4204 ('', 'bundle', '',
4206 ('', 'bundle', '',
4205 _('file to store the bundles into'), _('FILE')),
4207 _('file to store the bundles into'), _('FILE')),
4206 ('r', 'rev', [],
4208 ('r', 'rev', [],
4207 _('a remote changeset intended to be added'), _('REV')),
4209 _('a remote changeset intended to be added'), _('REV')),
4208 ('b', 'branch', [],
4210 ('b', 'branch', [],
4209 _('a specific branch you would like to pull'), _('BRANCH')),
4211 _('a specific branch you would like to pull'), _('BRANCH')),
4210 ] + logopts + remoteopts + subrepoopts,
4212 ] + logopts + remoteopts + subrepoopts,
4211 _('[-p] [-n] [-M] [-f] [-r REV]...'
4213 _('[-p] [-n] [-M] [-f] [-r REV]...'
4212 ' [--bundle FILENAME] [SOURCE]')),
4214 ' [--bundle FILENAME] [SOURCE]')),
4213 "^init":
4215 "^init":
4214 (init,
4216 (init,
4215 remoteopts,
4217 remoteopts,
4216 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4218 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4217 "locate":
4219 "locate":
4218 (locate,
4220 (locate,
4219 [('r', 'rev', '',
4221 [('r', 'rev', '',
4220 _('search the repository as it is in REV'), _('REV')),
4222 _('search the repository as it is in REV'), _('REV')),
4221 ('0', 'print0', None,
4223 ('0', 'print0', None,
4222 _('end filenames with NUL, for use with xargs')),
4224 _('end filenames with NUL, for use with xargs')),
4223 ('f', 'fullpath', None,
4225 ('f', 'fullpath', None,
4224 _('print complete paths from the filesystem root')),
4226 _('print complete paths from the filesystem root')),
4225 ] + walkopts,
4227 ] + walkopts,
4226 _('[OPTION]... [PATTERN]...')),
4228 _('[OPTION]... [PATTERN]...')),
4227 "^log|history":
4229 "^log|history":
4228 (log,
4230 (log,
4229 [('f', 'follow', None,
4231 [('f', 'follow', None,
4230 _('follow changeset history,'
4232 _('follow changeset history,'
4231 ' or file history across copies and renames')),
4233 ' or file history across copies and renames')),
4232 ('', 'follow-first', None,
4234 ('', 'follow-first', None,
4233 _('only follow the first parent of merge changesets')),
4235 _('only follow the first parent of merge changesets')),
4234 ('d', 'date', '',
4236 ('d', 'date', '',
4235 _('show revisions matching date spec'), _('DATE')),
4237 _('show revisions matching date spec'), _('DATE')),
4236 ('C', 'copies', None, _('show copied files')),
4238 ('C', 'copies', None, _('show copied files')),
4237 ('k', 'keyword', [],
4239 ('k', 'keyword', [],
4238 _('do case-insensitive search for a given text'), _('TEXT')),
4240 _('do case-insensitive search for a given text'), _('TEXT')),
4239 ('r', 'rev', [],
4241 ('r', 'rev', [],
4240 _('show the specified revision or range'), _('REV')),
4242 _('show the specified revision or range'), _('REV')),
4241 ('', 'removed', None, _('include revisions where files were removed')),
4243 ('', 'removed', None, _('include revisions where files were removed')),
4242 ('m', 'only-merges', None, _('show only merges')),
4244 ('m', 'only-merges', None, _('show only merges')),
4243 ('u', 'user', [],
4245 ('u', 'user', [],
4244 _('revisions committed by user'), _('USER')),
4246 _('revisions committed by user'), _('USER')),
4245 ('', 'only-branch', [],
4247 ('', 'only-branch', [],
4246 _('show only changesets within the given named branch (DEPRECATED)'),
4248 _('show only changesets within the given named branch (DEPRECATED)'),
4247 _('BRANCH')),
4249 _('BRANCH')),
4248 ('b', 'branch', [],
4250 ('b', 'branch', [],
4249 _('show changesets within the given named branch'), _('BRANCH')),
4251 _('show changesets within the given named branch'), _('BRANCH')),
4250 ('P', 'prune', [],
4252 ('P', 'prune', [],
4251 _('do not display revision or any of its ancestors'), _('REV')),
4253 _('do not display revision or any of its ancestors'), _('REV')),
4252 ] + logopts + walkopts,
4254 ] + logopts + walkopts,
4253 _('[OPTION]... [FILE]')),
4255 _('[OPTION]... [FILE]')),
4254 "manifest":
4256 "manifest":
4255 (manifest,
4257 (manifest,
4256 [('r', 'rev', '',
4258 [('r', 'rev', '',
4257 _('revision to display'), _('REV'))],
4259 _('revision to display'), _('REV'))],
4258 _('[-r REV]')),
4260 _('[-r REV]')),
4259 "^merge":
4261 "^merge":
4260 (merge,
4262 (merge,
4261 [('f', 'force', None, _('force a merge with outstanding changes')),
4263 [('f', 'force', None, _('force a merge with outstanding changes')),
4262 ('r', 'rev', '',
4264 ('r', 'rev', '',
4263 _('revision to merge'), _('REV')),
4265 _('revision to merge'), _('REV')),
4264 ('P', 'preview', None,
4266 ('P', 'preview', None,
4265 _('review revisions to merge (no merge is performed)'))],
4267 _('review revisions to merge (no merge is performed)'))],
4266 _('[-P] [-f] [[-r] REV]')),
4268 _('[-P] [-f] [[-r] REV]')),
4267 "outgoing|out":
4269 "outgoing|out":
4268 (outgoing,
4270 (outgoing,
4269 [('f', 'force', None,
4271 [('f', 'force', None,
4270 _('run even when the destination is unrelated')),
4272 _('run even when the destination is unrelated')),
4271 ('r', 'rev', [],
4273 ('r', 'rev', [],
4272 _('a changeset intended to be included in the destination'),
4274 _('a changeset intended to be included in the destination'),
4273 _('REV')),
4275 _('REV')),
4274 ('n', 'newest-first', None, _('show newest record first')),
4276 ('n', 'newest-first', None, _('show newest record first')),
4275 ('b', 'branch', [],
4277 ('b', 'branch', [],
4276 _('a specific branch you would like to push'), _('BRANCH')),
4278 _('a specific branch you would like to push'), _('BRANCH')),
4277 ] + logopts + remoteopts + subrepoopts,
4279 ] + logopts + remoteopts + subrepoopts,
4278 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4280 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4279 "parents":
4281 "parents":
4280 (parents,
4282 (parents,
4281 [('r', 'rev', '',
4283 [('r', 'rev', '',
4282 _('show parents of the specified revision'), _('REV')),
4284 _('show parents of the specified revision'), _('REV')),
4283 ] + templateopts,
4285 ] + templateopts,
4284 _('[-r REV] [FILE]')),
4286 _('[-r REV] [FILE]')),
4285 "paths": (paths, [], _('[NAME]')),
4287 "paths": (paths, [], _('[NAME]')),
4286 "^pull":
4288 "^pull":
4287 (pull,
4289 (pull,
4288 [('u', 'update', None,
4290 [('u', 'update', None,
4289 _('update to new branch head if changesets were pulled')),
4291 _('update to new branch head if changesets were pulled')),
4290 ('f', 'force', None,
4292 ('f', 'force', None,
4291 _('run even when remote repository is unrelated')),
4293 _('run even when remote repository is unrelated')),
4292 ('r', 'rev', [],
4294 ('r', 'rev', [],
4293 _('a remote changeset intended to be added'), _('REV')),
4295 _('a remote changeset intended to be added'), _('REV')),
4294 ('b', 'branch', [],
4296 ('b', 'branch', [],
4295 _('a specific branch you would like to pull'), _('BRANCH')),
4297 _('a specific branch you would like to pull'), _('BRANCH')),
4296 ] + remoteopts,
4298 ] + remoteopts,
4297 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4299 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4298 "^push":
4300 "^push":
4299 (push,
4301 (push,
4300 [('f', 'force', None, _('force push')),
4302 [('f', 'force', None, _('force push')),
4301 ('r', 'rev', [],
4303 ('r', 'rev', [],
4302 _('a changeset intended to be included in the destination'),
4304 _('a changeset intended to be included in the destination'),
4303 _('REV')),
4305 _('REV')),
4304 ('b', 'branch', [],
4306 ('b', 'branch', [],
4305 _('a specific branch you would like to push'), _('BRANCH')),
4307 _('a specific branch you would like to push'), _('BRANCH')),
4306 ('', 'new-branch', False, _('allow pushing a new branch')),
4308 ('', 'new-branch', False, _('allow pushing a new branch')),
4307 ] + remoteopts,
4309 ] + remoteopts,
4308 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4310 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4309 "recover": (recover, []),
4311 "recover": (recover, []),
4310 "^remove|rm":
4312 "^remove|rm":
4311 (remove,
4313 (remove,
4312 [('A', 'after', None, _('record delete for missing files')),
4314 [('A', 'after', None, _('record delete for missing files')),
4313 ('f', 'force', None,
4315 ('f', 'force', None,
4314 _('remove (and delete) file even if added or modified')),
4316 _('remove (and delete) file even if added or modified')),
4315 ] + walkopts,
4317 ] + walkopts,
4316 _('[OPTION]... FILE...')),
4318 _('[OPTION]... FILE...')),
4317 "rename|mv":
4319 "rename|mv":
4318 (rename,
4320 (rename,
4319 [('A', 'after', None, _('record a rename that has already occurred')),
4321 [('A', 'after', None, _('record a rename that has already occurred')),
4320 ('f', 'force', None,
4322 ('f', 'force', None,
4321 _('forcibly copy over an existing managed file')),
4323 _('forcibly copy over an existing managed file')),
4322 ] + walkopts + dryrunopts,
4324 ] + walkopts + dryrunopts,
4323 _('[OPTION]... SOURCE... DEST')),
4325 _('[OPTION]... SOURCE... DEST')),
4324 "resolve":
4326 "resolve":
4325 (resolve,
4327 (resolve,
4326 [('a', 'all', None, _('select all unresolved files')),
4328 [('a', 'all', None, _('select all unresolved files')),
4327 ('l', 'list', None, _('list state of files needing merge')),
4329 ('l', 'list', None, _('list state of files needing merge')),
4328 ('m', 'mark', None, _('mark files as resolved')),
4330 ('m', 'mark', None, _('mark files as resolved')),
4329 ('u', 'unmark', None, _('mark files as unresolved')),
4331 ('u', 'unmark', None, _('mark files as unresolved')),
4330 ('n', 'no-status', None, _('hide status prefix'))]
4332 ('n', 'no-status', None, _('hide status prefix'))]
4331 + walkopts,
4333 + walkopts,
4332 _('[OPTION]... [FILE]...')),
4334 _('[OPTION]... [FILE]...')),
4333 "revert":
4335 "revert":
4334 (revert,
4336 (revert,
4335 [('a', 'all', None, _('revert all changes when no arguments given')),
4337 [('a', 'all', None, _('revert all changes when no arguments given')),
4336 ('d', 'date', '',
4338 ('d', 'date', '',
4337 _('tipmost revision matching date'), _('DATE')),
4339 _('tipmost revision matching date'), _('DATE')),
4338 ('r', 'rev', '',
4340 ('r', 'rev', '',
4339 _('revert to the specified revision'), _('REV')),
4341 _('revert to the specified revision'), _('REV')),
4340 ('', 'no-backup', None, _('do not save backup copies of files')),
4342 ('', 'no-backup', None, _('do not save backup copies of files')),
4341 ] + walkopts + dryrunopts,
4343 ] + walkopts + dryrunopts,
4342 _('[OPTION]... [-r REV] [NAME]...')),
4344 _('[OPTION]... [-r REV] [NAME]...')),
4343 "rollback": (rollback, dryrunopts),
4345 "rollback": (rollback, dryrunopts),
4344 "root": (root, []),
4346 "root": (root, []),
4345 "^serve":
4347 "^serve":
4346 (serve,
4348 (serve,
4347 [('A', 'accesslog', '',
4349 [('A', 'accesslog', '',
4348 _('name of access log file to write to'), _('FILE')),
4350 _('name of access log file to write to'), _('FILE')),
4349 ('d', 'daemon', None, _('run server in background')),
4351 ('d', 'daemon', None, _('run server in background')),
4350 ('', 'daemon-pipefds', '',
4352 ('', 'daemon-pipefds', '',
4351 _('used internally by daemon mode'), _('NUM')),
4353 _('used internally by daemon mode'), _('NUM')),
4352 ('E', 'errorlog', '',
4354 ('E', 'errorlog', '',
4353 _('name of error log file to write to'), _('FILE')),
4355 _('name of error log file to write to'), _('FILE')),
4354 # use string type, then we can check if something was passed
4356 # use string type, then we can check if something was passed
4355 ('p', 'port', '',
4357 ('p', 'port', '',
4356 _('port to listen on (default: 8000)'), _('PORT')),
4358 _('port to listen on (default: 8000)'), _('PORT')),
4357 ('a', 'address', '',
4359 ('a', 'address', '',
4358 _('address to listen on (default: all interfaces)'), _('ADDR')),
4360 _('address to listen on (default: all interfaces)'), _('ADDR')),
4359 ('', 'prefix', '',
4361 ('', 'prefix', '',
4360 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4362 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4361 ('n', 'name', '',
4363 ('n', 'name', '',
4362 _('name to show in web pages (default: working directory)'),
4364 _('name to show in web pages (default: working directory)'),
4363 _('NAME')),
4365 _('NAME')),
4364 ('', 'web-conf', '',
4366 ('', 'web-conf', '',
4365 _('name of the hgweb config file (see "hg help hgweb")'),
4367 _('name of the hgweb config file (see "hg help hgweb")'),
4366 _('FILE')),
4368 _('FILE')),
4367 ('', 'webdir-conf', '',
4369 ('', 'webdir-conf', '',
4368 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4370 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4369 ('', 'pid-file', '',
4371 ('', 'pid-file', '',
4370 _('name of file to write process ID to'), _('FILE')),
4372 _('name of file to write process ID to'), _('FILE')),
4371 ('', 'stdio', None, _('for remote clients')),
4373 ('', 'stdio', None, _('for remote clients')),
4372 ('t', 'templates', '',
4374 ('t', 'templates', '',
4373 _('web templates to use'), _('TEMPLATE')),
4375 _('web templates to use'), _('TEMPLATE')),
4374 ('', 'style', '',
4376 ('', 'style', '',
4375 _('template style to use'), _('STYLE')),
4377 _('template style to use'), _('STYLE')),
4376 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4378 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4377 ('', 'certificate', '',
4379 ('', 'certificate', '',
4378 _('SSL certificate file'), _('FILE'))],
4380 _('SSL certificate file'), _('FILE'))],
4379 _('[OPTION]...')),
4381 _('[OPTION]...')),
4380 "showconfig|debugconfig":
4382 "showconfig|debugconfig":
4381 (showconfig,
4383 (showconfig,
4382 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4384 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4383 _('[-u] [NAME]...')),
4385 _('[-u] [NAME]...')),
4384 "^summary|sum":
4386 "^summary|sum":
4385 (summary,
4387 (summary,
4386 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4388 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4387 "^status|st":
4389 "^status|st":
4388 (status,
4390 (status,
4389 [('A', 'all', None, _('show status of all files')),
4391 [('A', 'all', None, _('show status of all files')),
4390 ('m', 'modified', None, _('show only modified files')),
4392 ('m', 'modified', None, _('show only modified files')),
4391 ('a', 'added', None, _('show only added files')),
4393 ('a', 'added', None, _('show only added files')),
4392 ('r', 'removed', None, _('show only removed files')),
4394 ('r', 'removed', None, _('show only removed files')),
4393 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4395 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4394 ('c', 'clean', None, _('show only files without changes')),
4396 ('c', 'clean', None, _('show only files without changes')),
4395 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4397 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4396 ('i', 'ignored', None, _('show only ignored files')),
4398 ('i', 'ignored', None, _('show only ignored files')),
4397 ('n', 'no-status', None, _('hide status prefix')),
4399 ('n', 'no-status', None, _('hide status prefix')),
4398 ('C', 'copies', None, _('show source of copied files')),
4400 ('C', 'copies', None, _('show source of copied files')),
4399 ('0', 'print0', None,
4401 ('0', 'print0', None,
4400 _('end filenames with NUL, for use with xargs')),
4402 _('end filenames with NUL, for use with xargs')),
4401 ('', 'rev', [],
4403 ('', 'rev', [],
4402 _('show difference from revision'), _('REV')),
4404 _('show difference from revision'), _('REV')),
4403 ('', 'change', '',
4405 ('', 'change', '',
4404 _('list the changed files of a revision'), _('REV')),
4406 _('list the changed files of a revision'), _('REV')),
4405 ] + walkopts + subrepoopts,
4407 ] + walkopts + subrepoopts,
4406 _('[OPTION]... [FILE]...')),
4408 _('[OPTION]... [FILE]...')),
4407 "tag":
4409 "tag":
4408 (tag,
4410 (tag,
4409 [('f', 'force', None, _('replace existing tag')),
4411 [('f', 'force', None, _('replace existing tag')),
4410 ('l', 'local', None, _('make the tag local')),
4412 ('l', 'local', None, _('make the tag local')),
4411 ('r', 'rev', '',
4413 ('r', 'rev', '',
4412 _('revision to tag'), _('REV')),
4414 _('revision to tag'), _('REV')),
4413 ('', 'remove', None, _('remove a tag')),
4415 ('', 'remove', None, _('remove a tag')),
4414 # -l/--local is already there, commitopts cannot be used
4416 # -l/--local is already there, commitopts cannot be used
4415 ('e', 'edit', None, _('edit commit message')),
4417 ('e', 'edit', None, _('edit commit message')),
4416 ('m', 'message', '',
4418 ('m', 'message', '',
4417 _('use <text> as commit message'), _('TEXT')),
4419 _('use <text> as commit message'), _('TEXT')),
4418 ] + commitopts2,
4420 ] + commitopts2,
4419 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4421 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4420 "tags": (tags, [], ''),
4422 "tags": (tags, [], ''),
4421 "tip":
4423 "tip":
4422 (tip,
4424 (tip,
4423 [('p', 'patch', None, _('show patch')),
4425 [('p', 'patch', None, _('show patch')),
4424 ('g', 'git', None, _('use git extended diff format')),
4426 ('g', 'git', None, _('use git extended diff format')),
4425 ] + templateopts,
4427 ] + templateopts,
4426 _('[-p] [-g]')),
4428 _('[-p] [-g]')),
4427 "unbundle":
4429 "unbundle":
4428 (unbundle,
4430 (unbundle,
4429 [('u', 'update', None,
4431 [('u', 'update', None,
4430 _('update to new branch head if changesets were unbundled'))],
4432 _('update to new branch head if changesets were unbundled'))],
4431 _('[-u] FILE...')),
4433 _('[-u] FILE...')),
4432 "^update|up|checkout|co":
4434 "^update|up|checkout|co":
4433 (update,
4435 (update,
4434 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4436 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4435 ('c', 'check', None,
4437 ('c', 'check', None,
4436 _('update across branches if no uncommitted changes')),
4438 _('update across branches if no uncommitted changes')),
4437 ('d', 'date', '',
4439 ('d', 'date', '',
4438 _('tipmost revision matching date'), _('DATE')),
4440 _('tipmost revision matching date'), _('DATE')),
4439 ('r', 'rev', '',
4441 ('r', 'rev', '',
4440 _('revision'), _('REV'))],
4442 _('revision'), _('REV'))],
4441 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4443 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4442 "verify": (verify, []),
4444 "verify": (verify, []),
4443 "version": (version_, []),
4445 "version": (version_, []),
4444 }
4446 }
4445
4447
4446 norepo = ("clone init version help debugcommands debugcomplete"
4448 norepo = ("clone init version help debugcommands debugcomplete"
4447 " debugdate debuginstall debugfsinfo debugpushkey")
4449 " debugdate debuginstall debugfsinfo debugpushkey")
4448 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
4450 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
4449 " debugdata debugindex debugindexdot")
4451 " debugdata debugindex debugindexdot")
@@ -1,119 +1,135 b''
1 Use hgrc within $TESTTMP
1 Use hgrc within $TESTTMP
2
2
3 $ HGRCPATH=`pwd`/hgrc
3 $ HGRCPATH=`pwd`/hgrc
4 $ export HGRCPATH
4 $ export HGRCPATH
5
5
6 Basic syntax error
6 Basic syntax error
7
7
8 $ echo "invalid" > $HGRCPATH
8 $ echo "invalid" > $HGRCPATH
9 $ hg version
9 $ hg version
10 hg: parse error at $TESTTMP/hgrc:1: invalid
10 hg: parse error at $TESTTMP/hgrc:1: invalid
11 [255]
11 [255]
12 $ echo "" > $HGRCPATH
12 $ echo "" > $HGRCPATH
13
13
14 Issue1199: Can't use '%' in hgrc (eg url encoded username)
14 Issue1199: Can't use '%' in hgrc (eg url encoded username)
15
15
16 $ hg init "foo%bar"
16 $ hg init "foo%bar"
17 $ hg clone "foo%bar" foobar
17 $ hg clone "foo%bar" foobar
18 updating to branch default
18 updating to branch default
19 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
19 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 $ cd foobar
20 $ cd foobar
21 $ cat .hg/hgrc
21 $ cat .hg/hgrc
22 [paths]
22 [paths]
23 default = */foo%bar (glob)
23 default = */foo%bar (glob)
24 $ hg paths
24 $ hg paths
25 default = */foo%bar (glob)
25 default = */foo%bar (glob)
26 $ hg showconfig
26 $ hg showconfig
27 bundle.mainreporoot=*/foobar (glob)
27 bundle.mainreporoot=*/foobar (glob)
28 paths.default=*/foo%bar (glob)
28 paths.default=*/foo%bar (glob)
29 $ cd ..
29 $ cd ..
30
30
31 issue1829: wrong indentation
31 issue1829: wrong indentation
32
32
33 $ echo '[foo]' > $HGRCPATH
33 $ echo '[foo]' > $HGRCPATH
34 $ echo ' x = y' >> $HGRCPATH
34 $ echo ' x = y' >> $HGRCPATH
35 $ hg version
35 $ hg version
36 hg: parse error at $TESTTMP/hgrc:2: x = y
36 hg: parse error at $TESTTMP/hgrc:2: x = y
37 [255]
37 [255]
38
38
39 $ python -c "print '[foo]\nbar = a\n b\n c \n de\n fg \nbaz = bif cb \n'" \
39 $ python -c "print '[foo]\nbar = a\n b\n c \n de\n fg \nbaz = bif cb \n'" \
40 > > $HGRCPATH
40 > > $HGRCPATH
41 $ hg showconfig foo
41 $ hg showconfig foo
42 foo.bar=a\nb\nc\nde\nfg
42 foo.bar=a\nb\nc\nde\nfg
43 foo.baz=bif cb
43 foo.baz=bif cb
44
44
45 $ FAKEPATH=/path/to/nowhere
45 $ FAKEPATH=/path/to/nowhere
46 $ export FAKEPATH
46 $ export FAKEPATH
47 $ echo '%include $FAKEPATH/no-such-file' > $HGRCPATH
47 $ echo '%include $FAKEPATH/no-such-file' > $HGRCPATH
48 $ hg version
48 $ hg version
49 hg: parse error at $TESTTMP/hgrc:1: cannot include /path/to/nowhere/no-such-file (No such file or directory)
49 hg: parse error at $TESTTMP/hgrc:1: cannot include /path/to/nowhere/no-such-file (No such file or directory)
50 [255]
50 [255]
51 $ unset FAKEPATH
51 $ unset FAKEPATH
52
52
53 username expansion
53 username expansion
54
54
55 $ olduser=$HGUSER
55 $ olduser=$HGUSER
56 $ unset HGUSER
56 $ unset HGUSER
57
57
58 $ FAKEUSER='John Doe'
58 $ FAKEUSER='John Doe'
59 $ export FAKEUSER
59 $ export FAKEUSER
60 $ echo '[ui]' > $HGRCPATH
60 $ echo '[ui]' > $HGRCPATH
61 $ echo 'username = $FAKEUSER' >> $HGRCPATH
61 $ echo 'username = $FAKEUSER' >> $HGRCPATH
62
62
63 $ hg init usertest
63 $ hg init usertest
64 $ cd usertest
64 $ cd usertest
65 $ touch bar
65 $ touch bar
66 $ hg commit --addremove --quiet -m "added bar"
66 $ hg commit --addremove --quiet -m "added bar"
67 $ hg log --template "{author}\n"
67 $ hg log --template "{author}\n"
68 John Doe
68 John Doe
69 $ cd ..
69 $ cd ..
70
70
71 $ hg showconfig
71 $ hg showconfig
72 ui.username=$FAKEUSER
72 ui.username=$FAKEUSER
73
73
74 $ unset FAKEUSER
74 $ unset FAKEUSER
75 $ HGUSER=$olduser
75 $ HGUSER=$olduser
76 $ export HGUSER
76 $ export HGUSER
77
77
78 showconfig with multiple arguments
79
80 $ echo "[alias]" > $HGRCPATH
81 $ echo "log = log -g" >> $HGRCPATH
82 $ echo "[defaults]" >> $HGRCPATH
83 $ echo "identify = -n" >> $HGRCPATH
84 $ hg showconfig alias defaults
85 alias.log=log -g
86 defaults.identify=-n
87 $ hg showconfig alias defaults.identify
88 abort: only one config item permitted
89 [255]
90 $ hg showconfig alias.log defaults.identify
91 abort: only one config item permitted
92 [255]
93
78 HGPLAIN
94 HGPLAIN
79
95
80 $ cd ..
96 $ cd ..
81 $ p=`pwd`
97 $ p=`pwd`
82 $ echo "[ui]" > $HGRCPATH
98 $ echo "[ui]" > $HGRCPATH
83 $ echo "debug=true" >> $HGRCPATH
99 $ echo "debug=true" >> $HGRCPATH
84 $ echo "fallbackencoding=ASCII" >> $HGRCPATH
100 $ echo "fallbackencoding=ASCII" >> $HGRCPATH
85 $ echo "quiet=true" >> $HGRCPATH
101 $ echo "quiet=true" >> $HGRCPATH
86 $ echo "slash=true" >> $HGRCPATH
102 $ echo "slash=true" >> $HGRCPATH
87 $ echo "traceback=true" >> $HGRCPATH
103 $ echo "traceback=true" >> $HGRCPATH
88 $ echo "verbose=true" >> $HGRCPATH
104 $ echo "verbose=true" >> $HGRCPATH
89 $ echo "style=~/.hgstyle" >> $HGRCPATH
105 $ echo "style=~/.hgstyle" >> $HGRCPATH
90 $ echo "logtemplate={node}" >> $HGRCPATH
106 $ echo "logtemplate={node}" >> $HGRCPATH
91 $ echo "[defaults]" >> $HGRCPATH
107 $ echo "[defaults]" >> $HGRCPATH
92 $ echo "identify=-n" >> $HGRCPATH
108 $ echo "identify=-n" >> $HGRCPATH
93 $ echo "[alias]" >> $HGRCPATH
109 $ echo "[alias]" >> $HGRCPATH
94 $ echo "log=log -g" >> $HGRCPATH
110 $ echo "log=log -g" >> $HGRCPATH
95
111
96 customized hgrc
112 customized hgrc
97
113
98 $ hg showconfig
114 $ hg showconfig
99 read config from: $TESTTMP/hgrc
115 read config from: $TESTTMP/hgrc
100 $TESTTMP/hgrc:13: alias.log=log -g
116 $TESTTMP/hgrc:13: alias.log=log -g
101 $TESTTMP/hgrc:11: defaults.identify=-n
117 $TESTTMP/hgrc:11: defaults.identify=-n
102 $TESTTMP/hgrc:2: ui.debug=true
118 $TESTTMP/hgrc:2: ui.debug=true
103 $TESTTMP/hgrc:3: ui.fallbackencoding=ASCII
119 $TESTTMP/hgrc:3: ui.fallbackencoding=ASCII
104 $TESTTMP/hgrc:4: ui.quiet=true
120 $TESTTMP/hgrc:4: ui.quiet=true
105 $TESTTMP/hgrc:5: ui.slash=true
121 $TESTTMP/hgrc:5: ui.slash=true
106 $TESTTMP/hgrc:6: ui.traceback=true
122 $TESTTMP/hgrc:6: ui.traceback=true
107 $TESTTMP/hgrc:7: ui.verbose=true
123 $TESTTMP/hgrc:7: ui.verbose=true
108 $TESTTMP/hgrc:8: ui.style=~/.hgstyle
124 $TESTTMP/hgrc:8: ui.style=~/.hgstyle
109 $TESTTMP/hgrc:9: ui.logtemplate={node}
125 $TESTTMP/hgrc:9: ui.logtemplate={node}
110
126
111 plain hgrc
127 plain hgrc
112
128
113 $ HGPLAIN=; export HGPLAIN
129 $ HGPLAIN=; export HGPLAIN
114 $ hg showconfig --config ui.traceback=True --debug
130 $ hg showconfig --config ui.traceback=True --debug
115 read config from: $TESTTMP/hgrc
131 read config from: $TESTTMP/hgrc
116 none: ui.traceback=True
132 none: ui.traceback=True
117 none: ui.verbose=False
133 none: ui.verbose=False
118 none: ui.debug=True
134 none: ui.debug=True
119 none: ui.quiet=False
135 none: ui.quiet=False
General Comments 0
You need to be logged in to leave comments. Login now