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