##// END OF EJS Templates
revert: Make it clearer when not to use revert
Mads Kiilerich -
r11459:59af1d65 stable
parent child Browse files
Show More
@@ -1,4452 +1,4455 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 debugpushkey(ui, repopath, namespace, *keyinfo):
1085 def debugpushkey(ui, repopath, namespace, *keyinfo):
1086 '''access the pushkey key/value protocol
1086 '''access the pushkey key/value protocol
1087
1087
1088 With two args, list the keys in the given namespace.
1088 With two args, list the keys in the given namespace.
1089
1089
1090 With five args, set a key to new if it currently is set to old.
1090 With five args, set a key to new if it currently is set to old.
1091 Reports success or failure.
1091 Reports success or failure.
1092 '''
1092 '''
1093
1093
1094 target = hg.repository(ui, repopath)
1094 target = hg.repository(ui, repopath)
1095 if keyinfo:
1095 if keyinfo:
1096 key, old, new = keyinfo
1096 key, old, new = keyinfo
1097 r = target.pushkey(namespace, key, old, new)
1097 r = target.pushkey(namespace, key, old, new)
1098 ui.status(str(r) + '\n')
1098 ui.status(str(r) + '\n')
1099 return not(r)
1099 return not(r)
1100 else:
1100 else:
1101 for k, v in target.listkeys(namespace).iteritems():
1101 for k, v in target.listkeys(namespace).iteritems():
1102 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1102 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1103 v.encode('string-escape')))
1103 v.encode('string-escape')))
1104
1104
1105 def debugrevspec(ui, repo, expr):
1105 def debugrevspec(ui, repo, expr):
1106 '''parse and apply a revision specification'''
1106 '''parse and apply a revision specification'''
1107 if ui.verbose:
1107 if ui.verbose:
1108 tree = revset.parse(expr)
1108 tree = revset.parse(expr)
1109 ui.note(tree, "\n")
1109 ui.note(tree, "\n")
1110 func = revset.match(expr)
1110 func = revset.match(expr)
1111 for c in func(repo, range(len(repo))):
1111 for c in func(repo, range(len(repo))):
1112 ui.write("%s\n" % c)
1112 ui.write("%s\n" % c)
1113
1113
1114 def debugsetparents(ui, repo, rev1, rev2=None):
1114 def debugsetparents(ui, repo, rev1, rev2=None):
1115 """manually set the parents of the current working directory
1115 """manually set the parents of the current working directory
1116
1116
1117 This is useful for writing repository conversion tools, but should
1117 This is useful for writing repository conversion tools, but should
1118 be used with care.
1118 be used with care.
1119
1119
1120 Returns 0 on success.
1120 Returns 0 on success.
1121 """
1121 """
1122
1122
1123 if not rev2:
1123 if not rev2:
1124 rev2 = hex(nullid)
1124 rev2 = hex(nullid)
1125
1125
1126 wlock = repo.wlock()
1126 wlock = repo.wlock()
1127 try:
1127 try:
1128 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
1128 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
1129 finally:
1129 finally:
1130 wlock.release()
1130 wlock.release()
1131
1131
1132 def debugstate(ui, repo, nodates=None):
1132 def debugstate(ui, repo, nodates=None):
1133 """show the contents of the current dirstate"""
1133 """show the contents of the current dirstate"""
1134 timestr = ""
1134 timestr = ""
1135 showdate = not nodates
1135 showdate = not nodates
1136 for file_, ent in sorted(repo.dirstate._map.iteritems()):
1136 for file_, ent in sorted(repo.dirstate._map.iteritems()):
1137 if showdate:
1137 if showdate:
1138 if ent[3] == -1:
1138 if ent[3] == -1:
1139 # Pad or slice to locale representation
1139 # Pad or slice to locale representation
1140 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1140 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1141 time.localtime(0)))
1141 time.localtime(0)))
1142 timestr = 'unset'
1142 timestr = 'unset'
1143 timestr = (timestr[:locale_len] +
1143 timestr = (timestr[:locale_len] +
1144 ' ' * (locale_len - len(timestr)))
1144 ' ' * (locale_len - len(timestr)))
1145 else:
1145 else:
1146 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1146 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1147 time.localtime(ent[3]))
1147 time.localtime(ent[3]))
1148 if ent[1] & 020000:
1148 if ent[1] & 020000:
1149 mode = 'lnk'
1149 mode = 'lnk'
1150 else:
1150 else:
1151 mode = '%3o' % (ent[1] & 0777)
1151 mode = '%3o' % (ent[1] & 0777)
1152 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1152 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1153 for f in repo.dirstate.copies():
1153 for f in repo.dirstate.copies():
1154 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1154 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1155
1155
1156 def debugsub(ui, repo, rev=None):
1156 def debugsub(ui, repo, rev=None):
1157 if rev == '':
1157 if rev == '':
1158 rev = None
1158 rev = None
1159 for k, v in sorted(repo[rev].substate.items()):
1159 for k, v in sorted(repo[rev].substate.items()):
1160 ui.write('path %s\n' % k)
1160 ui.write('path %s\n' % k)
1161 ui.write(' source %s\n' % v[0])
1161 ui.write(' source %s\n' % v[0])
1162 ui.write(' revision %s\n' % v[1])
1162 ui.write(' revision %s\n' % v[1])
1163
1163
1164 def debugdag(ui, repo, file_=None, *revs, **opts):
1164 def debugdag(ui, repo, file_=None, *revs, **opts):
1165 """format the changelog or an index DAG as a concise textual description
1165 """format the changelog or an index DAG as a concise textual description
1166
1166
1167 If you pass a revlog index, the revlog's DAG is emitted. If you list
1167 If you pass a revlog index, the revlog's DAG is emitted. If you list
1168 revision numbers, they get labelled in the output as rN.
1168 revision numbers, they get labelled in the output as rN.
1169
1169
1170 Otherwise, the changelog DAG of the current repo is emitted.
1170 Otherwise, the changelog DAG of the current repo is emitted.
1171 """
1171 """
1172 spaces = opts.get('spaces')
1172 spaces = opts.get('spaces')
1173 dots = opts.get('dots')
1173 dots = opts.get('dots')
1174 if file_:
1174 if file_:
1175 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1175 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1176 revs = set((int(r) for r in revs))
1176 revs = set((int(r) for r in revs))
1177 def events():
1177 def events():
1178 for r in rlog:
1178 for r in rlog:
1179 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1179 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1180 if r in revs:
1180 if r in revs:
1181 yield 'l', (r, "r%i" % r)
1181 yield 'l', (r, "r%i" % r)
1182 elif repo:
1182 elif repo:
1183 cl = repo.changelog
1183 cl = repo.changelog
1184 tags = opts.get('tags')
1184 tags = opts.get('tags')
1185 branches = opts.get('branches')
1185 branches = opts.get('branches')
1186 if tags:
1186 if tags:
1187 labels = {}
1187 labels = {}
1188 for l, n in repo.tags().items():
1188 for l, n in repo.tags().items():
1189 labels.setdefault(cl.rev(n), []).append(l)
1189 labels.setdefault(cl.rev(n), []).append(l)
1190 def events():
1190 def events():
1191 b = "default"
1191 b = "default"
1192 for r in cl:
1192 for r in cl:
1193 if branches:
1193 if branches:
1194 newb = cl.read(cl.node(r))[5]['branch']
1194 newb = cl.read(cl.node(r))[5]['branch']
1195 if newb != b:
1195 if newb != b:
1196 yield 'a', newb
1196 yield 'a', newb
1197 b = newb
1197 b = newb
1198 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1198 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1199 if tags:
1199 if tags:
1200 ls = labels.get(r)
1200 ls = labels.get(r)
1201 if ls:
1201 if ls:
1202 for l in ls:
1202 for l in ls:
1203 yield 'l', (r, l)
1203 yield 'l', (r, l)
1204 else:
1204 else:
1205 raise util.Abort(_('need repo for changelog dag'))
1205 raise util.Abort(_('need repo for changelog dag'))
1206
1206
1207 for line in dagparser.dagtextlines(events(),
1207 for line in dagparser.dagtextlines(events(),
1208 addspaces=spaces,
1208 addspaces=spaces,
1209 wraplabels=True,
1209 wraplabels=True,
1210 wrapannotations=True,
1210 wrapannotations=True,
1211 wrapnonlinear=dots,
1211 wrapnonlinear=dots,
1212 usedots=dots,
1212 usedots=dots,
1213 maxlinewidth=70):
1213 maxlinewidth=70):
1214 ui.write(line)
1214 ui.write(line)
1215 ui.write("\n")
1215 ui.write("\n")
1216
1216
1217 def debugdata(ui, file_, rev):
1217 def debugdata(ui, file_, rev):
1218 """dump the contents of a data file revision"""
1218 """dump the contents of a data file revision"""
1219 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1219 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1220 try:
1220 try:
1221 ui.write(r.revision(r.lookup(rev)))
1221 ui.write(r.revision(r.lookup(rev)))
1222 except KeyError:
1222 except KeyError:
1223 raise util.Abort(_('invalid revision identifier %s') % rev)
1223 raise util.Abort(_('invalid revision identifier %s') % rev)
1224
1224
1225 def debugdate(ui, date, range=None, **opts):
1225 def debugdate(ui, date, range=None, **opts):
1226 """parse and display a date"""
1226 """parse and display a date"""
1227 if opts["extended"]:
1227 if opts["extended"]:
1228 d = util.parsedate(date, util.extendeddateformats)
1228 d = util.parsedate(date, util.extendeddateformats)
1229 else:
1229 else:
1230 d = util.parsedate(date)
1230 d = util.parsedate(date)
1231 ui.write("internal: %s %s\n" % d)
1231 ui.write("internal: %s %s\n" % d)
1232 ui.write("standard: %s\n" % util.datestr(d))
1232 ui.write("standard: %s\n" % util.datestr(d))
1233 if range:
1233 if range:
1234 m = util.matchdate(range)
1234 m = util.matchdate(range)
1235 ui.write("match: %s\n" % m(d[0]))
1235 ui.write("match: %s\n" % m(d[0]))
1236
1236
1237 def debugindex(ui, file_):
1237 def debugindex(ui, file_):
1238 """dump the contents of an index file"""
1238 """dump the contents of an index file"""
1239 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1239 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1240 ui.write(" rev offset length base linkrev"
1240 ui.write(" rev offset length base linkrev"
1241 " nodeid p1 p2\n")
1241 " nodeid p1 p2\n")
1242 for i in r:
1242 for i in r:
1243 node = r.node(i)
1243 node = r.node(i)
1244 try:
1244 try:
1245 pp = r.parents(node)
1245 pp = r.parents(node)
1246 except:
1246 except:
1247 pp = [nullid, nullid]
1247 pp = [nullid, nullid]
1248 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1248 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1249 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1249 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1250 short(node), short(pp[0]), short(pp[1])))
1250 short(node), short(pp[0]), short(pp[1])))
1251
1251
1252 def debugindexdot(ui, file_):
1252 def debugindexdot(ui, file_):
1253 """dump an index DAG as a graphviz dot file"""
1253 """dump an index DAG as a graphviz dot file"""
1254 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1254 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1255 ui.write("digraph G {\n")
1255 ui.write("digraph G {\n")
1256 for i in r:
1256 for i in r:
1257 node = r.node(i)
1257 node = r.node(i)
1258 pp = r.parents(node)
1258 pp = r.parents(node)
1259 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1259 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1260 if pp[1] != nullid:
1260 if pp[1] != nullid:
1261 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1261 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1262 ui.write("}\n")
1262 ui.write("}\n")
1263
1263
1264 def debuginstall(ui):
1264 def debuginstall(ui):
1265 '''test Mercurial installation
1265 '''test Mercurial installation
1266
1266
1267 Returns 0 on success.
1267 Returns 0 on success.
1268 '''
1268 '''
1269
1269
1270 def writetemp(contents):
1270 def writetemp(contents):
1271 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1271 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1272 f = os.fdopen(fd, "wb")
1272 f = os.fdopen(fd, "wb")
1273 f.write(contents)
1273 f.write(contents)
1274 f.close()
1274 f.close()
1275 return name
1275 return name
1276
1276
1277 problems = 0
1277 problems = 0
1278
1278
1279 # encoding
1279 # encoding
1280 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1280 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1281 try:
1281 try:
1282 encoding.fromlocal("test")
1282 encoding.fromlocal("test")
1283 except util.Abort, inst:
1283 except util.Abort, inst:
1284 ui.write(" %s\n" % inst)
1284 ui.write(" %s\n" % inst)
1285 ui.write(_(" (check that your locale is properly set)\n"))
1285 ui.write(_(" (check that your locale is properly set)\n"))
1286 problems += 1
1286 problems += 1
1287
1287
1288 # compiled modules
1288 # compiled modules
1289 ui.status(_("Checking extensions...\n"))
1289 ui.status(_("Checking extensions...\n"))
1290 try:
1290 try:
1291 import bdiff, mpatch, base85
1291 import bdiff, mpatch, base85
1292 except Exception, inst:
1292 except Exception, inst:
1293 ui.write(" %s\n" % inst)
1293 ui.write(" %s\n" % inst)
1294 ui.write(_(" One or more extensions could not be found"))
1294 ui.write(_(" One or more extensions could not be found"))
1295 ui.write(_(" (check that you compiled the extensions)\n"))
1295 ui.write(_(" (check that you compiled the extensions)\n"))
1296 problems += 1
1296 problems += 1
1297
1297
1298 # templates
1298 # templates
1299 ui.status(_("Checking templates...\n"))
1299 ui.status(_("Checking templates...\n"))
1300 try:
1300 try:
1301 import templater
1301 import templater
1302 templater.templater(templater.templatepath("map-cmdline.default"))
1302 templater.templater(templater.templatepath("map-cmdline.default"))
1303 except Exception, inst:
1303 except Exception, inst:
1304 ui.write(" %s\n" % inst)
1304 ui.write(" %s\n" % inst)
1305 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1305 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1306 problems += 1
1306 problems += 1
1307
1307
1308 # patch
1308 # patch
1309 ui.status(_("Checking patch...\n"))
1309 ui.status(_("Checking patch...\n"))
1310 patchproblems = 0
1310 patchproblems = 0
1311 a = "1\n2\n3\n4\n"
1311 a = "1\n2\n3\n4\n"
1312 b = "1\n2\n3\ninsert\n4\n"
1312 b = "1\n2\n3\ninsert\n4\n"
1313 fa = writetemp(a)
1313 fa = writetemp(a)
1314 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
1314 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
1315 os.path.basename(fa))
1315 os.path.basename(fa))
1316 fd = writetemp(d)
1316 fd = writetemp(d)
1317
1317
1318 files = {}
1318 files = {}
1319 try:
1319 try:
1320 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
1320 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
1321 except util.Abort, e:
1321 except util.Abort, e:
1322 ui.write(_(" patch call failed:\n"))
1322 ui.write(_(" patch call failed:\n"))
1323 ui.write(" " + str(e) + "\n")
1323 ui.write(" " + str(e) + "\n")
1324 patchproblems += 1
1324 patchproblems += 1
1325 else:
1325 else:
1326 if list(files) != [os.path.basename(fa)]:
1326 if list(files) != [os.path.basename(fa)]:
1327 ui.write(_(" unexpected patch output!\n"))
1327 ui.write(_(" unexpected patch output!\n"))
1328 patchproblems += 1
1328 patchproblems += 1
1329 a = open(fa).read()
1329 a = open(fa).read()
1330 if a != b:
1330 if a != b:
1331 ui.write(_(" patch test failed!\n"))
1331 ui.write(_(" patch test failed!\n"))
1332 patchproblems += 1
1332 patchproblems += 1
1333
1333
1334 if patchproblems:
1334 if patchproblems:
1335 if ui.config('ui', 'patch'):
1335 if ui.config('ui', 'patch'):
1336 ui.write(_(" (Current patch tool may be incompatible with patch,"
1336 ui.write(_(" (Current patch tool may be incompatible with patch,"
1337 " or misconfigured. Please check your .hgrc file)\n"))
1337 " or misconfigured. Please check your .hgrc file)\n"))
1338 else:
1338 else:
1339 ui.write(_(" Internal patcher failure, please report this error"
1339 ui.write(_(" Internal patcher failure, please report this error"
1340 " to http://mercurial.selenic.com/bts/\n"))
1340 " to http://mercurial.selenic.com/bts/\n"))
1341 problems += patchproblems
1341 problems += patchproblems
1342
1342
1343 os.unlink(fa)
1343 os.unlink(fa)
1344 os.unlink(fd)
1344 os.unlink(fd)
1345
1345
1346 # editor
1346 # editor
1347 ui.status(_("Checking commit editor...\n"))
1347 ui.status(_("Checking commit editor...\n"))
1348 editor = ui.geteditor()
1348 editor = ui.geteditor()
1349 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1349 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1350 if not cmdpath:
1350 if not cmdpath:
1351 if editor == 'vi':
1351 if editor == 'vi':
1352 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1352 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1353 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1353 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1354 else:
1354 else:
1355 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1355 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1356 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1356 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1357 problems += 1
1357 problems += 1
1358
1358
1359 # check username
1359 # check username
1360 ui.status(_("Checking username...\n"))
1360 ui.status(_("Checking username...\n"))
1361 try:
1361 try:
1362 user = ui.username()
1362 user = ui.username()
1363 except util.Abort, e:
1363 except util.Abort, e:
1364 ui.write(" %s\n" % e)
1364 ui.write(" %s\n" % e)
1365 ui.write(_(" (specify a username in your .hgrc file)\n"))
1365 ui.write(_(" (specify a username in your .hgrc file)\n"))
1366 problems += 1
1366 problems += 1
1367
1367
1368 if not problems:
1368 if not problems:
1369 ui.status(_("No problems detected\n"))
1369 ui.status(_("No problems detected\n"))
1370 else:
1370 else:
1371 ui.write(_("%s problems detected,"
1371 ui.write(_("%s problems detected,"
1372 " please check your install!\n") % problems)
1372 " please check your install!\n") % problems)
1373
1373
1374 return problems
1374 return problems
1375
1375
1376 def debugrename(ui, repo, file1, *pats, **opts):
1376 def debugrename(ui, repo, file1, *pats, **opts):
1377 """dump rename information"""
1377 """dump rename information"""
1378
1378
1379 ctx = repo[opts.get('rev')]
1379 ctx = repo[opts.get('rev')]
1380 m = cmdutil.match(repo, (file1,) + pats, opts)
1380 m = cmdutil.match(repo, (file1,) + pats, opts)
1381 for abs in ctx.walk(m):
1381 for abs in ctx.walk(m):
1382 fctx = ctx[abs]
1382 fctx = ctx[abs]
1383 o = fctx.filelog().renamed(fctx.filenode())
1383 o = fctx.filelog().renamed(fctx.filenode())
1384 rel = m.rel(abs)
1384 rel = m.rel(abs)
1385 if o:
1385 if o:
1386 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1386 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1387 else:
1387 else:
1388 ui.write(_("%s not renamed\n") % rel)
1388 ui.write(_("%s not renamed\n") % rel)
1389
1389
1390 def debugwalk(ui, repo, *pats, **opts):
1390 def debugwalk(ui, repo, *pats, **opts):
1391 """show how files match on given patterns"""
1391 """show how files match on given patterns"""
1392 m = cmdutil.match(repo, pats, opts)
1392 m = cmdutil.match(repo, pats, opts)
1393 items = list(repo.walk(m))
1393 items = list(repo.walk(m))
1394 if not items:
1394 if not items:
1395 return
1395 return
1396 fmt = 'f %%-%ds %%-%ds %%s' % (
1396 fmt = 'f %%-%ds %%-%ds %%s' % (
1397 max([len(abs) for abs in items]),
1397 max([len(abs) for abs in items]),
1398 max([len(m.rel(abs)) for abs in items]))
1398 max([len(m.rel(abs)) for abs in items]))
1399 for abs in items:
1399 for abs in items:
1400 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1400 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1401 ui.write("%s\n" % line.rstrip())
1401 ui.write("%s\n" % line.rstrip())
1402
1402
1403 def diff(ui, repo, *pats, **opts):
1403 def diff(ui, repo, *pats, **opts):
1404 """diff repository (or selected files)
1404 """diff repository (or selected files)
1405
1405
1406 Show differences between revisions for the specified files.
1406 Show differences between revisions for the specified files.
1407
1407
1408 Differences between files are shown using the unified diff format.
1408 Differences between files are shown using the unified diff format.
1409
1409
1410 NOTE: diff may generate unexpected results for merges, as it will
1410 NOTE: diff may generate unexpected results for merges, as it will
1411 default to comparing against the working directory's first parent
1411 default to comparing against the working directory's first parent
1412 changeset if no revisions are specified.
1412 changeset if no revisions are specified.
1413
1413
1414 When two revision arguments are given, then changes are shown
1414 When two revision arguments are given, then changes are shown
1415 between those revisions. If only one revision is specified then
1415 between those revisions. If only one revision is specified then
1416 that revision is compared to the working directory, and, when no
1416 that revision is compared to the working directory, and, when no
1417 revisions are specified, the working directory files are compared
1417 revisions are specified, the working directory files are compared
1418 to its parent.
1418 to its parent.
1419
1419
1420 Alternatively you can specify -c/--change with a revision to see
1420 Alternatively you can specify -c/--change with a revision to see
1421 the changes in that changeset relative to its first parent.
1421 the changes in that changeset relative to its first parent.
1422
1422
1423 Without the -a/--text option, diff will avoid generating diffs of
1423 Without the -a/--text option, diff will avoid generating diffs of
1424 files it detects as binary. With -a, diff will generate a diff
1424 files it detects as binary. With -a, diff will generate a diff
1425 anyway, probably with undesirable results.
1425 anyway, probably with undesirable results.
1426
1426
1427 Use the -g/--git option to generate diffs in the git extended diff
1427 Use the -g/--git option to generate diffs in the git extended diff
1428 format. For more information, read :hg:`help diffs`.
1428 format. For more information, read :hg:`help diffs`.
1429
1429
1430 Returns 0 on success.
1430 Returns 0 on success.
1431 """
1431 """
1432
1432
1433 revs = opts.get('rev')
1433 revs = opts.get('rev')
1434 change = opts.get('change')
1434 change = opts.get('change')
1435 stat = opts.get('stat')
1435 stat = opts.get('stat')
1436 reverse = opts.get('reverse')
1436 reverse = opts.get('reverse')
1437
1437
1438 if revs and change:
1438 if revs and change:
1439 msg = _('cannot specify --rev and --change at the same time')
1439 msg = _('cannot specify --rev and --change at the same time')
1440 raise util.Abort(msg)
1440 raise util.Abort(msg)
1441 elif change:
1441 elif change:
1442 node2 = repo.lookup(change)
1442 node2 = repo.lookup(change)
1443 node1 = repo[node2].parents()[0].node()
1443 node1 = repo[node2].parents()[0].node()
1444 else:
1444 else:
1445 node1, node2 = cmdutil.revpair(repo, revs)
1445 node1, node2 = cmdutil.revpair(repo, revs)
1446
1446
1447 if reverse:
1447 if reverse:
1448 node1, node2 = node2, node1
1448 node1, node2 = node2, node1
1449
1449
1450 diffopts = patch.diffopts(ui, opts)
1450 diffopts = patch.diffopts(ui, opts)
1451 m = cmdutil.match(repo, pats, opts)
1451 m = cmdutil.match(repo, pats, opts)
1452 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat)
1452 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat)
1453
1453
1454 def export(ui, repo, *changesets, **opts):
1454 def export(ui, repo, *changesets, **opts):
1455 """dump the header and diffs for one or more changesets
1455 """dump the header and diffs for one or more changesets
1456
1456
1457 Print the changeset header and diffs for one or more revisions.
1457 Print the changeset header and diffs for one or more revisions.
1458
1458
1459 The information shown in the changeset header is: author, date,
1459 The information shown in the changeset header is: author, date,
1460 branch name (if non-default), changeset hash, parent(s) and commit
1460 branch name (if non-default), changeset hash, parent(s) and commit
1461 comment.
1461 comment.
1462
1462
1463 NOTE: export may generate unexpected diff output for merge
1463 NOTE: export may generate unexpected diff output for merge
1464 changesets, as it will compare the merge changeset against its
1464 changesets, as it will compare the merge changeset against its
1465 first parent only.
1465 first parent only.
1466
1466
1467 Output may be to a file, in which case the name of the file is
1467 Output may be to a file, in which case the name of the file is
1468 given using a format string. The formatting rules are as follows:
1468 given using a format string. The formatting rules are as follows:
1469
1469
1470 :``%%``: literal "%" character
1470 :``%%``: literal "%" character
1471 :``%H``: changeset hash (40 bytes of hexadecimal)
1471 :``%H``: changeset hash (40 bytes of hexadecimal)
1472 :``%N``: number of patches being generated
1472 :``%N``: number of patches being generated
1473 :``%R``: changeset revision number
1473 :``%R``: changeset revision number
1474 :``%b``: basename of the exporting repository
1474 :``%b``: basename of the exporting repository
1475 :``%h``: short-form changeset hash (12 bytes of hexadecimal)
1475 :``%h``: short-form changeset hash (12 bytes of hexadecimal)
1476 :``%n``: zero-padded sequence number, starting at 1
1476 :``%n``: zero-padded sequence number, starting at 1
1477 :``%r``: zero-padded changeset revision number
1477 :``%r``: zero-padded changeset revision number
1478
1478
1479 Without the -a/--text option, export will avoid generating diffs
1479 Without the -a/--text option, export will avoid generating diffs
1480 of files it detects as binary. With -a, export will generate a
1480 of files it detects as binary. With -a, export will generate a
1481 diff anyway, probably with undesirable results.
1481 diff anyway, probably with undesirable results.
1482
1482
1483 Use the -g/--git option to generate diffs in the git extended diff
1483 Use the -g/--git option to generate diffs in the git extended diff
1484 format. See :hg:`help diffs` for more information.
1484 format. See :hg:`help diffs` for more information.
1485
1485
1486 With the --switch-parent option, the diff will be against the
1486 With the --switch-parent option, the diff will be against the
1487 second parent. It can be useful to review a merge.
1487 second parent. It can be useful to review a merge.
1488
1488
1489 Returns 0 on success.
1489 Returns 0 on success.
1490 """
1490 """
1491 changesets += tuple(opts.get('rev', []))
1491 changesets += tuple(opts.get('rev', []))
1492 if not changesets:
1492 if not changesets:
1493 raise util.Abort(_("export requires at least one changeset"))
1493 raise util.Abort(_("export requires at least one changeset"))
1494 revs = cmdutil.revrange(repo, changesets)
1494 revs = cmdutil.revrange(repo, changesets)
1495 if len(revs) > 1:
1495 if len(revs) > 1:
1496 ui.note(_('exporting patches:\n'))
1496 ui.note(_('exporting patches:\n'))
1497 else:
1497 else:
1498 ui.note(_('exporting patch:\n'))
1498 ui.note(_('exporting patch:\n'))
1499 cmdutil.export(repo, revs, template=opts.get('output'),
1499 cmdutil.export(repo, revs, template=opts.get('output'),
1500 switch_parent=opts.get('switch_parent'),
1500 switch_parent=opts.get('switch_parent'),
1501 opts=patch.diffopts(ui, opts))
1501 opts=patch.diffopts(ui, opts))
1502
1502
1503 def forget(ui, repo, *pats, **opts):
1503 def forget(ui, repo, *pats, **opts):
1504 """forget the specified files on the next commit
1504 """forget the specified files on the next commit
1505
1505
1506 Mark the specified files so they will no longer be tracked
1506 Mark the specified files so they will no longer be tracked
1507 after the next commit.
1507 after the next commit.
1508
1508
1509 This only removes files from the current branch, not from the
1509 This only removes files from the current branch, not from the
1510 entire project history, and it does not delete them from the
1510 entire project history, and it does not delete them from the
1511 working directory.
1511 working directory.
1512
1512
1513 To undo a forget before the next commit, see :hg:`add`.
1513 To undo a forget before the next commit, see :hg:`add`.
1514
1514
1515 Returns 0 on success.
1515 Returns 0 on success.
1516 """
1516 """
1517
1517
1518 if not pats:
1518 if not pats:
1519 raise util.Abort(_('no files specified'))
1519 raise util.Abort(_('no files specified'))
1520
1520
1521 m = cmdutil.match(repo, pats, opts)
1521 m = cmdutil.match(repo, pats, opts)
1522 s = repo.status(match=m, clean=True)
1522 s = repo.status(match=m, clean=True)
1523 forget = sorted(s[0] + s[1] + s[3] + s[6])
1523 forget = sorted(s[0] + s[1] + s[3] + s[6])
1524 errs = 0
1524 errs = 0
1525
1525
1526 for f in m.files():
1526 for f in m.files():
1527 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1527 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1528 ui.warn(_('not removing %s: file is already untracked\n')
1528 ui.warn(_('not removing %s: file is already untracked\n')
1529 % m.rel(f))
1529 % m.rel(f))
1530 errs = 1
1530 errs = 1
1531
1531
1532 for f in forget:
1532 for f in forget:
1533 if ui.verbose or not m.exact(f):
1533 if ui.verbose or not m.exact(f):
1534 ui.status(_('removing %s\n') % m.rel(f))
1534 ui.status(_('removing %s\n') % m.rel(f))
1535
1535
1536 repo[None].remove(forget, unlink=False)
1536 repo[None].remove(forget, unlink=False)
1537 return errs
1537 return errs
1538
1538
1539 def grep(ui, repo, pattern, *pats, **opts):
1539 def grep(ui, repo, pattern, *pats, **opts):
1540 """search for a pattern in specified files and revisions
1540 """search for a pattern in specified files and revisions
1541
1541
1542 Search revisions of files for a regular expression.
1542 Search revisions of files for a regular expression.
1543
1543
1544 This command behaves differently than Unix grep. It only accepts
1544 This command behaves differently than Unix grep. It only accepts
1545 Python/Perl regexps. It searches repository history, not the
1545 Python/Perl regexps. It searches repository history, not the
1546 working directory. It always prints the revision number in which a
1546 working directory. It always prints the revision number in which a
1547 match appears.
1547 match appears.
1548
1548
1549 By default, grep only prints output for the first revision of a
1549 By default, grep only prints output for the first revision of a
1550 file in which it finds a match. To get it to print every revision
1550 file in which it finds a match. To get it to print every revision
1551 that contains a change in match status ("-" for a match that
1551 that contains a change in match status ("-" for a match that
1552 becomes a non-match, or "+" for a non-match that becomes a match),
1552 becomes a non-match, or "+" for a non-match that becomes a match),
1553 use the --all flag.
1553 use the --all flag.
1554
1554
1555 Returns 0 if a match is found, 1 otherwise.
1555 Returns 0 if a match is found, 1 otherwise.
1556 """
1556 """
1557 reflags = 0
1557 reflags = 0
1558 if opts.get('ignore_case'):
1558 if opts.get('ignore_case'):
1559 reflags |= re.I
1559 reflags |= re.I
1560 try:
1560 try:
1561 regexp = re.compile(pattern, reflags)
1561 regexp = re.compile(pattern, reflags)
1562 except Exception, inst:
1562 except Exception, inst:
1563 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1563 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1564 return 1
1564 return 1
1565 sep, eol = ':', '\n'
1565 sep, eol = ':', '\n'
1566 if opts.get('print0'):
1566 if opts.get('print0'):
1567 sep = eol = '\0'
1567 sep = eol = '\0'
1568
1568
1569 getfile = util.lrucachefunc(repo.file)
1569 getfile = util.lrucachefunc(repo.file)
1570
1570
1571 def matchlines(body):
1571 def matchlines(body):
1572 begin = 0
1572 begin = 0
1573 linenum = 0
1573 linenum = 0
1574 while True:
1574 while True:
1575 match = regexp.search(body, begin)
1575 match = regexp.search(body, begin)
1576 if not match:
1576 if not match:
1577 break
1577 break
1578 mstart, mend = match.span()
1578 mstart, mend = match.span()
1579 linenum += body.count('\n', begin, mstart) + 1
1579 linenum += body.count('\n', begin, mstart) + 1
1580 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1580 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1581 begin = body.find('\n', mend) + 1 or len(body)
1581 begin = body.find('\n', mend) + 1 or len(body)
1582 lend = begin - 1
1582 lend = begin - 1
1583 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1583 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1584
1584
1585 class linestate(object):
1585 class linestate(object):
1586 def __init__(self, line, linenum, colstart, colend):
1586 def __init__(self, line, linenum, colstart, colend):
1587 self.line = line
1587 self.line = line
1588 self.linenum = linenum
1588 self.linenum = linenum
1589 self.colstart = colstart
1589 self.colstart = colstart
1590 self.colend = colend
1590 self.colend = colend
1591
1591
1592 def __hash__(self):
1592 def __hash__(self):
1593 return hash((self.linenum, self.line))
1593 return hash((self.linenum, self.line))
1594
1594
1595 def __eq__(self, other):
1595 def __eq__(self, other):
1596 return self.line == other.line
1596 return self.line == other.line
1597
1597
1598 matches = {}
1598 matches = {}
1599 copies = {}
1599 copies = {}
1600 def grepbody(fn, rev, body):
1600 def grepbody(fn, rev, body):
1601 matches[rev].setdefault(fn, [])
1601 matches[rev].setdefault(fn, [])
1602 m = matches[rev][fn]
1602 m = matches[rev][fn]
1603 for lnum, cstart, cend, line in matchlines(body):
1603 for lnum, cstart, cend, line in matchlines(body):
1604 s = linestate(line, lnum, cstart, cend)
1604 s = linestate(line, lnum, cstart, cend)
1605 m.append(s)
1605 m.append(s)
1606
1606
1607 def difflinestates(a, b):
1607 def difflinestates(a, b):
1608 sm = difflib.SequenceMatcher(None, a, b)
1608 sm = difflib.SequenceMatcher(None, a, b)
1609 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1609 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1610 if tag == 'insert':
1610 if tag == 'insert':
1611 for i in xrange(blo, bhi):
1611 for i in xrange(blo, bhi):
1612 yield ('+', b[i])
1612 yield ('+', b[i])
1613 elif tag == 'delete':
1613 elif tag == 'delete':
1614 for i in xrange(alo, ahi):
1614 for i in xrange(alo, ahi):
1615 yield ('-', a[i])
1615 yield ('-', a[i])
1616 elif tag == 'replace':
1616 elif tag == 'replace':
1617 for i in xrange(alo, ahi):
1617 for i in xrange(alo, ahi):
1618 yield ('-', a[i])
1618 yield ('-', a[i])
1619 for i in xrange(blo, bhi):
1619 for i in xrange(blo, bhi):
1620 yield ('+', b[i])
1620 yield ('+', b[i])
1621
1621
1622 def display(fn, ctx, pstates, states):
1622 def display(fn, ctx, pstates, states):
1623 rev = ctx.rev()
1623 rev = ctx.rev()
1624 datefunc = ui.quiet and util.shortdate or util.datestr
1624 datefunc = ui.quiet and util.shortdate or util.datestr
1625 found = False
1625 found = False
1626 filerevmatches = {}
1626 filerevmatches = {}
1627 if opts.get('all'):
1627 if opts.get('all'):
1628 iter = difflinestates(pstates, states)
1628 iter = difflinestates(pstates, states)
1629 else:
1629 else:
1630 iter = [('', l) for l in states]
1630 iter = [('', l) for l in states]
1631 for change, l in iter:
1631 for change, l in iter:
1632 cols = [fn, str(rev)]
1632 cols = [fn, str(rev)]
1633 before, match, after = None, None, None
1633 before, match, after = None, None, None
1634 if opts.get('line_number'):
1634 if opts.get('line_number'):
1635 cols.append(str(l.linenum))
1635 cols.append(str(l.linenum))
1636 if opts.get('all'):
1636 if opts.get('all'):
1637 cols.append(change)
1637 cols.append(change)
1638 if opts.get('user'):
1638 if opts.get('user'):
1639 cols.append(ui.shortuser(ctx.user()))
1639 cols.append(ui.shortuser(ctx.user()))
1640 if opts.get('date'):
1640 if opts.get('date'):
1641 cols.append(datefunc(ctx.date()))
1641 cols.append(datefunc(ctx.date()))
1642 if opts.get('files_with_matches'):
1642 if opts.get('files_with_matches'):
1643 c = (fn, rev)
1643 c = (fn, rev)
1644 if c in filerevmatches:
1644 if c in filerevmatches:
1645 continue
1645 continue
1646 filerevmatches[c] = 1
1646 filerevmatches[c] = 1
1647 else:
1647 else:
1648 before = l.line[:l.colstart]
1648 before = l.line[:l.colstart]
1649 match = l.line[l.colstart:l.colend]
1649 match = l.line[l.colstart:l.colend]
1650 after = l.line[l.colend:]
1650 after = l.line[l.colend:]
1651 ui.write(sep.join(cols))
1651 ui.write(sep.join(cols))
1652 if before is not None:
1652 if before is not None:
1653 ui.write(sep + before)
1653 ui.write(sep + before)
1654 ui.write(match, label='grep.match')
1654 ui.write(match, label='grep.match')
1655 ui.write(after)
1655 ui.write(after)
1656 ui.write(eol)
1656 ui.write(eol)
1657 found = True
1657 found = True
1658 return found
1658 return found
1659
1659
1660 skip = {}
1660 skip = {}
1661 revfiles = {}
1661 revfiles = {}
1662 matchfn = cmdutil.match(repo, pats, opts)
1662 matchfn = cmdutil.match(repo, pats, opts)
1663 found = False
1663 found = False
1664 follow = opts.get('follow')
1664 follow = opts.get('follow')
1665
1665
1666 def prep(ctx, fns):
1666 def prep(ctx, fns):
1667 rev = ctx.rev()
1667 rev = ctx.rev()
1668 pctx = ctx.parents()[0]
1668 pctx = ctx.parents()[0]
1669 parent = pctx.rev()
1669 parent = pctx.rev()
1670 matches.setdefault(rev, {})
1670 matches.setdefault(rev, {})
1671 matches.setdefault(parent, {})
1671 matches.setdefault(parent, {})
1672 files = revfiles.setdefault(rev, [])
1672 files = revfiles.setdefault(rev, [])
1673 for fn in fns:
1673 for fn in fns:
1674 flog = getfile(fn)
1674 flog = getfile(fn)
1675 try:
1675 try:
1676 fnode = ctx.filenode(fn)
1676 fnode = ctx.filenode(fn)
1677 except error.LookupError:
1677 except error.LookupError:
1678 continue
1678 continue
1679
1679
1680 copied = flog.renamed(fnode)
1680 copied = flog.renamed(fnode)
1681 copy = follow and copied and copied[0]
1681 copy = follow and copied and copied[0]
1682 if copy:
1682 if copy:
1683 copies.setdefault(rev, {})[fn] = copy
1683 copies.setdefault(rev, {})[fn] = copy
1684 if fn in skip:
1684 if fn in skip:
1685 if copy:
1685 if copy:
1686 skip[copy] = True
1686 skip[copy] = True
1687 continue
1687 continue
1688 files.append(fn)
1688 files.append(fn)
1689
1689
1690 if fn not in matches[rev]:
1690 if fn not in matches[rev]:
1691 grepbody(fn, rev, flog.read(fnode))
1691 grepbody(fn, rev, flog.read(fnode))
1692
1692
1693 pfn = copy or fn
1693 pfn = copy or fn
1694 if pfn not in matches[parent]:
1694 if pfn not in matches[parent]:
1695 try:
1695 try:
1696 fnode = pctx.filenode(pfn)
1696 fnode = pctx.filenode(pfn)
1697 grepbody(pfn, parent, flog.read(fnode))
1697 grepbody(pfn, parent, flog.read(fnode))
1698 except error.LookupError:
1698 except error.LookupError:
1699 pass
1699 pass
1700
1700
1701 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1701 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1702 rev = ctx.rev()
1702 rev = ctx.rev()
1703 parent = ctx.parents()[0].rev()
1703 parent = ctx.parents()[0].rev()
1704 for fn in sorted(revfiles.get(rev, [])):
1704 for fn in sorted(revfiles.get(rev, [])):
1705 states = matches[rev][fn]
1705 states = matches[rev][fn]
1706 copy = copies.get(rev, {}).get(fn)
1706 copy = copies.get(rev, {}).get(fn)
1707 if fn in skip:
1707 if fn in skip:
1708 if copy:
1708 if copy:
1709 skip[copy] = True
1709 skip[copy] = True
1710 continue
1710 continue
1711 pstates = matches.get(parent, {}).get(copy or fn, [])
1711 pstates = matches.get(parent, {}).get(copy or fn, [])
1712 if pstates or states:
1712 if pstates or states:
1713 r = display(fn, ctx, pstates, states)
1713 r = display(fn, ctx, pstates, states)
1714 found = found or r
1714 found = found or r
1715 if r and not opts.get('all'):
1715 if r and not opts.get('all'):
1716 skip[fn] = True
1716 skip[fn] = True
1717 if copy:
1717 if copy:
1718 skip[copy] = True
1718 skip[copy] = True
1719 del matches[rev]
1719 del matches[rev]
1720 del revfiles[rev]
1720 del revfiles[rev]
1721
1721
1722 return not found
1722 return not found
1723
1723
1724 def heads(ui, repo, *branchrevs, **opts):
1724 def heads(ui, repo, *branchrevs, **opts):
1725 """show current repository heads or show branch heads
1725 """show current repository heads or show branch heads
1726
1726
1727 With no arguments, show all repository branch heads.
1727 With no arguments, show all repository branch heads.
1728
1728
1729 Repository "heads" are changesets with no child changesets. They are
1729 Repository "heads" are changesets with no child changesets. They are
1730 where development generally takes place and are the usual targets
1730 where development generally takes place and are the usual targets
1731 for update and merge operations. Branch heads are changesets that have
1731 for update and merge operations. Branch heads are changesets that have
1732 no child changeset on the same branch.
1732 no child changeset on the same branch.
1733
1733
1734 If one or more REVs are given, only branch heads on the branches
1734 If one or more REVs are given, only branch heads on the branches
1735 associated with the specified changesets are shown.
1735 associated with the specified changesets are shown.
1736
1736
1737 If -c/--closed is specified, also show branch heads marked closed
1737 If -c/--closed is specified, also show branch heads marked closed
1738 (see :hg:`commit --close-branch`).
1738 (see :hg:`commit --close-branch`).
1739
1739
1740 If STARTREV is specified, only those heads that are descendants of
1740 If STARTREV is specified, only those heads that are descendants of
1741 STARTREV will be displayed.
1741 STARTREV will be displayed.
1742
1742
1743 If -t/--topo is specified, named branch mechanics will be ignored and only
1743 If -t/--topo is specified, named branch mechanics will be ignored and only
1744 changesets without children will be shown.
1744 changesets without children will be shown.
1745
1745
1746 Returns 0 if matching heads are found, 1 if not.
1746 Returns 0 if matching heads are found, 1 if not.
1747 """
1747 """
1748
1748
1749 if opts.get('rev'):
1749 if opts.get('rev'):
1750 start = repo.lookup(opts['rev'])
1750 start = repo.lookup(opts['rev'])
1751 else:
1751 else:
1752 start = None
1752 start = None
1753
1753
1754 if opts.get('topo'):
1754 if opts.get('topo'):
1755 heads = [repo[h] for h in repo.heads(start)]
1755 heads = [repo[h] for h in repo.heads(start)]
1756 else:
1756 else:
1757 heads = []
1757 heads = []
1758 for b, ls in repo.branchmap().iteritems():
1758 for b, ls in repo.branchmap().iteritems():
1759 if start is None:
1759 if start is None:
1760 heads += [repo[h] for h in ls]
1760 heads += [repo[h] for h in ls]
1761 continue
1761 continue
1762 startrev = repo.changelog.rev(start)
1762 startrev = repo.changelog.rev(start)
1763 descendants = set(repo.changelog.descendants(startrev))
1763 descendants = set(repo.changelog.descendants(startrev))
1764 descendants.add(startrev)
1764 descendants.add(startrev)
1765 rev = repo.changelog.rev
1765 rev = repo.changelog.rev
1766 heads += [repo[h] for h in ls if rev(h) in descendants]
1766 heads += [repo[h] for h in ls if rev(h) in descendants]
1767
1767
1768 if branchrevs:
1768 if branchrevs:
1769 decode, encode = encoding.fromlocal, encoding.tolocal
1769 decode, encode = encoding.fromlocal, encoding.tolocal
1770 branches = set(repo[decode(br)].branch() for br in branchrevs)
1770 branches = set(repo[decode(br)].branch() for br in branchrevs)
1771 heads = [h for h in heads if h.branch() in branches]
1771 heads = [h for h in heads if h.branch() in branches]
1772
1772
1773 if not opts.get('closed'):
1773 if not opts.get('closed'):
1774 heads = [h for h in heads if not h.extra().get('close')]
1774 heads = [h for h in heads if not h.extra().get('close')]
1775
1775
1776 if opts.get('active') and branchrevs:
1776 if opts.get('active') and branchrevs:
1777 dagheads = repo.heads(start)
1777 dagheads = repo.heads(start)
1778 heads = [h for h in heads if h.node() in dagheads]
1778 heads = [h for h in heads if h.node() in dagheads]
1779
1779
1780 if branchrevs:
1780 if branchrevs:
1781 haveheads = set(h.branch() for h in heads)
1781 haveheads = set(h.branch() for h in heads)
1782 if branches - haveheads:
1782 if branches - haveheads:
1783 headless = ', '.join(encode(b) for b in branches - haveheads)
1783 headless = ', '.join(encode(b) for b in branches - haveheads)
1784 msg = _('no open branch heads found on branches %s')
1784 msg = _('no open branch heads found on branches %s')
1785 if opts.get('rev'):
1785 if opts.get('rev'):
1786 msg += _(' (started at %s)' % opts['rev'])
1786 msg += _(' (started at %s)' % opts['rev'])
1787 ui.warn((msg + '\n') % headless)
1787 ui.warn((msg + '\n') % headless)
1788
1788
1789 if not heads:
1789 if not heads:
1790 return 1
1790 return 1
1791
1791
1792 heads = sorted(heads, key=lambda x: -x.rev())
1792 heads = sorted(heads, key=lambda x: -x.rev())
1793 displayer = cmdutil.show_changeset(ui, repo, opts)
1793 displayer = cmdutil.show_changeset(ui, repo, opts)
1794 for ctx in heads:
1794 for ctx in heads:
1795 displayer.show(ctx)
1795 displayer.show(ctx)
1796 displayer.close()
1796 displayer.close()
1797
1797
1798 def help_(ui, name=None, with_version=False, unknowncmd=False):
1798 def help_(ui, name=None, with_version=False, unknowncmd=False):
1799 """show help for a given topic or a help overview
1799 """show help for a given topic or a help overview
1800
1800
1801 With no arguments, print a list of commands with short help messages.
1801 With no arguments, print a list of commands with short help messages.
1802
1802
1803 Given a topic, extension, or command name, print help for that
1803 Given a topic, extension, or command name, print help for that
1804 topic.
1804 topic.
1805
1805
1806 Returns 0 if successful.
1806 Returns 0 if successful.
1807 """
1807 """
1808 option_lists = []
1808 option_lists = []
1809 textwidth = util.termwidth() - 2
1809 textwidth = util.termwidth() - 2
1810
1810
1811 def addglobalopts(aliases):
1811 def addglobalopts(aliases):
1812 if ui.verbose:
1812 if ui.verbose:
1813 option_lists.append((_("global options:"), globalopts))
1813 option_lists.append((_("global options:"), globalopts))
1814 if name == 'shortlist':
1814 if name == 'shortlist':
1815 option_lists.append((_('use "hg help" for the full list '
1815 option_lists.append((_('use "hg help" for the full list '
1816 'of commands'), ()))
1816 'of commands'), ()))
1817 else:
1817 else:
1818 if name == 'shortlist':
1818 if name == 'shortlist':
1819 msg = _('use "hg help" for the full list of commands '
1819 msg = _('use "hg help" for the full list of commands '
1820 'or "hg -v" for details')
1820 'or "hg -v" for details')
1821 elif aliases:
1821 elif aliases:
1822 msg = _('use "hg -v help%s" to show aliases and '
1822 msg = _('use "hg -v help%s" to show aliases and '
1823 'global options') % (name and " " + name or "")
1823 'global options') % (name and " " + name or "")
1824 else:
1824 else:
1825 msg = _('use "hg -v help %s" to show global options') % name
1825 msg = _('use "hg -v help %s" to show global options') % name
1826 option_lists.append((msg, ()))
1826 option_lists.append((msg, ()))
1827
1827
1828 def helpcmd(name):
1828 def helpcmd(name):
1829 if with_version:
1829 if with_version:
1830 version_(ui)
1830 version_(ui)
1831 ui.write('\n')
1831 ui.write('\n')
1832
1832
1833 try:
1833 try:
1834 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1834 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1835 except error.AmbiguousCommand, inst:
1835 except error.AmbiguousCommand, inst:
1836 # py3k fix: except vars can't be used outside the scope of the
1836 # py3k fix: except vars can't be used outside the scope of the
1837 # except block, nor can be used inside a lambda. python issue4617
1837 # except block, nor can be used inside a lambda. python issue4617
1838 prefix = inst.args[0]
1838 prefix = inst.args[0]
1839 select = lambda c: c.lstrip('^').startswith(prefix)
1839 select = lambda c: c.lstrip('^').startswith(prefix)
1840 helplist(_('list of commands:\n\n'), select)
1840 helplist(_('list of commands:\n\n'), select)
1841 return
1841 return
1842
1842
1843 # check if it's an invalid alias and display its error if it is
1843 # check if it's an invalid alias and display its error if it is
1844 if getattr(entry[0], 'badalias', False):
1844 if getattr(entry[0], 'badalias', False):
1845 if not unknowncmd:
1845 if not unknowncmd:
1846 entry[0](ui)
1846 entry[0](ui)
1847 return
1847 return
1848
1848
1849 # synopsis
1849 # synopsis
1850 if len(entry) > 2:
1850 if len(entry) > 2:
1851 if entry[2].startswith('hg'):
1851 if entry[2].startswith('hg'):
1852 ui.write("%s\n" % entry[2])
1852 ui.write("%s\n" % entry[2])
1853 else:
1853 else:
1854 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
1854 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
1855 else:
1855 else:
1856 ui.write('hg %s\n' % aliases[0])
1856 ui.write('hg %s\n' % aliases[0])
1857
1857
1858 # aliases
1858 # aliases
1859 if not ui.quiet and len(aliases) > 1:
1859 if not ui.quiet and len(aliases) > 1:
1860 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1860 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1861
1861
1862 # description
1862 # description
1863 doc = gettext(entry[0].__doc__)
1863 doc = gettext(entry[0].__doc__)
1864 if not doc:
1864 if not doc:
1865 doc = _("(no help text available)")
1865 doc = _("(no help text available)")
1866 if hasattr(entry[0], 'definition'): # aliased command
1866 if hasattr(entry[0], 'definition'): # aliased command
1867 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
1867 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
1868 if ui.quiet:
1868 if ui.quiet:
1869 doc = doc.splitlines()[0]
1869 doc = doc.splitlines()[0]
1870 keep = ui.verbose and ['verbose'] or []
1870 keep = ui.verbose and ['verbose'] or []
1871 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
1871 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
1872 ui.write("\n%s\n" % formatted)
1872 ui.write("\n%s\n" % formatted)
1873 if pruned:
1873 if pruned:
1874 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
1874 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
1875
1875
1876 if not ui.quiet:
1876 if not ui.quiet:
1877 # options
1877 # options
1878 if entry[1]:
1878 if entry[1]:
1879 option_lists.append((_("options:\n"), entry[1]))
1879 option_lists.append((_("options:\n"), entry[1]))
1880
1880
1881 addglobalopts(False)
1881 addglobalopts(False)
1882
1882
1883 def helplist(header, select=None):
1883 def helplist(header, select=None):
1884 h = {}
1884 h = {}
1885 cmds = {}
1885 cmds = {}
1886 for c, e in table.iteritems():
1886 for c, e in table.iteritems():
1887 f = c.split("|", 1)[0]
1887 f = c.split("|", 1)[0]
1888 if select and not select(f):
1888 if select and not select(f):
1889 continue
1889 continue
1890 if (not select and name != 'shortlist' and
1890 if (not select and name != 'shortlist' and
1891 e[0].__module__ != __name__):
1891 e[0].__module__ != __name__):
1892 continue
1892 continue
1893 if name == "shortlist" and not f.startswith("^"):
1893 if name == "shortlist" and not f.startswith("^"):
1894 continue
1894 continue
1895 f = f.lstrip("^")
1895 f = f.lstrip("^")
1896 if not ui.debugflag and f.startswith("debug"):
1896 if not ui.debugflag and f.startswith("debug"):
1897 continue
1897 continue
1898 doc = e[0].__doc__
1898 doc = e[0].__doc__
1899 if doc and 'DEPRECATED' in doc and not ui.verbose:
1899 if doc and 'DEPRECATED' in doc and not ui.verbose:
1900 continue
1900 continue
1901 doc = gettext(doc)
1901 doc = gettext(doc)
1902 if not doc:
1902 if not doc:
1903 doc = _("(no help text available)")
1903 doc = _("(no help text available)")
1904 h[f] = doc.splitlines()[0].rstrip()
1904 h[f] = doc.splitlines()[0].rstrip()
1905 cmds[f] = c.lstrip("^")
1905 cmds[f] = c.lstrip("^")
1906
1906
1907 if not h:
1907 if not h:
1908 ui.status(_('no commands defined\n'))
1908 ui.status(_('no commands defined\n'))
1909 return
1909 return
1910
1910
1911 ui.status(header)
1911 ui.status(header)
1912 fns = sorted(h)
1912 fns = sorted(h)
1913 m = max(map(len, fns))
1913 m = max(map(len, fns))
1914 for f in fns:
1914 for f in fns:
1915 if ui.verbose:
1915 if ui.verbose:
1916 commands = cmds[f].replace("|",", ")
1916 commands = cmds[f].replace("|",", ")
1917 ui.write(" %s:\n %s\n"%(commands, h[f]))
1917 ui.write(" %s:\n %s\n"%(commands, h[f]))
1918 else:
1918 else:
1919 ui.write('%s\n' % (util.wrap(h[f],
1919 ui.write('%s\n' % (util.wrap(h[f],
1920 initindent=' %-*s ' % (m, f),
1920 initindent=' %-*s ' % (m, f),
1921 hangindent=' ' * (m + 4))))
1921 hangindent=' ' * (m + 4))))
1922
1922
1923 if not ui.quiet:
1923 if not ui.quiet:
1924 addglobalopts(True)
1924 addglobalopts(True)
1925
1925
1926 def helptopic(name):
1926 def helptopic(name):
1927 for names, header, doc in help.helptable:
1927 for names, header, doc in help.helptable:
1928 if name in names:
1928 if name in names:
1929 break
1929 break
1930 else:
1930 else:
1931 raise error.UnknownCommand(name)
1931 raise error.UnknownCommand(name)
1932
1932
1933 # description
1933 # description
1934 if not doc:
1934 if not doc:
1935 doc = _("(no help text available)")
1935 doc = _("(no help text available)")
1936 if hasattr(doc, '__call__'):
1936 if hasattr(doc, '__call__'):
1937 doc = doc()
1937 doc = doc()
1938
1938
1939 ui.write("%s\n\n" % header)
1939 ui.write("%s\n\n" % header)
1940 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
1940 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
1941
1941
1942 def helpext(name):
1942 def helpext(name):
1943 try:
1943 try:
1944 mod = extensions.find(name)
1944 mod = extensions.find(name)
1945 doc = gettext(mod.__doc__) or _('no help text available')
1945 doc = gettext(mod.__doc__) or _('no help text available')
1946 except KeyError:
1946 except KeyError:
1947 mod = None
1947 mod = None
1948 doc = extensions.disabledext(name)
1948 doc = extensions.disabledext(name)
1949 if not doc:
1949 if not doc:
1950 raise error.UnknownCommand(name)
1950 raise error.UnknownCommand(name)
1951
1951
1952 if '\n' not in doc:
1952 if '\n' not in doc:
1953 head, tail = doc, ""
1953 head, tail = doc, ""
1954 else:
1954 else:
1955 head, tail = doc.split('\n', 1)
1955 head, tail = doc.split('\n', 1)
1956 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
1956 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
1957 if tail:
1957 if tail:
1958 ui.write(minirst.format(tail, textwidth))
1958 ui.write(minirst.format(tail, textwidth))
1959 ui.status('\n\n')
1959 ui.status('\n\n')
1960
1960
1961 if mod:
1961 if mod:
1962 try:
1962 try:
1963 ct = mod.cmdtable
1963 ct = mod.cmdtable
1964 except AttributeError:
1964 except AttributeError:
1965 ct = {}
1965 ct = {}
1966 modcmds = set([c.split('|', 1)[0] for c in ct])
1966 modcmds = set([c.split('|', 1)[0] for c in ct])
1967 helplist(_('list of commands:\n\n'), modcmds.__contains__)
1967 helplist(_('list of commands:\n\n'), modcmds.__contains__)
1968 else:
1968 else:
1969 ui.write(_('use "hg help extensions" for information on enabling '
1969 ui.write(_('use "hg help extensions" for information on enabling '
1970 'extensions\n'))
1970 'extensions\n'))
1971
1971
1972 def helpextcmd(name):
1972 def helpextcmd(name):
1973 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
1973 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
1974 doc = gettext(mod.__doc__).splitlines()[0]
1974 doc = gettext(mod.__doc__).splitlines()[0]
1975
1975
1976 msg = help.listexts(_("'%s' is provided by the following "
1976 msg = help.listexts(_("'%s' is provided by the following "
1977 "extension:") % cmd, {ext: doc}, len(ext),
1977 "extension:") % cmd, {ext: doc}, len(ext),
1978 indent=4)
1978 indent=4)
1979 ui.write(minirst.format(msg, textwidth))
1979 ui.write(minirst.format(msg, textwidth))
1980 ui.write('\n\n')
1980 ui.write('\n\n')
1981 ui.write(_('use "hg help extensions" for information on enabling '
1981 ui.write(_('use "hg help extensions" for information on enabling '
1982 'extensions\n'))
1982 'extensions\n'))
1983
1983
1984 if name and name != 'shortlist':
1984 if name and name != 'shortlist':
1985 i = None
1985 i = None
1986 if unknowncmd:
1986 if unknowncmd:
1987 queries = (helpextcmd,)
1987 queries = (helpextcmd,)
1988 else:
1988 else:
1989 queries = (helptopic, helpcmd, helpext, helpextcmd)
1989 queries = (helptopic, helpcmd, helpext, helpextcmd)
1990 for f in queries:
1990 for f in queries:
1991 try:
1991 try:
1992 f(name)
1992 f(name)
1993 i = None
1993 i = None
1994 break
1994 break
1995 except error.UnknownCommand, inst:
1995 except error.UnknownCommand, inst:
1996 i = inst
1996 i = inst
1997 if i:
1997 if i:
1998 raise i
1998 raise i
1999
1999
2000 else:
2000 else:
2001 # program name
2001 # program name
2002 if ui.verbose or with_version:
2002 if ui.verbose or with_version:
2003 version_(ui)
2003 version_(ui)
2004 else:
2004 else:
2005 ui.status(_("Mercurial Distributed SCM\n"))
2005 ui.status(_("Mercurial Distributed SCM\n"))
2006 ui.status('\n')
2006 ui.status('\n')
2007
2007
2008 # list of commands
2008 # list of commands
2009 if name == "shortlist":
2009 if name == "shortlist":
2010 header = _('basic commands:\n\n')
2010 header = _('basic commands:\n\n')
2011 else:
2011 else:
2012 header = _('list of commands:\n\n')
2012 header = _('list of commands:\n\n')
2013
2013
2014 helplist(header)
2014 helplist(header)
2015 if name != 'shortlist':
2015 if name != 'shortlist':
2016 exts, maxlength = extensions.enabled()
2016 exts, maxlength = extensions.enabled()
2017 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2017 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2018 if text:
2018 if text:
2019 ui.write("\n%s\n" % minirst.format(text, textwidth))
2019 ui.write("\n%s\n" % minirst.format(text, textwidth))
2020
2020
2021 # list all option lists
2021 # list all option lists
2022 opt_output = []
2022 opt_output = []
2023 multioccur = False
2023 multioccur = False
2024 for title, options in option_lists:
2024 for title, options in option_lists:
2025 opt_output.append(("\n%s" % title, None))
2025 opt_output.append(("\n%s" % title, None))
2026 for option in options:
2026 for option in options:
2027 if len(option) == 5:
2027 if len(option) == 5:
2028 shortopt, longopt, default, desc, optlabel = option
2028 shortopt, longopt, default, desc, optlabel = option
2029 else:
2029 else:
2030 shortopt, longopt, default, desc = option
2030 shortopt, longopt, default, desc = option
2031 optlabel = _("VALUE") # default label
2031 optlabel = _("VALUE") # default label
2032
2032
2033 if _("DEPRECATED") in desc and not ui.verbose:
2033 if _("DEPRECATED") in desc and not ui.verbose:
2034 continue
2034 continue
2035 if isinstance(default, list):
2035 if isinstance(default, list):
2036 numqualifier = " %s [+]" % optlabel
2036 numqualifier = " %s [+]" % optlabel
2037 multioccur = True
2037 multioccur = True
2038 elif (default is not None) and not isinstance(default, bool):
2038 elif (default is not None) and not isinstance(default, bool):
2039 numqualifier = " %s" % optlabel
2039 numqualifier = " %s" % optlabel
2040 else:
2040 else:
2041 numqualifier = ""
2041 numqualifier = ""
2042 opt_output.append(("%2s%s" %
2042 opt_output.append(("%2s%s" %
2043 (shortopt and "-%s" % shortopt,
2043 (shortopt and "-%s" % shortopt,
2044 longopt and " --%s%s" %
2044 longopt and " --%s%s" %
2045 (longopt, numqualifier)),
2045 (longopt, numqualifier)),
2046 "%s%s" % (desc,
2046 "%s%s" % (desc,
2047 default
2047 default
2048 and _(" (default: %s)") % default
2048 and _(" (default: %s)") % default
2049 or "")))
2049 or "")))
2050 if multioccur:
2050 if multioccur:
2051 msg = _("\n[+] marked option can be specified multiple times")
2051 msg = _("\n[+] marked option can be specified multiple times")
2052 if ui.verbose and name != 'shortlist':
2052 if ui.verbose and name != 'shortlist':
2053 opt_output.append((msg, ()))
2053 opt_output.append((msg, ()))
2054 else:
2054 else:
2055 opt_output.insert(-1, (msg, ()))
2055 opt_output.insert(-1, (msg, ()))
2056
2056
2057 if not name:
2057 if not name:
2058 ui.write(_("\nadditional help topics:\n\n"))
2058 ui.write(_("\nadditional help topics:\n\n"))
2059 topics = []
2059 topics = []
2060 for names, header, doc in help.helptable:
2060 for names, header, doc in help.helptable:
2061 topics.append((sorted(names, key=len, reverse=True)[0], header))
2061 topics.append((sorted(names, key=len, reverse=True)[0], header))
2062 topics_len = max([len(s[0]) for s in topics])
2062 topics_len = max([len(s[0]) for s in topics])
2063 for t, desc in topics:
2063 for t, desc in topics:
2064 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2064 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2065
2065
2066 if opt_output:
2066 if opt_output:
2067 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
2067 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
2068 for first, second in opt_output:
2068 for first, second in opt_output:
2069 if second:
2069 if second:
2070 initindent = ' %-*s ' % (opts_len, first)
2070 initindent = ' %-*s ' % (opts_len, first)
2071 hangindent = ' ' * (opts_len + 3)
2071 hangindent = ' ' * (opts_len + 3)
2072 ui.write('%s\n' % (util.wrap(second,
2072 ui.write('%s\n' % (util.wrap(second,
2073 initindent=initindent,
2073 initindent=initindent,
2074 hangindent=hangindent)))
2074 hangindent=hangindent)))
2075 else:
2075 else:
2076 ui.write("%s\n" % first)
2076 ui.write("%s\n" % first)
2077
2077
2078 def identify(ui, repo, source=None,
2078 def identify(ui, repo, source=None,
2079 rev=None, num=None, id=None, branch=None, tags=None):
2079 rev=None, num=None, id=None, branch=None, tags=None):
2080 """identify the working copy or specified revision
2080 """identify the working copy or specified revision
2081
2081
2082 With no revision, print a summary of the current state of the
2082 With no revision, print a summary of the current state of the
2083 repository.
2083 repository.
2084
2084
2085 Specifying a path to a repository root or Mercurial bundle will
2085 Specifying a path to a repository root or Mercurial bundle will
2086 cause lookup to operate on that repository/bundle.
2086 cause lookup to operate on that repository/bundle.
2087
2087
2088 This summary identifies the repository state using one or two
2088 This summary identifies the repository state using one or two
2089 parent hash identifiers, followed by a "+" if there are
2089 parent hash identifiers, followed by a "+" if there are
2090 uncommitted changes in the working directory, a list of tags for
2090 uncommitted changes in the working directory, a list of tags for
2091 this revision and a branch name for non-default branches.
2091 this revision and a branch name for non-default branches.
2092
2092
2093 Returns 0 if successful.
2093 Returns 0 if successful.
2094 """
2094 """
2095
2095
2096 if not repo and not source:
2096 if not repo and not source:
2097 raise util.Abort(_("There is no Mercurial repository here "
2097 raise util.Abort(_("There is no Mercurial repository here "
2098 "(.hg not found)"))
2098 "(.hg not found)"))
2099
2099
2100 hexfunc = ui.debugflag and hex or short
2100 hexfunc = ui.debugflag and hex or short
2101 default = not (num or id or branch or tags)
2101 default = not (num or id or branch or tags)
2102 output = []
2102 output = []
2103
2103
2104 revs = []
2104 revs = []
2105 if source:
2105 if source:
2106 source, branches = hg.parseurl(ui.expandpath(source))
2106 source, branches = hg.parseurl(ui.expandpath(source))
2107 repo = hg.repository(ui, source)
2107 repo = hg.repository(ui, source)
2108 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2108 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2109
2109
2110 if not repo.local():
2110 if not repo.local():
2111 if not rev and revs:
2111 if not rev and revs:
2112 rev = revs[0]
2112 rev = revs[0]
2113 if not rev:
2113 if not rev:
2114 rev = "tip"
2114 rev = "tip"
2115 if num or branch or tags:
2115 if num or branch or tags:
2116 raise util.Abort(
2116 raise util.Abort(
2117 "can't query remote revision number, branch, or tags")
2117 "can't query remote revision number, branch, or tags")
2118 output = [hexfunc(repo.lookup(rev))]
2118 output = [hexfunc(repo.lookup(rev))]
2119 elif not rev:
2119 elif not rev:
2120 ctx = repo[None]
2120 ctx = repo[None]
2121 parents = ctx.parents()
2121 parents = ctx.parents()
2122 changed = False
2122 changed = False
2123 if default or id or num:
2123 if default or id or num:
2124 changed = util.any(repo.status())
2124 changed = util.any(repo.status())
2125 if default or id:
2125 if default or id:
2126 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2126 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2127 (changed) and "+" or "")]
2127 (changed) and "+" or "")]
2128 if num:
2128 if num:
2129 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
2129 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
2130 (changed) and "+" or ""))
2130 (changed) and "+" or ""))
2131 else:
2131 else:
2132 ctx = repo[rev]
2132 ctx = repo[rev]
2133 if default or id:
2133 if default or id:
2134 output = [hexfunc(ctx.node())]
2134 output = [hexfunc(ctx.node())]
2135 if num:
2135 if num:
2136 output.append(str(ctx.rev()))
2136 output.append(str(ctx.rev()))
2137
2137
2138 if repo.local() and default and not ui.quiet:
2138 if repo.local() and default and not ui.quiet:
2139 b = encoding.tolocal(ctx.branch())
2139 b = encoding.tolocal(ctx.branch())
2140 if b != 'default':
2140 if b != 'default':
2141 output.append("(%s)" % b)
2141 output.append("(%s)" % b)
2142
2142
2143 # multiple tags for a single parent separated by '/'
2143 # multiple tags for a single parent separated by '/'
2144 t = "/".join(ctx.tags())
2144 t = "/".join(ctx.tags())
2145 if t:
2145 if t:
2146 output.append(t)
2146 output.append(t)
2147
2147
2148 if branch:
2148 if branch:
2149 output.append(encoding.tolocal(ctx.branch()))
2149 output.append(encoding.tolocal(ctx.branch()))
2150
2150
2151 if tags:
2151 if tags:
2152 output.extend(ctx.tags())
2152 output.extend(ctx.tags())
2153
2153
2154 ui.write("%s\n" % ' '.join(output))
2154 ui.write("%s\n" % ' '.join(output))
2155
2155
2156 def import_(ui, repo, patch1, *patches, **opts):
2156 def import_(ui, repo, patch1, *patches, **opts):
2157 """import an ordered set of patches
2157 """import an ordered set of patches
2158
2158
2159 Import a list of patches and commit them individually (unless
2159 Import a list of patches and commit them individually (unless
2160 --no-commit is specified).
2160 --no-commit is specified).
2161
2161
2162 If there are outstanding changes in the working directory, import
2162 If there are outstanding changes in the working directory, import
2163 will abort unless given the -f/--force flag.
2163 will abort unless given the -f/--force flag.
2164
2164
2165 You can import a patch straight from a mail message. Even patches
2165 You can import a patch straight from a mail message. Even patches
2166 as attachments work (to use the body part, it must have type
2166 as attachments work (to use the body part, it must have type
2167 text/plain or text/x-patch). From and Subject headers of email
2167 text/plain or text/x-patch). From and Subject headers of email
2168 message are used as default committer and commit message. All
2168 message are used as default committer and commit message. All
2169 text/plain body parts before first diff are added to commit
2169 text/plain body parts before first diff are added to commit
2170 message.
2170 message.
2171
2171
2172 If the imported patch was generated by :hg:`export`, user and
2172 If the imported patch was generated by :hg:`export`, user and
2173 description from patch override values from message headers and
2173 description from patch override values from message headers and
2174 body. Values given on command line with -m/--message and -u/--user
2174 body. Values given on command line with -m/--message and -u/--user
2175 override these.
2175 override these.
2176
2176
2177 If --exact is specified, import will set the working directory to
2177 If --exact is specified, import will set the working directory to
2178 the parent of each patch before applying it, and will abort if the
2178 the parent of each patch before applying it, and will abort if the
2179 resulting changeset has a different ID than the one recorded in
2179 resulting changeset has a different ID than the one recorded in
2180 the patch. This may happen due to character set problems or other
2180 the patch. This may happen due to character set problems or other
2181 deficiencies in the text patch format.
2181 deficiencies in the text patch format.
2182
2182
2183 With -s/--similarity, hg will attempt to discover renames and
2183 With -s/--similarity, hg will attempt to discover renames and
2184 copies in the patch in the same way as 'addremove'.
2184 copies in the patch in the same way as 'addremove'.
2185
2185
2186 To read a patch from standard input, use "-" as the patch name. If
2186 To read a patch from standard input, use "-" as the patch name. If
2187 a URL is specified, the patch will be downloaded from it.
2187 a URL is specified, the patch will be downloaded from it.
2188 See :hg:`help dates` for a list of formats valid for -d/--date.
2188 See :hg:`help dates` for a list of formats valid for -d/--date.
2189
2189
2190 Returns 0 on success.
2190 Returns 0 on success.
2191 """
2191 """
2192 patches = (patch1,) + patches
2192 patches = (patch1,) + patches
2193
2193
2194 date = opts.get('date')
2194 date = opts.get('date')
2195 if date:
2195 if date:
2196 opts['date'] = util.parsedate(date)
2196 opts['date'] = util.parsedate(date)
2197
2197
2198 try:
2198 try:
2199 sim = float(opts.get('similarity') or 0)
2199 sim = float(opts.get('similarity') or 0)
2200 except ValueError:
2200 except ValueError:
2201 raise util.Abort(_('similarity must be a number'))
2201 raise util.Abort(_('similarity must be a number'))
2202 if sim < 0 or sim > 100:
2202 if sim < 0 or sim > 100:
2203 raise util.Abort(_('similarity must be between 0 and 100'))
2203 raise util.Abort(_('similarity must be between 0 and 100'))
2204
2204
2205 if opts.get('exact') or not opts.get('force'):
2205 if opts.get('exact') or not opts.get('force'):
2206 cmdutil.bail_if_changed(repo)
2206 cmdutil.bail_if_changed(repo)
2207
2207
2208 d = opts["base"]
2208 d = opts["base"]
2209 strip = opts["strip"]
2209 strip = opts["strip"]
2210 wlock = lock = None
2210 wlock = lock = None
2211
2211
2212 def tryone(ui, hunk):
2212 def tryone(ui, hunk):
2213 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2213 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2214 patch.extract(ui, hunk)
2214 patch.extract(ui, hunk)
2215
2215
2216 if not tmpname:
2216 if not tmpname:
2217 return None
2217 return None
2218 commitid = _('to working directory')
2218 commitid = _('to working directory')
2219
2219
2220 try:
2220 try:
2221 cmdline_message = cmdutil.logmessage(opts)
2221 cmdline_message = cmdutil.logmessage(opts)
2222 if cmdline_message:
2222 if cmdline_message:
2223 # pickup the cmdline msg
2223 # pickup the cmdline msg
2224 message = cmdline_message
2224 message = cmdline_message
2225 elif message:
2225 elif message:
2226 # pickup the patch msg
2226 # pickup the patch msg
2227 message = message.strip()
2227 message = message.strip()
2228 else:
2228 else:
2229 # launch the editor
2229 # launch the editor
2230 message = None
2230 message = None
2231 ui.debug('message:\n%s\n' % message)
2231 ui.debug('message:\n%s\n' % message)
2232
2232
2233 wp = repo.parents()
2233 wp = repo.parents()
2234 if opts.get('exact'):
2234 if opts.get('exact'):
2235 if not nodeid or not p1:
2235 if not nodeid or not p1:
2236 raise util.Abort(_('not a Mercurial patch'))
2236 raise util.Abort(_('not a Mercurial patch'))
2237 p1 = repo.lookup(p1)
2237 p1 = repo.lookup(p1)
2238 p2 = repo.lookup(p2 or hex(nullid))
2238 p2 = repo.lookup(p2 or hex(nullid))
2239
2239
2240 if p1 != wp[0].node():
2240 if p1 != wp[0].node():
2241 hg.clean(repo, p1)
2241 hg.clean(repo, p1)
2242 repo.dirstate.setparents(p1, p2)
2242 repo.dirstate.setparents(p1, p2)
2243 elif p2:
2243 elif p2:
2244 try:
2244 try:
2245 p1 = repo.lookup(p1)
2245 p1 = repo.lookup(p1)
2246 p2 = repo.lookup(p2)
2246 p2 = repo.lookup(p2)
2247 if p1 == wp[0].node():
2247 if p1 == wp[0].node():
2248 repo.dirstate.setparents(p1, p2)
2248 repo.dirstate.setparents(p1, p2)
2249 except error.RepoError:
2249 except error.RepoError:
2250 pass
2250 pass
2251 if opts.get('exact') or opts.get('import_branch'):
2251 if opts.get('exact') or opts.get('import_branch'):
2252 repo.dirstate.setbranch(branch or 'default')
2252 repo.dirstate.setbranch(branch or 'default')
2253
2253
2254 files = {}
2254 files = {}
2255 try:
2255 try:
2256 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2256 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2257 files=files, eolmode=None)
2257 files=files, eolmode=None)
2258 finally:
2258 finally:
2259 files = patch.updatedir(ui, repo, files,
2259 files = patch.updatedir(ui, repo, files,
2260 similarity=sim / 100.0)
2260 similarity=sim / 100.0)
2261 if not opts.get('no_commit'):
2261 if not opts.get('no_commit'):
2262 if opts.get('exact'):
2262 if opts.get('exact'):
2263 m = None
2263 m = None
2264 else:
2264 else:
2265 m = cmdutil.matchfiles(repo, files or [])
2265 m = cmdutil.matchfiles(repo, files or [])
2266 n = repo.commit(message, opts.get('user') or user,
2266 n = repo.commit(message, opts.get('user') or user,
2267 opts.get('date') or date, match=m,
2267 opts.get('date') or date, match=m,
2268 editor=cmdutil.commiteditor)
2268 editor=cmdutil.commiteditor)
2269 if opts.get('exact'):
2269 if opts.get('exact'):
2270 if hex(n) != nodeid:
2270 if hex(n) != nodeid:
2271 repo.rollback()
2271 repo.rollback()
2272 raise util.Abort(_('patch is damaged'
2272 raise util.Abort(_('patch is damaged'
2273 ' or loses information'))
2273 ' or loses information'))
2274 # Force a dirstate write so that the next transaction
2274 # Force a dirstate write so that the next transaction
2275 # backups an up-do-date file.
2275 # backups an up-do-date file.
2276 repo.dirstate.write()
2276 repo.dirstate.write()
2277 if n:
2277 if n:
2278 commitid = short(n)
2278 commitid = short(n)
2279
2279
2280 return commitid
2280 return commitid
2281 finally:
2281 finally:
2282 os.unlink(tmpname)
2282 os.unlink(tmpname)
2283
2283
2284 try:
2284 try:
2285 wlock = repo.wlock()
2285 wlock = repo.wlock()
2286 lock = repo.lock()
2286 lock = repo.lock()
2287 lastcommit = None
2287 lastcommit = None
2288 for p in patches:
2288 for p in patches:
2289 pf = os.path.join(d, p)
2289 pf = os.path.join(d, p)
2290
2290
2291 if pf == '-':
2291 if pf == '-':
2292 ui.status(_("applying patch from stdin\n"))
2292 ui.status(_("applying patch from stdin\n"))
2293 pf = sys.stdin
2293 pf = sys.stdin
2294 else:
2294 else:
2295 ui.status(_("applying %s\n") % p)
2295 ui.status(_("applying %s\n") % p)
2296 pf = url.open(ui, pf)
2296 pf = url.open(ui, pf)
2297
2297
2298 haspatch = False
2298 haspatch = False
2299 for hunk in patch.split(pf):
2299 for hunk in patch.split(pf):
2300 commitid = tryone(ui, hunk)
2300 commitid = tryone(ui, hunk)
2301 if commitid:
2301 if commitid:
2302 haspatch = True
2302 haspatch = True
2303 if lastcommit:
2303 if lastcommit:
2304 ui.status(_('applied %s\n') % lastcommit)
2304 ui.status(_('applied %s\n') % lastcommit)
2305 lastcommit = commitid
2305 lastcommit = commitid
2306
2306
2307 if not haspatch:
2307 if not haspatch:
2308 raise util.Abort(_('no diffs found'))
2308 raise util.Abort(_('no diffs found'))
2309
2309
2310 finally:
2310 finally:
2311 release(lock, wlock)
2311 release(lock, wlock)
2312
2312
2313 def incoming(ui, repo, source="default", **opts):
2313 def incoming(ui, repo, source="default", **opts):
2314 """show new changesets found in source
2314 """show new changesets found in source
2315
2315
2316 Show new changesets found in the specified path/URL or the default
2316 Show new changesets found in the specified path/URL or the default
2317 pull location. These are the changesets that would have been pulled
2317 pull location. These are the changesets that would have been pulled
2318 if a pull at the time you issued this command.
2318 if a pull at the time you issued this command.
2319
2319
2320 For remote repository, using --bundle avoids downloading the
2320 For remote repository, using --bundle avoids downloading the
2321 changesets twice if the incoming is followed by a pull.
2321 changesets twice if the incoming is followed by a pull.
2322
2322
2323 See pull for valid source format details.
2323 See pull for valid source format details.
2324
2324
2325 Returns 0 if there are incoming changes, 1 otherwise.
2325 Returns 0 if there are incoming changes, 1 otherwise.
2326 """
2326 """
2327 limit = cmdutil.loglimit(opts)
2327 limit = cmdutil.loglimit(opts)
2328 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2328 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2329 other = hg.repository(hg.remoteui(repo, opts), source)
2329 other = hg.repository(hg.remoteui(repo, opts), source)
2330 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2330 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2331 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2331 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2332 if revs:
2332 if revs:
2333 revs = [other.lookup(rev) for rev in revs]
2333 revs = [other.lookup(rev) for rev in revs]
2334
2334
2335 tmp = discovery.findcommonincoming(repo, other, heads=revs,
2335 tmp = discovery.findcommonincoming(repo, other, heads=revs,
2336 force=opts.get('force'))
2336 force=opts.get('force'))
2337 common, incoming, rheads = tmp
2337 common, incoming, rheads = tmp
2338 if not incoming:
2338 if not incoming:
2339 try:
2339 try:
2340 os.unlink(opts["bundle"])
2340 os.unlink(opts["bundle"])
2341 except:
2341 except:
2342 pass
2342 pass
2343 ui.status(_("no changes found\n"))
2343 ui.status(_("no changes found\n"))
2344 return 1
2344 return 1
2345
2345
2346 cleanup = None
2346 cleanup = None
2347 try:
2347 try:
2348 fname = opts["bundle"]
2348 fname = opts["bundle"]
2349 if fname or not other.local():
2349 if fname or not other.local():
2350 # create a bundle (uncompressed if other repo is not local)
2350 # create a bundle (uncompressed if other repo is not local)
2351
2351
2352 if revs is None and other.capable('changegroupsubset'):
2352 if revs is None and other.capable('changegroupsubset'):
2353 revs = rheads
2353 revs = rheads
2354
2354
2355 if revs is None:
2355 if revs is None:
2356 cg = other.changegroup(incoming, "incoming")
2356 cg = other.changegroup(incoming, "incoming")
2357 else:
2357 else:
2358 cg = other.changegroupsubset(incoming, revs, 'incoming')
2358 cg = other.changegroupsubset(incoming, revs, 'incoming')
2359 bundletype = other.local() and "HG10BZ" or "HG10UN"
2359 bundletype = other.local() and "HG10BZ" or "HG10UN"
2360 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
2360 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
2361 # keep written bundle?
2361 # keep written bundle?
2362 if opts["bundle"]:
2362 if opts["bundle"]:
2363 cleanup = None
2363 cleanup = None
2364 if not other.local():
2364 if not other.local():
2365 # use the created uncompressed bundlerepo
2365 # use the created uncompressed bundlerepo
2366 other = bundlerepo.bundlerepository(ui, repo.root, fname)
2366 other = bundlerepo.bundlerepository(ui, repo.root, fname)
2367
2367
2368 o = other.changelog.nodesbetween(incoming, revs)[0]
2368 o = other.changelog.nodesbetween(incoming, revs)[0]
2369 if opts.get('newest_first'):
2369 if opts.get('newest_first'):
2370 o.reverse()
2370 o.reverse()
2371 displayer = cmdutil.show_changeset(ui, other, opts)
2371 displayer = cmdutil.show_changeset(ui, other, opts)
2372 count = 0
2372 count = 0
2373 for n in o:
2373 for n in o:
2374 if limit is not None and count >= limit:
2374 if limit is not None and count >= limit:
2375 break
2375 break
2376 parents = [p for p in other.changelog.parents(n) if p != nullid]
2376 parents = [p for p in other.changelog.parents(n) if p != nullid]
2377 if opts.get('no_merges') and len(parents) == 2:
2377 if opts.get('no_merges') and len(parents) == 2:
2378 continue
2378 continue
2379 count += 1
2379 count += 1
2380 displayer.show(other[n])
2380 displayer.show(other[n])
2381 displayer.close()
2381 displayer.close()
2382 finally:
2382 finally:
2383 if hasattr(other, 'close'):
2383 if hasattr(other, 'close'):
2384 other.close()
2384 other.close()
2385 if cleanup:
2385 if cleanup:
2386 os.unlink(cleanup)
2386 os.unlink(cleanup)
2387
2387
2388 def init(ui, dest=".", **opts):
2388 def init(ui, dest=".", **opts):
2389 """create a new repository in the given directory
2389 """create a new repository in the given directory
2390
2390
2391 Initialize a new repository in the given directory. If the given
2391 Initialize a new repository in the given directory. If the given
2392 directory does not exist, it will be created.
2392 directory does not exist, it will be created.
2393
2393
2394 If no directory is given, the current directory is used.
2394 If no directory is given, the current directory is used.
2395
2395
2396 It is possible to specify an ``ssh://`` URL as the destination.
2396 It is possible to specify an ``ssh://`` URL as the destination.
2397 See :hg:`help urls` for more information.
2397 See :hg:`help urls` for more information.
2398
2398
2399 Returns 0 on success.
2399 Returns 0 on success.
2400 """
2400 """
2401 hg.repository(hg.remoteui(ui, opts), dest, create=1)
2401 hg.repository(hg.remoteui(ui, opts), dest, create=1)
2402
2402
2403 def locate(ui, repo, *pats, **opts):
2403 def locate(ui, repo, *pats, **opts):
2404 """locate files matching specific patterns
2404 """locate files matching specific patterns
2405
2405
2406 Print files under Mercurial control in the working directory whose
2406 Print files under Mercurial control in the working directory whose
2407 names match the given patterns.
2407 names match the given patterns.
2408
2408
2409 By default, this command searches all directories in the working
2409 By default, this command searches all directories in the working
2410 directory. To search just the current directory and its
2410 directory. To search just the current directory and its
2411 subdirectories, use "--include .".
2411 subdirectories, use "--include .".
2412
2412
2413 If no patterns are given to match, this command prints the names
2413 If no patterns are given to match, this command prints the names
2414 of all files under Mercurial control in the working directory.
2414 of all files under Mercurial control in the working directory.
2415
2415
2416 If you want to feed the output of this command into the "xargs"
2416 If you want to feed the output of this command into the "xargs"
2417 command, use the -0 option to both this command and "xargs". This
2417 command, use the -0 option to both this command and "xargs". This
2418 will avoid the problem of "xargs" treating single filenames that
2418 will avoid the problem of "xargs" treating single filenames that
2419 contain whitespace as multiple filenames.
2419 contain whitespace as multiple filenames.
2420
2420
2421 Returns 0 if a match is found, 1 otherwise.
2421 Returns 0 if a match is found, 1 otherwise.
2422 """
2422 """
2423 end = opts.get('print0') and '\0' or '\n'
2423 end = opts.get('print0') and '\0' or '\n'
2424 rev = opts.get('rev') or None
2424 rev = opts.get('rev') or None
2425
2425
2426 ret = 1
2426 ret = 1
2427 m = cmdutil.match(repo, pats, opts, default='relglob')
2427 m = cmdutil.match(repo, pats, opts, default='relglob')
2428 m.bad = lambda x, y: False
2428 m.bad = lambda x, y: False
2429 for abs in repo[rev].walk(m):
2429 for abs in repo[rev].walk(m):
2430 if not rev and abs not in repo.dirstate:
2430 if not rev and abs not in repo.dirstate:
2431 continue
2431 continue
2432 if opts.get('fullpath'):
2432 if opts.get('fullpath'):
2433 ui.write(repo.wjoin(abs), end)
2433 ui.write(repo.wjoin(abs), end)
2434 else:
2434 else:
2435 ui.write(((pats and m.rel(abs)) or abs), end)
2435 ui.write(((pats and m.rel(abs)) or abs), end)
2436 ret = 0
2436 ret = 0
2437
2437
2438 return ret
2438 return ret
2439
2439
2440 def log(ui, repo, *pats, **opts):
2440 def log(ui, repo, *pats, **opts):
2441 """show revision history of entire repository or files
2441 """show revision history of entire repository or files
2442
2442
2443 Print the revision history of the specified files or the entire
2443 Print the revision history of the specified files or the entire
2444 project.
2444 project.
2445
2445
2446 File history is shown without following rename or copy history of
2446 File history is shown without following rename or copy history of
2447 files. Use -f/--follow with a filename to follow history across
2447 files. Use -f/--follow with a filename to follow history across
2448 renames and copies. --follow without a filename will only show
2448 renames and copies. --follow without a filename will only show
2449 ancestors or descendants of the starting revision. --follow-first
2449 ancestors or descendants of the starting revision. --follow-first
2450 only follows the first parent of merge revisions.
2450 only follows the first parent of merge revisions.
2451
2451
2452 If no revision range is specified, the default is tip:0 unless
2452 If no revision range is specified, the default is tip:0 unless
2453 --follow is set, in which case the working directory parent is
2453 --follow is set, in which case the working directory parent is
2454 used as the starting revision. You can specify a revision set for
2454 used as the starting revision. You can specify a revision set for
2455 log, see :hg:`help revsets` for more information.
2455 log, see :hg:`help revsets` for more information.
2456
2456
2457 See :hg:`help dates` for a list of formats valid for -d/--date.
2457 See :hg:`help dates` for a list of formats valid for -d/--date.
2458
2458
2459 By default this command prints revision number and changeset id,
2459 By default this command prints revision number and changeset id,
2460 tags, non-trivial parents, user, date and time, and a summary for
2460 tags, non-trivial parents, user, date and time, and a summary for
2461 each commit. When the -v/--verbose switch is used, the list of
2461 each commit. When the -v/--verbose switch is used, the list of
2462 changed files and full commit message are shown.
2462 changed files and full commit message are shown.
2463
2463
2464 NOTE: log -p/--patch may generate unexpected diff output for merge
2464 NOTE: log -p/--patch may generate unexpected diff output for merge
2465 changesets, as it will only compare the merge changeset against
2465 changesets, as it will only compare the merge changeset against
2466 its first parent. Also, only files different from BOTH parents
2466 its first parent. Also, only files different from BOTH parents
2467 will appear in files:.
2467 will appear in files:.
2468
2468
2469 Returns 0 on success.
2469 Returns 0 on success.
2470 """
2470 """
2471
2471
2472 matchfn = cmdutil.match(repo, pats, opts)
2472 matchfn = cmdutil.match(repo, pats, opts)
2473 limit = cmdutil.loglimit(opts)
2473 limit = cmdutil.loglimit(opts)
2474 count = 0
2474 count = 0
2475
2475
2476 endrev = None
2476 endrev = None
2477 if opts.get('copies') and opts.get('rev'):
2477 if opts.get('copies') and opts.get('rev'):
2478 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2478 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2479
2479
2480 df = False
2480 df = False
2481 if opts["date"]:
2481 if opts["date"]:
2482 df = util.matchdate(opts["date"])
2482 df = util.matchdate(opts["date"])
2483
2483
2484 branches = opts.get('branch', []) + opts.get('only_branch', [])
2484 branches = opts.get('branch', []) + opts.get('only_branch', [])
2485 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2485 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2486
2486
2487 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
2487 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
2488 def prep(ctx, fns):
2488 def prep(ctx, fns):
2489 rev = ctx.rev()
2489 rev = ctx.rev()
2490 parents = [p for p in repo.changelog.parentrevs(rev)
2490 parents = [p for p in repo.changelog.parentrevs(rev)
2491 if p != nullrev]
2491 if p != nullrev]
2492 if opts.get('no_merges') and len(parents) == 2:
2492 if opts.get('no_merges') and len(parents) == 2:
2493 return
2493 return
2494 if opts.get('only_merges') and len(parents) != 2:
2494 if opts.get('only_merges') and len(parents) != 2:
2495 return
2495 return
2496 if opts.get('branch') and ctx.branch() not in opts['branch']:
2496 if opts.get('branch') and ctx.branch() not in opts['branch']:
2497 return
2497 return
2498 if df and not df(ctx.date()[0]):
2498 if df and not df(ctx.date()[0]):
2499 return
2499 return
2500 if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
2500 if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
2501 return
2501 return
2502 if opts.get('keyword'):
2502 if opts.get('keyword'):
2503 for k in [kw.lower() for kw in opts['keyword']]:
2503 for k in [kw.lower() for kw in opts['keyword']]:
2504 if (k in ctx.user().lower() or
2504 if (k in ctx.user().lower() or
2505 k in ctx.description().lower() or
2505 k in ctx.description().lower() or
2506 k in " ".join(ctx.files()).lower()):
2506 k in " ".join(ctx.files()).lower()):
2507 break
2507 break
2508 else:
2508 else:
2509 return
2509 return
2510
2510
2511 copies = None
2511 copies = None
2512 if opts.get('copies') and rev:
2512 if opts.get('copies') and rev:
2513 copies = []
2513 copies = []
2514 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2514 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2515 for fn in ctx.files():
2515 for fn in ctx.files():
2516 rename = getrenamed(fn, rev)
2516 rename = getrenamed(fn, rev)
2517 if rename:
2517 if rename:
2518 copies.append((fn, rename[0]))
2518 copies.append((fn, rename[0]))
2519
2519
2520 displayer.show(ctx, copies=copies)
2520 displayer.show(ctx, copies=copies)
2521
2521
2522 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2522 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2523 if count == limit:
2523 if count == limit:
2524 break
2524 break
2525 if displayer.flush(ctx.rev()):
2525 if displayer.flush(ctx.rev()):
2526 count += 1
2526 count += 1
2527 displayer.close()
2527 displayer.close()
2528
2528
2529 def manifest(ui, repo, node=None, rev=None):
2529 def manifest(ui, repo, node=None, rev=None):
2530 """output the current or given revision of the project manifest
2530 """output the current or given revision of the project manifest
2531
2531
2532 Print a list of version controlled files for the given revision.
2532 Print a list of version controlled files for the given revision.
2533 If no revision is given, the first parent of the working directory
2533 If no revision is given, the first parent of the working directory
2534 is used, or the null revision if no revision is checked out.
2534 is used, or the null revision if no revision is checked out.
2535
2535
2536 With -v, print file permissions, symlink and executable bits.
2536 With -v, print file permissions, symlink and executable bits.
2537 With --debug, print file revision hashes.
2537 With --debug, print file revision hashes.
2538
2538
2539 Returns 0 on success.
2539 Returns 0 on success.
2540 """
2540 """
2541
2541
2542 if rev and node:
2542 if rev and node:
2543 raise util.Abort(_("please specify just one revision"))
2543 raise util.Abort(_("please specify just one revision"))
2544
2544
2545 if not node:
2545 if not node:
2546 node = rev
2546 node = rev
2547
2547
2548 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2548 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2549 ctx = repo[node]
2549 ctx = repo[node]
2550 for f in ctx:
2550 for f in ctx:
2551 if ui.debugflag:
2551 if ui.debugflag:
2552 ui.write("%40s " % hex(ctx.manifest()[f]))
2552 ui.write("%40s " % hex(ctx.manifest()[f]))
2553 if ui.verbose:
2553 if ui.verbose:
2554 ui.write(decor[ctx.flags(f)])
2554 ui.write(decor[ctx.flags(f)])
2555 ui.write("%s\n" % f)
2555 ui.write("%s\n" % f)
2556
2556
2557 def merge(ui, repo, node=None, **opts):
2557 def merge(ui, repo, node=None, **opts):
2558 """merge working directory with another revision
2558 """merge working directory with another revision
2559
2559
2560 The current working directory is updated with all changes made in
2560 The current working directory is updated with all changes made in
2561 the requested revision since the last common predecessor revision.
2561 the requested revision since the last common predecessor revision.
2562
2562
2563 Files that changed between either parent are marked as changed for
2563 Files that changed between either parent are marked as changed for
2564 the next commit and a commit must be performed before any further
2564 the next commit and a commit must be performed before any further
2565 updates to the repository are allowed. The next commit will have
2565 updates to the repository are allowed. The next commit will have
2566 two parents.
2566 two parents.
2567
2567
2568 If no revision is specified, the working directory's parent is a
2568 If no revision is specified, the working directory's parent is a
2569 head revision, and the current branch contains exactly one other
2569 head revision, and the current branch contains exactly one other
2570 head, the other head is merged with by default. Otherwise, an
2570 head, the other head is merged with by default. Otherwise, an
2571 explicit revision with which to merge with must be provided.
2571 explicit revision with which to merge with must be provided.
2572
2572
2573 To undo an uncommitted merge, use :hg:`update --clean .` which
2573 To undo an uncommitted merge, use :hg:`update --clean .` which
2574 will check out a clean copy of the original merge parent, losing
2574 will check out a clean copy of the original merge parent, losing
2575 all changes.
2575 all changes.
2576
2576
2577 Returns 0 on success, 1 if there are unresolved files.
2577 Returns 0 on success, 1 if there are unresolved files.
2578 """
2578 """
2579
2579
2580 if opts.get('rev') and node:
2580 if opts.get('rev') and node:
2581 raise util.Abort(_("please specify just one revision"))
2581 raise util.Abort(_("please specify just one revision"))
2582 if not node:
2582 if not node:
2583 node = opts.get('rev')
2583 node = opts.get('rev')
2584
2584
2585 if not node:
2585 if not node:
2586 branch = repo.changectx(None).branch()
2586 branch = repo.changectx(None).branch()
2587 bheads = repo.branchheads(branch)
2587 bheads = repo.branchheads(branch)
2588 if len(bheads) > 2:
2588 if len(bheads) > 2:
2589 raise util.Abort(_(
2589 raise util.Abort(_(
2590 'branch \'%s\' has %d heads - '
2590 'branch \'%s\' has %d heads - '
2591 'please merge with an explicit rev\n'
2591 'please merge with an explicit rev\n'
2592 '(run \'hg heads .\' to see heads)')
2592 '(run \'hg heads .\' to see heads)')
2593 % (branch, len(bheads)))
2593 % (branch, len(bheads)))
2594
2594
2595 parent = repo.dirstate.parents()[0]
2595 parent = repo.dirstate.parents()[0]
2596 if len(bheads) == 1:
2596 if len(bheads) == 1:
2597 if len(repo.heads()) > 1:
2597 if len(repo.heads()) > 1:
2598 raise util.Abort(_(
2598 raise util.Abort(_(
2599 'branch \'%s\' has one head - '
2599 'branch \'%s\' has one head - '
2600 'please merge with an explicit rev\n'
2600 'please merge with an explicit rev\n'
2601 '(run \'hg heads\' to see all heads)')
2601 '(run \'hg heads\' to see all heads)')
2602 % branch)
2602 % branch)
2603 msg = _('there is nothing to merge')
2603 msg = _('there is nothing to merge')
2604 if parent != repo.lookup(repo[None].branch()):
2604 if parent != repo.lookup(repo[None].branch()):
2605 msg = _('%s - use "hg update" instead') % msg
2605 msg = _('%s - use "hg update" instead') % msg
2606 raise util.Abort(msg)
2606 raise util.Abort(msg)
2607
2607
2608 if parent not in bheads:
2608 if parent not in bheads:
2609 raise util.Abort(_('working dir not at a head rev - '
2609 raise util.Abort(_('working dir not at a head rev - '
2610 'use "hg update" or merge with an explicit rev'))
2610 'use "hg update" or merge with an explicit rev'))
2611 node = parent == bheads[0] and bheads[-1] or bheads[0]
2611 node = parent == bheads[0] and bheads[-1] or bheads[0]
2612
2612
2613 if opts.get('preview'):
2613 if opts.get('preview'):
2614 # find nodes that are ancestors of p2 but not of p1
2614 # find nodes that are ancestors of p2 but not of p1
2615 p1 = repo.lookup('.')
2615 p1 = repo.lookup('.')
2616 p2 = repo.lookup(node)
2616 p2 = repo.lookup(node)
2617 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2617 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2618
2618
2619 displayer = cmdutil.show_changeset(ui, repo, opts)
2619 displayer = cmdutil.show_changeset(ui, repo, opts)
2620 for node in nodes:
2620 for node in nodes:
2621 displayer.show(repo[node])
2621 displayer.show(repo[node])
2622 displayer.close()
2622 displayer.close()
2623 return 0
2623 return 0
2624
2624
2625 return hg.merge(repo, node, force=opts.get('force'))
2625 return hg.merge(repo, node, force=opts.get('force'))
2626
2626
2627 def outgoing(ui, repo, dest=None, **opts):
2627 def outgoing(ui, repo, dest=None, **opts):
2628 """show changesets not found in the destination
2628 """show changesets not found in the destination
2629
2629
2630 Show changesets not found in the specified destination repository
2630 Show changesets not found in the specified destination repository
2631 or the default push location. These are the changesets that would
2631 or the default push location. These are the changesets that would
2632 be pushed if a push was requested.
2632 be pushed if a push was requested.
2633
2633
2634 See pull for details of valid destination formats.
2634 See pull for details of valid destination formats.
2635
2635
2636 Returns 0 if there are outgoing changes, 1 otherwise.
2636 Returns 0 if there are outgoing changes, 1 otherwise.
2637 """
2637 """
2638 limit = cmdutil.loglimit(opts)
2638 limit = cmdutil.loglimit(opts)
2639 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2639 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2640 dest, branches = hg.parseurl(dest, opts.get('branch'))
2640 dest, branches = hg.parseurl(dest, opts.get('branch'))
2641 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2641 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2642 if revs:
2642 if revs:
2643 revs = [repo.lookup(rev) for rev in revs]
2643 revs = [repo.lookup(rev) for rev in revs]
2644
2644
2645 other = hg.repository(hg.remoteui(repo, opts), dest)
2645 other = hg.repository(hg.remoteui(repo, opts), dest)
2646 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2646 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2647 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
2647 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
2648 if not o:
2648 if not o:
2649 ui.status(_("no changes found\n"))
2649 ui.status(_("no changes found\n"))
2650 return 1
2650 return 1
2651 o = repo.changelog.nodesbetween(o, revs)[0]
2651 o = repo.changelog.nodesbetween(o, revs)[0]
2652 if opts.get('newest_first'):
2652 if opts.get('newest_first'):
2653 o.reverse()
2653 o.reverse()
2654 displayer = cmdutil.show_changeset(ui, repo, opts)
2654 displayer = cmdutil.show_changeset(ui, repo, opts)
2655 count = 0
2655 count = 0
2656 for n in o:
2656 for n in o:
2657 if limit is not None and count >= limit:
2657 if limit is not None and count >= limit:
2658 break
2658 break
2659 parents = [p for p in repo.changelog.parents(n) if p != nullid]
2659 parents = [p for p in repo.changelog.parents(n) if p != nullid]
2660 if opts.get('no_merges') and len(parents) == 2:
2660 if opts.get('no_merges') and len(parents) == 2:
2661 continue
2661 continue
2662 count += 1
2662 count += 1
2663 displayer.show(repo[n])
2663 displayer.show(repo[n])
2664 displayer.close()
2664 displayer.close()
2665
2665
2666 def parents(ui, repo, file_=None, **opts):
2666 def parents(ui, repo, file_=None, **opts):
2667 """show the parents of the working directory or revision
2667 """show the parents of the working directory or revision
2668
2668
2669 Print the working directory's parent revisions. If a revision is
2669 Print the working directory's parent revisions. If a revision is
2670 given via -r/--rev, the parent of that revision will be printed.
2670 given via -r/--rev, the parent of that revision will be printed.
2671 If a file argument is given, the revision in which the file was
2671 If a file argument is given, the revision in which the file was
2672 last changed (before the working directory revision or the
2672 last changed (before the working directory revision or the
2673 argument to --rev if given) is printed.
2673 argument to --rev if given) is printed.
2674
2674
2675 Returns 0 on success.
2675 Returns 0 on success.
2676 """
2676 """
2677 rev = opts.get('rev')
2677 rev = opts.get('rev')
2678 if rev:
2678 if rev:
2679 ctx = repo[rev]
2679 ctx = repo[rev]
2680 else:
2680 else:
2681 ctx = repo[None]
2681 ctx = repo[None]
2682
2682
2683 if file_:
2683 if file_:
2684 m = cmdutil.match(repo, (file_,), opts)
2684 m = cmdutil.match(repo, (file_,), opts)
2685 if m.anypats() or len(m.files()) != 1:
2685 if m.anypats() or len(m.files()) != 1:
2686 raise util.Abort(_('can only specify an explicit filename'))
2686 raise util.Abort(_('can only specify an explicit filename'))
2687 file_ = m.files()[0]
2687 file_ = m.files()[0]
2688 filenodes = []
2688 filenodes = []
2689 for cp in ctx.parents():
2689 for cp in ctx.parents():
2690 if not cp:
2690 if not cp:
2691 continue
2691 continue
2692 try:
2692 try:
2693 filenodes.append(cp.filenode(file_))
2693 filenodes.append(cp.filenode(file_))
2694 except error.LookupError:
2694 except error.LookupError:
2695 pass
2695 pass
2696 if not filenodes:
2696 if not filenodes:
2697 raise util.Abort(_("'%s' not found in manifest!") % file_)
2697 raise util.Abort(_("'%s' not found in manifest!") % file_)
2698 fl = repo.file(file_)
2698 fl = repo.file(file_)
2699 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2699 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2700 else:
2700 else:
2701 p = [cp.node() for cp in ctx.parents()]
2701 p = [cp.node() for cp in ctx.parents()]
2702
2702
2703 displayer = cmdutil.show_changeset(ui, repo, opts)
2703 displayer = cmdutil.show_changeset(ui, repo, opts)
2704 for n in p:
2704 for n in p:
2705 if n != nullid:
2705 if n != nullid:
2706 displayer.show(repo[n])
2706 displayer.show(repo[n])
2707 displayer.close()
2707 displayer.close()
2708
2708
2709 def paths(ui, repo, search=None):
2709 def paths(ui, repo, search=None):
2710 """show aliases for remote repositories
2710 """show aliases for remote repositories
2711
2711
2712 Show definition of symbolic path name NAME. If no name is given,
2712 Show definition of symbolic path name NAME. If no name is given,
2713 show definition of all available names.
2713 show definition of all available names.
2714
2714
2715 Path names are defined in the [paths] section of
2715 Path names are defined in the [paths] section of
2716 ``/etc/mercurial/hgrc`` and ``$HOME/.hgrc``. If run inside a
2716 ``/etc/mercurial/hgrc`` and ``$HOME/.hgrc``. If run inside a
2717 repository, ``.hg/hgrc`` is used, too.
2717 repository, ``.hg/hgrc`` is used, too.
2718
2718
2719 The path names ``default`` and ``default-push`` have a special
2719 The path names ``default`` and ``default-push`` have a special
2720 meaning. When performing a push or pull operation, they are used
2720 meaning. When performing a push or pull operation, they are used
2721 as fallbacks if no location is specified on the command-line.
2721 as fallbacks if no location is specified on the command-line.
2722 When ``default-push`` is set, it will be used for push and
2722 When ``default-push`` is set, it will be used for push and
2723 ``default`` will be used for pull; otherwise ``default`` is used
2723 ``default`` will be used for pull; otherwise ``default`` is used
2724 as the fallback for both. When cloning a repository, the clone
2724 as the fallback for both. When cloning a repository, the clone
2725 source is written as ``default`` in ``.hg/hgrc``. Note that
2725 source is written as ``default`` in ``.hg/hgrc``. Note that
2726 ``default`` and ``default-push`` apply to all inbound (e.g.
2726 ``default`` and ``default-push`` apply to all inbound (e.g.
2727 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2727 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2728 :hg:`bundle`) operations.
2728 :hg:`bundle`) operations.
2729
2729
2730 See :hg:`help urls` for more information.
2730 See :hg:`help urls` for more information.
2731 """
2731 """
2732 if search:
2732 if search:
2733 for name, path in ui.configitems("paths"):
2733 for name, path in ui.configitems("paths"):
2734 if name == search:
2734 if name == search:
2735 ui.write("%s\n" % url.hidepassword(path))
2735 ui.write("%s\n" % url.hidepassword(path))
2736 return
2736 return
2737 ui.warn(_("not found!\n"))
2737 ui.warn(_("not found!\n"))
2738 return 1
2738 return 1
2739 else:
2739 else:
2740 for name, path in ui.configitems("paths"):
2740 for name, path in ui.configitems("paths"):
2741 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2741 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2742
2742
2743 def postincoming(ui, repo, modheads, optupdate, checkout):
2743 def postincoming(ui, repo, modheads, optupdate, checkout):
2744 if modheads == 0:
2744 if modheads == 0:
2745 return
2745 return
2746 if optupdate:
2746 if optupdate:
2747 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2747 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2748 return hg.update(repo, checkout)
2748 return hg.update(repo, checkout)
2749 else:
2749 else:
2750 ui.status(_("not updating, since new heads added\n"))
2750 ui.status(_("not updating, since new heads added\n"))
2751 if modheads > 1:
2751 if modheads > 1:
2752 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2752 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2753 else:
2753 else:
2754 ui.status(_("(run 'hg update' to get a working copy)\n"))
2754 ui.status(_("(run 'hg update' to get a working copy)\n"))
2755
2755
2756 def pull(ui, repo, source="default", **opts):
2756 def pull(ui, repo, source="default", **opts):
2757 """pull changes from the specified source
2757 """pull changes from the specified source
2758
2758
2759 Pull changes from a remote repository to a local one.
2759 Pull changes from a remote repository to a local one.
2760
2760
2761 This finds all changes from the repository at the specified path
2761 This finds all changes from the repository at the specified path
2762 or URL and adds them to a local repository (the current one unless
2762 or URL and adds them to a local repository (the current one unless
2763 -R is specified). By default, this does not update the copy of the
2763 -R is specified). By default, this does not update the copy of the
2764 project in the working directory.
2764 project in the working directory.
2765
2765
2766 Use :hg:`incoming` if you want to see what would have been added
2766 Use :hg:`incoming` if you want to see what would have been added
2767 by a pull at the time you issued this command. If you then decide
2767 by a pull at the time you issued this command. If you then decide
2768 to add those changes to the repository, you should use :hg:`pull
2768 to add those changes to the repository, you should use :hg:`pull
2769 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
2769 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
2770
2770
2771 If SOURCE is omitted, the 'default' path will be used.
2771 If SOURCE is omitted, the 'default' path will be used.
2772 See :hg:`help urls` for more information.
2772 See :hg:`help urls` for more information.
2773
2773
2774 Returns 0 on success, 1 if an update had unresolved files.
2774 Returns 0 on success, 1 if an update had unresolved files.
2775 """
2775 """
2776 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2776 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2777 other = hg.repository(hg.remoteui(repo, opts), source)
2777 other = hg.repository(hg.remoteui(repo, opts), source)
2778 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2778 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2779 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2779 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2780 if revs:
2780 if revs:
2781 try:
2781 try:
2782 revs = [other.lookup(rev) for rev in revs]
2782 revs = [other.lookup(rev) for rev in revs]
2783 except error.CapabilityError:
2783 except error.CapabilityError:
2784 err = _("Other repository doesn't support revision lookup, "
2784 err = _("Other repository doesn't support revision lookup, "
2785 "so a rev cannot be specified.")
2785 "so a rev cannot be specified.")
2786 raise util.Abort(err)
2786 raise util.Abort(err)
2787
2787
2788 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2788 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2789 if checkout:
2789 if checkout:
2790 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2790 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2791 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2791 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2792
2792
2793 def push(ui, repo, dest=None, **opts):
2793 def push(ui, repo, dest=None, **opts):
2794 """push changes to the specified destination
2794 """push changes to the specified destination
2795
2795
2796 Push changesets from the local repository to the specified
2796 Push changesets from the local repository to the specified
2797 destination.
2797 destination.
2798
2798
2799 This operation is symmetrical to pull: it is identical to a pull
2799 This operation is symmetrical to pull: it is identical to a pull
2800 in the destination repository from the current one.
2800 in the destination repository from the current one.
2801
2801
2802 By default, push will not allow creation of new heads at the
2802 By default, push will not allow creation of new heads at the
2803 destination, since multiple heads would make it unclear which head
2803 destination, since multiple heads would make it unclear which head
2804 to use. In this situation, it is recommended to pull and merge
2804 to use. In this situation, it is recommended to pull and merge
2805 before pushing.
2805 before pushing.
2806
2806
2807 Use --new-branch if you want to allow push to create a new named
2807 Use --new-branch if you want to allow push to create a new named
2808 branch that is not present at the destination. This allows you to
2808 branch that is not present at the destination. This allows you to
2809 only create a new branch without forcing other changes.
2809 only create a new branch without forcing other changes.
2810
2810
2811 Use -f/--force to override the default behavior and push all
2811 Use -f/--force to override the default behavior and push all
2812 changesets on all branches.
2812 changesets on all branches.
2813
2813
2814 If -r/--rev is used, the specified revision and all its ancestors
2814 If -r/--rev is used, the specified revision and all its ancestors
2815 will be pushed to the remote repository.
2815 will be pushed to the remote repository.
2816
2816
2817 Please see :hg:`help urls` for important details about ``ssh://``
2817 Please see :hg:`help urls` for important details about ``ssh://``
2818 URLs. If DESTINATION is omitted, a default path will be used.
2818 URLs. If DESTINATION is omitted, a default path will be used.
2819
2819
2820 Returns 0 if push was successful, 1 if nothing to push.
2820 Returns 0 if push was successful, 1 if nothing to push.
2821 """
2821 """
2822 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2822 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2823 dest, branches = hg.parseurl(dest, opts.get('branch'))
2823 dest, branches = hg.parseurl(dest, opts.get('branch'))
2824 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2824 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2825 other = hg.repository(hg.remoteui(repo, opts), dest)
2825 other = hg.repository(hg.remoteui(repo, opts), dest)
2826 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2826 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2827 if revs:
2827 if revs:
2828 revs = [repo.lookup(rev) for rev in revs]
2828 revs = [repo.lookup(rev) for rev in revs]
2829
2829
2830 # push subrepos depth-first for coherent ordering
2830 # push subrepos depth-first for coherent ordering
2831 c = repo['']
2831 c = repo['']
2832 subs = c.substate # only repos that are committed
2832 subs = c.substate # only repos that are committed
2833 for s in sorted(subs):
2833 for s in sorted(subs):
2834 if not c.sub(s).push(opts.get('force')):
2834 if not c.sub(s).push(opts.get('force')):
2835 return False
2835 return False
2836
2836
2837 r = repo.push(other, opts.get('force'), revs=revs,
2837 r = repo.push(other, opts.get('force'), revs=revs,
2838 newbranch=opts.get('new_branch'))
2838 newbranch=opts.get('new_branch'))
2839 return r == 0
2839 return r == 0
2840
2840
2841 def recover(ui, repo):
2841 def recover(ui, repo):
2842 """roll back an interrupted transaction
2842 """roll back an interrupted transaction
2843
2843
2844 Recover from an interrupted commit or pull.
2844 Recover from an interrupted commit or pull.
2845
2845
2846 This command tries to fix the repository status after an
2846 This command tries to fix the repository status after an
2847 interrupted operation. It should only be necessary when Mercurial
2847 interrupted operation. It should only be necessary when Mercurial
2848 suggests it.
2848 suggests it.
2849
2849
2850 Returns 0 if successful, 1 if nothing to recover or verify fails.
2850 Returns 0 if successful, 1 if nothing to recover or verify fails.
2851 """
2851 """
2852 if repo.recover():
2852 if repo.recover():
2853 return hg.verify(repo)
2853 return hg.verify(repo)
2854 return 1
2854 return 1
2855
2855
2856 def remove(ui, repo, *pats, **opts):
2856 def remove(ui, repo, *pats, **opts):
2857 """remove the specified files on the next commit
2857 """remove the specified files on the next commit
2858
2858
2859 Schedule the indicated files for removal from the repository.
2859 Schedule the indicated files for removal from the repository.
2860
2860
2861 This only removes files from the current branch, not from the
2861 This only removes files from the current branch, not from the
2862 entire project history. -A/--after can be used to remove only
2862 entire project history. -A/--after can be used to remove only
2863 files that have already been deleted, -f/--force can be used to
2863 files that have already been deleted, -f/--force can be used to
2864 force deletion, and -Af can be used to remove files from the next
2864 force deletion, and -Af can be used to remove files from the next
2865 revision without deleting them from the working directory.
2865 revision without deleting them from the working directory.
2866
2866
2867 The following table details the behavior of remove for different
2867 The following table details the behavior of remove for different
2868 file states (columns) and option combinations (rows). The file
2868 file states (columns) and option combinations (rows). The file
2869 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
2869 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
2870 reported by :hg:`status`). The actions are Warn, Remove (from
2870 reported by :hg:`status`). The actions are Warn, Remove (from
2871 branch) and Delete (from disk)::
2871 branch) and Delete (from disk)::
2872
2872
2873 A C M !
2873 A C M !
2874 none W RD W R
2874 none W RD W R
2875 -f R RD RD R
2875 -f R RD RD R
2876 -A W W W R
2876 -A W W W R
2877 -Af R R R R
2877 -Af R R R R
2878
2878
2879 This command schedules the files to be removed at the next commit.
2879 This command schedules the files to be removed at the next commit.
2880 To undo a remove before that, see :hg:`revert`.
2880 To undo a remove before that, see :hg:`revert`.
2881
2881
2882 Returns 0 on success, 1 if any warnings encountered.
2882 Returns 0 on success, 1 if any warnings encountered.
2883 """
2883 """
2884
2884
2885 ret = 0
2885 ret = 0
2886 after, force = opts.get('after'), opts.get('force')
2886 after, force = opts.get('after'), opts.get('force')
2887 if not pats and not after:
2887 if not pats and not after:
2888 raise util.Abort(_('no files specified'))
2888 raise util.Abort(_('no files specified'))
2889
2889
2890 m = cmdutil.match(repo, pats, opts)
2890 m = cmdutil.match(repo, pats, opts)
2891 s = repo.status(match=m, clean=True)
2891 s = repo.status(match=m, clean=True)
2892 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2892 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2893
2893
2894 for f in m.files():
2894 for f in m.files():
2895 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2895 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2896 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2896 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2897 ret = 1
2897 ret = 1
2898
2898
2899 def warn(files, reason):
2899 def warn(files, reason):
2900 for f in files:
2900 for f in files:
2901 ui.warn(_('not removing %s: file %s (use -f to force removal)\n')
2901 ui.warn(_('not removing %s: file %s (use -f to force removal)\n')
2902 % (m.rel(f), reason))
2902 % (m.rel(f), reason))
2903 ret = 1
2903 ret = 1
2904
2904
2905 if force:
2905 if force:
2906 remove, forget = modified + deleted + clean, added
2906 remove, forget = modified + deleted + clean, added
2907 elif after:
2907 elif after:
2908 remove, forget = deleted, []
2908 remove, forget = deleted, []
2909 warn(modified + added + clean, _('still exists'))
2909 warn(modified + added + clean, _('still exists'))
2910 else:
2910 else:
2911 remove, forget = deleted + clean, []
2911 remove, forget = deleted + clean, []
2912 warn(modified, _('is modified'))
2912 warn(modified, _('is modified'))
2913 warn(added, _('has been marked for add'))
2913 warn(added, _('has been marked for add'))
2914
2914
2915 for f in sorted(remove + forget):
2915 for f in sorted(remove + forget):
2916 if ui.verbose or not m.exact(f):
2916 if ui.verbose or not m.exact(f):
2917 ui.status(_('removing %s\n') % m.rel(f))
2917 ui.status(_('removing %s\n') % m.rel(f))
2918
2918
2919 repo[None].forget(forget)
2919 repo[None].forget(forget)
2920 repo[None].remove(remove, unlink=not after)
2920 repo[None].remove(remove, unlink=not after)
2921 return ret
2921 return ret
2922
2922
2923 def rename(ui, repo, *pats, **opts):
2923 def rename(ui, repo, *pats, **opts):
2924 """rename files; equivalent of copy + remove
2924 """rename files; equivalent of copy + remove
2925
2925
2926 Mark dest as copies of sources; mark sources for deletion. If dest
2926 Mark dest as copies of sources; mark sources for deletion. If dest
2927 is a directory, copies are put in that directory. If dest is a
2927 is a directory, copies are put in that directory. If dest is a
2928 file, there can only be one source.
2928 file, there can only be one source.
2929
2929
2930 By default, this command copies the contents of files as they
2930 By default, this command copies the contents of files as they
2931 exist in the working directory. If invoked with -A/--after, the
2931 exist in the working directory. If invoked with -A/--after, the
2932 operation is recorded, but no copying is performed.
2932 operation is recorded, but no copying is performed.
2933
2933
2934 This command takes effect at the next commit. To undo a rename
2934 This command takes effect at the next commit. To undo a rename
2935 before that, see :hg:`revert`.
2935 before that, see :hg:`revert`.
2936
2936
2937 Returns 0 on success, 1 if errors are encountered.
2937 Returns 0 on success, 1 if errors are encountered.
2938 """
2938 """
2939 wlock = repo.wlock(False)
2939 wlock = repo.wlock(False)
2940 try:
2940 try:
2941 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2941 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2942 finally:
2942 finally:
2943 wlock.release()
2943 wlock.release()
2944
2944
2945 def resolve(ui, repo, *pats, **opts):
2945 def resolve(ui, repo, *pats, **opts):
2946 """various operations to help finish a merge
2946 """various operations to help finish a merge
2947
2947
2948 This command includes several actions that are often useful while
2948 This command includes several actions that are often useful while
2949 performing a merge, after running ``merge`` but before running
2949 performing a merge, after running ``merge`` but before running
2950 ``commit``. (It is only meaningful if your working directory has
2950 ``commit``. (It is only meaningful if your working directory has
2951 two parents.) It is most relevant for merges with unresolved
2951 two parents.) It is most relevant for merges with unresolved
2952 conflicts, which are typically a result of non-interactive merging with
2952 conflicts, which are typically a result of non-interactive merging with
2953 ``internal:merge`` or a command-line merge tool like ``diff3``.
2953 ``internal:merge`` or a command-line merge tool like ``diff3``.
2954
2954
2955 The available actions are:
2955 The available actions are:
2956
2956
2957 1) list files that were merged with conflicts (U, for unresolved)
2957 1) list files that were merged with conflicts (U, for unresolved)
2958 and without conflicts (R, for resolved): ``hg resolve -l``
2958 and without conflicts (R, for resolved): ``hg resolve -l``
2959 (this is like ``status`` for merges)
2959 (this is like ``status`` for merges)
2960 2) record that you have resolved conflicts in certain files:
2960 2) record that you have resolved conflicts in certain files:
2961 ``hg resolve -m [file ...]`` (default: mark all unresolved files)
2961 ``hg resolve -m [file ...]`` (default: mark all unresolved files)
2962 3) forget that you have resolved conflicts in certain files:
2962 3) forget that you have resolved conflicts in certain files:
2963 ``hg resolve -u [file ...]`` (default: unmark all resolved files)
2963 ``hg resolve -u [file ...]`` (default: unmark all resolved files)
2964 4) discard your current attempt(s) at resolving conflicts and
2964 4) discard your current attempt(s) at resolving conflicts and
2965 restart the merge from scratch: ``hg resolve file...``
2965 restart the merge from scratch: ``hg resolve file...``
2966 (or ``-a`` for all unresolved files)
2966 (or ``-a`` for all unresolved files)
2967
2967
2968 Note that Mercurial will not let you commit files with unresolved merge
2968 Note that Mercurial will not let you commit files with unresolved merge
2969 conflicts. You must use ``hg resolve -m ...`` before you can commit
2969 conflicts. You must use ``hg resolve -m ...`` before you can commit
2970 after a conflicting merge.
2970 after a conflicting merge.
2971
2971
2972 Returns 0 on success, 1 if any files fail a resolve attempt.
2972 Returns 0 on success, 1 if any files fail a resolve attempt.
2973 """
2973 """
2974
2974
2975 all, mark, unmark, show, nostatus = \
2975 all, mark, unmark, show, nostatus = \
2976 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
2976 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
2977
2977
2978 if (show and (mark or unmark)) or (mark and unmark):
2978 if (show and (mark or unmark)) or (mark and unmark):
2979 raise util.Abort(_("too many options specified"))
2979 raise util.Abort(_("too many options specified"))
2980 if pats and all:
2980 if pats and all:
2981 raise util.Abort(_("can't specify --all and patterns"))
2981 raise util.Abort(_("can't specify --all and patterns"))
2982 if not (all or pats or show or mark or unmark):
2982 if not (all or pats or show or mark or unmark):
2983 raise util.Abort(_('no files or directories specified; '
2983 raise util.Abort(_('no files or directories specified; '
2984 'use --all to remerge all files'))
2984 'use --all to remerge all files'))
2985
2985
2986 ms = mergemod.mergestate(repo)
2986 ms = mergemod.mergestate(repo)
2987 m = cmdutil.match(repo, pats, opts)
2987 m = cmdutil.match(repo, pats, opts)
2988 ret = 0
2988 ret = 0
2989
2989
2990 for f in ms:
2990 for f in ms:
2991 if m(f):
2991 if m(f):
2992 if show:
2992 if show:
2993 if nostatus:
2993 if nostatus:
2994 ui.write("%s\n" % f)
2994 ui.write("%s\n" % f)
2995 else:
2995 else:
2996 ui.write("%s %s\n" % (ms[f].upper(), f),
2996 ui.write("%s %s\n" % (ms[f].upper(), f),
2997 label='resolve.' +
2997 label='resolve.' +
2998 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
2998 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
2999 elif mark:
2999 elif mark:
3000 ms.mark(f, "r")
3000 ms.mark(f, "r")
3001 elif unmark:
3001 elif unmark:
3002 ms.mark(f, "u")
3002 ms.mark(f, "u")
3003 else:
3003 else:
3004 wctx = repo[None]
3004 wctx = repo[None]
3005 mctx = wctx.parents()[-1]
3005 mctx = wctx.parents()[-1]
3006
3006
3007 # backup pre-resolve (merge uses .orig for its own purposes)
3007 # backup pre-resolve (merge uses .orig for its own purposes)
3008 a = repo.wjoin(f)
3008 a = repo.wjoin(f)
3009 util.copyfile(a, a + ".resolve")
3009 util.copyfile(a, a + ".resolve")
3010
3010
3011 # resolve file
3011 # resolve file
3012 if ms.resolve(f, wctx, mctx):
3012 if ms.resolve(f, wctx, mctx):
3013 ret = 1
3013 ret = 1
3014
3014
3015 # replace filemerge's .orig file with our resolve file
3015 # replace filemerge's .orig file with our resolve file
3016 util.rename(a + ".resolve", a + ".orig")
3016 util.rename(a + ".resolve", a + ".orig")
3017 return ret
3017 return ret
3018
3018
3019 def revert(ui, repo, *pats, **opts):
3019 def revert(ui, repo, *pats, **opts):
3020 """restore individual files or directories to an earlier state
3020 """restore individual files or directories to an earlier state
3021
3021
3022 (Use update -r to check out earlier revisions, revert does not
3022 NOTE: This command is most likely not what you are looking for. revert
3023 change the working directory parents.)
3023 will partially overwrite content in the working directory without changing
3024 the working directory parents. Use :hg:`update -r rev` to check out earlier
3025 revisions, or :hg:`update --clean .` to undo a merge which has added
3026 another parent.
3024
3027
3025 With no revision specified, revert the named files or directories
3028 With no revision specified, revert the named files or directories
3026 to the contents they had in the parent of the working directory.
3029 to the contents they had in the parent of the working directory.
3027 This restores the contents of the affected files to an unmodified
3030 This restores the contents of the affected files to an unmodified
3028 state and unschedules adds, removes, copies, and renames. If the
3031 state and unschedules adds, removes, copies, and renames. If the
3029 working directory has two parents, you must explicitly specify a
3032 working directory has two parents, you must explicitly specify a
3030 revision.
3033 revision.
3031
3034
3032 Using the -r/--rev option, revert the given files or directories
3035 Using the -r/--rev option, revert the given files or directories
3033 to their contents as of a specific revision. This can be helpful
3036 to their contents as of a specific revision. This can be helpful
3034 to "roll back" some or all of an earlier change. See :hg:`help
3037 to "roll back" some or all of an earlier change. See :hg:`help
3035 dates` for a list of formats valid for -d/--date.
3038 dates` for a list of formats valid for -d/--date.
3036
3039
3037 Revert modifies the working directory. It does not commit any
3040 Revert modifies the working directory. It does not commit any
3038 changes, or change the parent of the working directory. If you
3041 changes, or change the parent of the working directory. If you
3039 revert to a revision other than the parent of the working
3042 revert to a revision other than the parent of the working
3040 directory, the reverted files will thus appear modified
3043 directory, the reverted files will thus appear modified
3041 afterwards.
3044 afterwards.
3042
3045
3043 If a file has been deleted, it is restored. If the executable mode
3046 If a file has been deleted, it is restored. If the executable mode
3044 of a file was changed, it is reset.
3047 of a file was changed, it is reset.
3045
3048
3046 If names are given, all files matching the names are reverted.
3049 If names are given, all files matching the names are reverted.
3047 If no arguments are given, no files are reverted.
3050 If no arguments are given, no files are reverted.
3048
3051
3049 Modified files are saved with a .orig suffix before reverting.
3052 Modified files are saved with a .orig suffix before reverting.
3050 To disable these backups, use --no-backup.
3053 To disable these backups, use --no-backup.
3051
3054
3052 Returns 0 on success.
3055 Returns 0 on success.
3053 """
3056 """
3054
3057
3055 if opts["date"]:
3058 if opts["date"]:
3056 if opts["rev"]:
3059 if opts["rev"]:
3057 raise util.Abort(_("you can't specify a revision and a date"))
3060 raise util.Abort(_("you can't specify a revision and a date"))
3058 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3061 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3059
3062
3060 if not pats and not opts.get('all'):
3063 if not pats and not opts.get('all'):
3061 raise util.Abort(_('no files or directories specified; '
3064 raise util.Abort(_('no files or directories specified; '
3062 'use --all to revert the whole repo'))
3065 'use --all to revert the whole repo'))
3063
3066
3064 parent, p2 = repo.dirstate.parents()
3067 parent, p2 = repo.dirstate.parents()
3065 if not opts.get('rev') and p2 != nullid:
3068 if not opts.get('rev') and p2 != nullid:
3066 raise util.Abort(_('uncommitted merge - please provide a '
3069 raise util.Abort(_('uncommitted merge - please provide a '
3067 'specific revision'))
3070 'specific revision'))
3068 ctx = repo[opts.get('rev')]
3071 ctx = repo[opts.get('rev')]
3069 node = ctx.node()
3072 node = ctx.node()
3070 mf = ctx.manifest()
3073 mf = ctx.manifest()
3071 if node == parent:
3074 if node == parent:
3072 pmf = mf
3075 pmf = mf
3073 else:
3076 else:
3074 pmf = None
3077 pmf = None
3075
3078
3076 # need all matching names in dirstate and manifest of target rev,
3079 # need all matching names in dirstate and manifest of target rev,
3077 # so have to walk both. do not print errors if files exist in one
3080 # so have to walk both. do not print errors if files exist in one
3078 # but not other.
3081 # but not other.
3079
3082
3080 names = {}
3083 names = {}
3081
3084
3082 wlock = repo.wlock()
3085 wlock = repo.wlock()
3083 try:
3086 try:
3084 # walk dirstate.
3087 # walk dirstate.
3085
3088
3086 m = cmdutil.match(repo, pats, opts)
3089 m = cmdutil.match(repo, pats, opts)
3087 m.bad = lambda x, y: False
3090 m.bad = lambda x, y: False
3088 for abs in repo.walk(m):
3091 for abs in repo.walk(m):
3089 names[abs] = m.rel(abs), m.exact(abs)
3092 names[abs] = m.rel(abs), m.exact(abs)
3090
3093
3091 # walk target manifest.
3094 # walk target manifest.
3092
3095
3093 def badfn(path, msg):
3096 def badfn(path, msg):
3094 if path in names:
3097 if path in names:
3095 return
3098 return
3096 path_ = path + '/'
3099 path_ = path + '/'
3097 for f in names:
3100 for f in names:
3098 if f.startswith(path_):
3101 if f.startswith(path_):
3099 return
3102 return
3100 ui.warn("%s: %s\n" % (m.rel(path), msg))
3103 ui.warn("%s: %s\n" % (m.rel(path), msg))
3101
3104
3102 m = cmdutil.match(repo, pats, opts)
3105 m = cmdutil.match(repo, pats, opts)
3103 m.bad = badfn
3106 m.bad = badfn
3104 for abs in repo[node].walk(m):
3107 for abs in repo[node].walk(m):
3105 if abs not in names:
3108 if abs not in names:
3106 names[abs] = m.rel(abs), m.exact(abs)
3109 names[abs] = m.rel(abs), m.exact(abs)
3107
3110
3108 m = cmdutil.matchfiles(repo, names)
3111 m = cmdutil.matchfiles(repo, names)
3109 changes = repo.status(match=m)[:4]
3112 changes = repo.status(match=m)[:4]
3110 modified, added, removed, deleted = map(set, changes)
3113 modified, added, removed, deleted = map(set, changes)
3111
3114
3112 # if f is a rename, also revert the source
3115 # if f is a rename, also revert the source
3113 cwd = repo.getcwd()
3116 cwd = repo.getcwd()
3114 for f in added:
3117 for f in added:
3115 src = repo.dirstate.copied(f)
3118 src = repo.dirstate.copied(f)
3116 if src and src not in names and repo.dirstate[src] == 'r':
3119 if src and src not in names and repo.dirstate[src] == 'r':
3117 removed.add(src)
3120 removed.add(src)
3118 names[src] = (repo.pathto(src, cwd), True)
3121 names[src] = (repo.pathto(src, cwd), True)
3119
3122
3120 def removeforget(abs):
3123 def removeforget(abs):
3121 if repo.dirstate[abs] == 'a':
3124 if repo.dirstate[abs] == 'a':
3122 return _('forgetting %s\n')
3125 return _('forgetting %s\n')
3123 return _('removing %s\n')
3126 return _('removing %s\n')
3124
3127
3125 revert = ([], _('reverting %s\n'))
3128 revert = ([], _('reverting %s\n'))
3126 add = ([], _('adding %s\n'))
3129 add = ([], _('adding %s\n'))
3127 remove = ([], removeforget)
3130 remove = ([], removeforget)
3128 undelete = ([], _('undeleting %s\n'))
3131 undelete = ([], _('undeleting %s\n'))
3129
3132
3130 disptable = (
3133 disptable = (
3131 # dispatch table:
3134 # dispatch table:
3132 # file state
3135 # file state
3133 # action if in target manifest
3136 # action if in target manifest
3134 # action if not in target manifest
3137 # action if not in target manifest
3135 # make backup if in target manifest
3138 # make backup if in target manifest
3136 # make backup if not in target manifest
3139 # make backup if not in target manifest
3137 (modified, revert, remove, True, True),
3140 (modified, revert, remove, True, True),
3138 (added, revert, remove, True, False),
3141 (added, revert, remove, True, False),
3139 (removed, undelete, None, False, False),
3142 (removed, undelete, None, False, False),
3140 (deleted, revert, remove, False, False),
3143 (deleted, revert, remove, False, False),
3141 )
3144 )
3142
3145
3143 for abs, (rel, exact) in sorted(names.items()):
3146 for abs, (rel, exact) in sorted(names.items()):
3144 mfentry = mf.get(abs)
3147 mfentry = mf.get(abs)
3145 target = repo.wjoin(abs)
3148 target = repo.wjoin(abs)
3146 def handle(xlist, dobackup):
3149 def handle(xlist, dobackup):
3147 xlist[0].append(abs)
3150 xlist[0].append(abs)
3148 if dobackup and not opts.get('no_backup') and util.lexists(target):
3151 if dobackup and not opts.get('no_backup') and util.lexists(target):
3149 bakname = "%s.orig" % rel
3152 bakname = "%s.orig" % rel
3150 ui.note(_('saving current version of %s as %s\n') %
3153 ui.note(_('saving current version of %s as %s\n') %
3151 (rel, bakname))
3154 (rel, bakname))
3152 if not opts.get('dry_run'):
3155 if not opts.get('dry_run'):
3153 util.copyfile(target, bakname)
3156 util.copyfile(target, bakname)
3154 if ui.verbose or not exact:
3157 if ui.verbose or not exact:
3155 msg = xlist[1]
3158 msg = xlist[1]
3156 if not isinstance(msg, basestring):
3159 if not isinstance(msg, basestring):
3157 msg = msg(abs)
3160 msg = msg(abs)
3158 ui.status(msg % rel)
3161 ui.status(msg % rel)
3159 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3162 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3160 if abs not in table:
3163 if abs not in table:
3161 continue
3164 continue
3162 # file has changed in dirstate
3165 # file has changed in dirstate
3163 if mfentry:
3166 if mfentry:
3164 handle(hitlist, backuphit)
3167 handle(hitlist, backuphit)
3165 elif misslist is not None:
3168 elif misslist is not None:
3166 handle(misslist, backupmiss)
3169 handle(misslist, backupmiss)
3167 break
3170 break
3168 else:
3171 else:
3169 if abs not in repo.dirstate:
3172 if abs not in repo.dirstate:
3170 if mfentry:
3173 if mfentry:
3171 handle(add, True)
3174 handle(add, True)
3172 elif exact:
3175 elif exact:
3173 ui.warn(_('file not managed: %s\n') % rel)
3176 ui.warn(_('file not managed: %s\n') % rel)
3174 continue
3177 continue
3175 # file has not changed in dirstate
3178 # file has not changed in dirstate
3176 if node == parent:
3179 if node == parent:
3177 if exact:
3180 if exact:
3178 ui.warn(_('no changes needed to %s\n') % rel)
3181 ui.warn(_('no changes needed to %s\n') % rel)
3179 continue
3182 continue
3180 if pmf is None:
3183 if pmf is None:
3181 # only need parent manifest in this unlikely case,
3184 # only need parent manifest in this unlikely case,
3182 # so do not read by default
3185 # so do not read by default
3183 pmf = repo[parent].manifest()
3186 pmf = repo[parent].manifest()
3184 if abs in pmf:
3187 if abs in pmf:
3185 if mfentry:
3188 if mfentry:
3186 # if version of file is same in parent and target
3189 # if version of file is same in parent and target
3187 # manifests, do nothing
3190 # manifests, do nothing
3188 if (pmf[abs] != mfentry or
3191 if (pmf[abs] != mfentry or
3189 pmf.flags(abs) != mf.flags(abs)):
3192 pmf.flags(abs) != mf.flags(abs)):
3190 handle(revert, False)
3193 handle(revert, False)
3191 else:
3194 else:
3192 handle(remove, False)
3195 handle(remove, False)
3193
3196
3194 if not opts.get('dry_run'):
3197 if not opts.get('dry_run'):
3195 def checkout(f):
3198 def checkout(f):
3196 fc = ctx[f]
3199 fc = ctx[f]
3197 repo.wwrite(f, fc.data(), fc.flags())
3200 repo.wwrite(f, fc.data(), fc.flags())
3198
3201
3199 audit_path = util.path_auditor(repo.root)
3202 audit_path = util.path_auditor(repo.root)
3200 for f in remove[0]:
3203 for f in remove[0]:
3201 if repo.dirstate[f] == 'a':
3204 if repo.dirstate[f] == 'a':
3202 repo.dirstate.forget(f)
3205 repo.dirstate.forget(f)
3203 continue
3206 continue
3204 audit_path(f)
3207 audit_path(f)
3205 try:
3208 try:
3206 util.unlink(repo.wjoin(f))
3209 util.unlink(repo.wjoin(f))
3207 except OSError:
3210 except OSError:
3208 pass
3211 pass
3209 repo.dirstate.remove(f)
3212 repo.dirstate.remove(f)
3210
3213
3211 normal = None
3214 normal = None
3212 if node == parent:
3215 if node == parent:
3213 # We're reverting to our parent. If possible, we'd like status
3216 # We're reverting to our parent. If possible, we'd like status
3214 # to report the file as clean. We have to use normallookup for
3217 # to report the file as clean. We have to use normallookup for
3215 # merges to avoid losing information about merged/dirty files.
3218 # merges to avoid losing information about merged/dirty files.
3216 if p2 != nullid:
3219 if p2 != nullid:
3217 normal = repo.dirstate.normallookup
3220 normal = repo.dirstate.normallookup
3218 else:
3221 else:
3219 normal = repo.dirstate.normal
3222 normal = repo.dirstate.normal
3220 for f in revert[0]:
3223 for f in revert[0]:
3221 checkout(f)
3224 checkout(f)
3222 if normal:
3225 if normal:
3223 normal(f)
3226 normal(f)
3224
3227
3225 for f in add[0]:
3228 for f in add[0]:
3226 checkout(f)
3229 checkout(f)
3227 repo.dirstate.add(f)
3230 repo.dirstate.add(f)
3228
3231
3229 normal = repo.dirstate.normallookup
3232 normal = repo.dirstate.normallookup
3230 if node == parent and p2 == nullid:
3233 if node == parent and p2 == nullid:
3231 normal = repo.dirstate.normal
3234 normal = repo.dirstate.normal
3232 for f in undelete[0]:
3235 for f in undelete[0]:
3233 checkout(f)
3236 checkout(f)
3234 normal(f)
3237 normal(f)
3235
3238
3236 finally:
3239 finally:
3237 wlock.release()
3240 wlock.release()
3238
3241
3239 def rollback(ui, repo, **opts):
3242 def rollback(ui, repo, **opts):
3240 """roll back the last transaction (dangerous)
3243 """roll back the last transaction (dangerous)
3241
3244
3242 This command should be used with care. There is only one level of
3245 This command should be used with care. There is only one level of
3243 rollback, and there is no way to undo a rollback. It will also
3246 rollback, and there is no way to undo a rollback. It will also
3244 restore the dirstate at the time of the last transaction, losing
3247 restore the dirstate at the time of the last transaction, losing
3245 any dirstate changes since that time. This command does not alter
3248 any dirstate changes since that time. This command does not alter
3246 the working directory.
3249 the working directory.
3247
3250
3248 Transactions are used to encapsulate the effects of all commands
3251 Transactions are used to encapsulate the effects of all commands
3249 that create new changesets or propagate existing changesets into a
3252 that create new changesets or propagate existing changesets into a
3250 repository. For example, the following commands are transactional,
3253 repository. For example, the following commands are transactional,
3251 and their effects can be rolled back:
3254 and their effects can be rolled back:
3252
3255
3253 - commit
3256 - commit
3254 - import
3257 - import
3255 - pull
3258 - pull
3256 - push (with this repository as the destination)
3259 - push (with this repository as the destination)
3257 - unbundle
3260 - unbundle
3258
3261
3259 This command is not intended for use on public repositories. Once
3262 This command is not intended for use on public repositories. Once
3260 changes are visible for pull by other users, rolling a transaction
3263 changes are visible for pull by other users, rolling a transaction
3261 back locally is ineffective (someone else may already have pulled
3264 back locally is ineffective (someone else may already have pulled
3262 the changes). Furthermore, a race is possible with readers of the
3265 the changes). Furthermore, a race is possible with readers of the
3263 repository; for example an in-progress pull from the repository
3266 repository; for example an in-progress pull from the repository
3264 may fail if a rollback is performed.
3267 may fail if a rollback is performed.
3265
3268
3266 Returns 0 on success, 1 if no rollback data is available.
3269 Returns 0 on success, 1 if no rollback data is available.
3267 """
3270 """
3268 return repo.rollback(opts.get('dry_run'))
3271 return repo.rollback(opts.get('dry_run'))
3269
3272
3270 def root(ui, repo):
3273 def root(ui, repo):
3271 """print the root (top) of the current working directory
3274 """print the root (top) of the current working directory
3272
3275
3273 Print the root directory of the current repository.
3276 Print the root directory of the current repository.
3274
3277
3275 Returns 0 on success.
3278 Returns 0 on success.
3276 """
3279 """
3277 ui.write(repo.root + "\n")
3280 ui.write(repo.root + "\n")
3278
3281
3279 def serve(ui, repo, **opts):
3282 def serve(ui, repo, **opts):
3280 """start stand-alone webserver
3283 """start stand-alone webserver
3281
3284
3282 Start a local HTTP repository browser and pull server. You can use
3285 Start a local HTTP repository browser and pull server. You can use
3283 this for ad-hoc sharing and browing of repositories. It is
3286 this for ad-hoc sharing and browing of repositories. It is
3284 recommended to use a real web server to serve a repository for
3287 recommended to use a real web server to serve a repository for
3285 longer periods of time.
3288 longer periods of time.
3286
3289
3287 Please note that the server does not implement access control.
3290 Please note that the server does not implement access control.
3288 This means that, by default, anybody can read from the server and
3291 This means that, by default, anybody can read from the server and
3289 nobody can write to it by default. Set the ``web.allow_push``
3292 nobody can write to it by default. Set the ``web.allow_push``
3290 option to ``*`` to allow everybody to push to the server. You
3293 option to ``*`` to allow everybody to push to the server. You
3291 should use a real web server if you need to authenticate users.
3294 should use a real web server if you need to authenticate users.
3292
3295
3293 By default, the server logs accesses to stdout and errors to
3296 By default, the server logs accesses to stdout and errors to
3294 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3297 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3295 files.
3298 files.
3296
3299
3297 To have the server choose a free port number to listen on, specify
3300 To have the server choose a free port number to listen on, specify
3298 a port number of 0; in this case, the server will print the port
3301 a port number of 0; in this case, the server will print the port
3299 number it uses.
3302 number it uses.
3300
3303
3301 Returns 0 on success.
3304 Returns 0 on success.
3302 """
3305 """
3303
3306
3304 if opts["stdio"]:
3307 if opts["stdio"]:
3305 if repo is None:
3308 if repo is None:
3306 raise error.RepoError(_("There is no Mercurial repository here"
3309 raise error.RepoError(_("There is no Mercurial repository here"
3307 " (.hg not found)"))
3310 " (.hg not found)"))
3308 s = sshserver.sshserver(ui, repo)
3311 s = sshserver.sshserver(ui, repo)
3309 s.serve_forever()
3312 s.serve_forever()
3310
3313
3311 # this way we can check if something was given in the command-line
3314 # this way we can check if something was given in the command-line
3312 if opts.get('port'):
3315 if opts.get('port'):
3313 opts['port'] = int(opts.get('port'))
3316 opts['port'] = int(opts.get('port'))
3314
3317
3315 baseui = repo and repo.baseui or ui
3318 baseui = repo and repo.baseui or ui
3316 optlist = ("name templates style address port prefix ipv6"
3319 optlist = ("name templates style address port prefix ipv6"
3317 " accesslog errorlog certificate encoding")
3320 " accesslog errorlog certificate encoding")
3318 for o in optlist.split():
3321 for o in optlist.split():
3319 val = opts.get(o, '')
3322 val = opts.get(o, '')
3320 if val in (None, ''): # should check against default options instead
3323 if val in (None, ''): # should check against default options instead
3321 continue
3324 continue
3322 baseui.setconfig("web", o, val)
3325 baseui.setconfig("web", o, val)
3323 if repo and repo.ui != baseui:
3326 if repo and repo.ui != baseui:
3324 repo.ui.setconfig("web", o, val)
3327 repo.ui.setconfig("web", o, val)
3325
3328
3326 o = opts.get('web_conf') or opts.get('webdir_conf')
3329 o = opts.get('web_conf') or opts.get('webdir_conf')
3327 if not o:
3330 if not o:
3328 if not repo:
3331 if not repo:
3329 raise error.RepoError(_("There is no Mercurial repository"
3332 raise error.RepoError(_("There is no Mercurial repository"
3330 " here (.hg not found)"))
3333 " here (.hg not found)"))
3331 o = repo.root
3334 o = repo.root
3332
3335
3333 app = hgweb.hgweb(o, baseui=ui)
3336 app = hgweb.hgweb(o, baseui=ui)
3334
3337
3335 class service(object):
3338 class service(object):
3336 def init(self):
3339 def init(self):
3337 util.set_signal_handler()
3340 util.set_signal_handler()
3338 self.httpd = hgweb.server.create_server(ui, app)
3341 self.httpd = hgweb.server.create_server(ui, app)
3339
3342
3340 if opts['port'] and not ui.verbose:
3343 if opts['port'] and not ui.verbose:
3341 return
3344 return
3342
3345
3343 if self.httpd.prefix:
3346 if self.httpd.prefix:
3344 prefix = self.httpd.prefix.strip('/') + '/'
3347 prefix = self.httpd.prefix.strip('/') + '/'
3345 else:
3348 else:
3346 prefix = ''
3349 prefix = ''
3347
3350
3348 port = ':%d' % self.httpd.port
3351 port = ':%d' % self.httpd.port
3349 if port == ':80':
3352 if port == ':80':
3350 port = ''
3353 port = ''
3351
3354
3352 bindaddr = self.httpd.addr
3355 bindaddr = self.httpd.addr
3353 if bindaddr == '0.0.0.0':
3356 if bindaddr == '0.0.0.0':
3354 bindaddr = '*'
3357 bindaddr = '*'
3355 elif ':' in bindaddr: # IPv6
3358 elif ':' in bindaddr: # IPv6
3356 bindaddr = '[%s]' % bindaddr
3359 bindaddr = '[%s]' % bindaddr
3357
3360
3358 fqaddr = self.httpd.fqaddr
3361 fqaddr = self.httpd.fqaddr
3359 if ':' in fqaddr:
3362 if ':' in fqaddr:
3360 fqaddr = '[%s]' % fqaddr
3363 fqaddr = '[%s]' % fqaddr
3361 if opts['port']:
3364 if opts['port']:
3362 write = ui.status
3365 write = ui.status
3363 else:
3366 else:
3364 write = ui.write
3367 write = ui.write
3365 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3368 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3366 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3369 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3367
3370
3368 def run(self):
3371 def run(self):
3369 self.httpd.serve_forever()
3372 self.httpd.serve_forever()
3370
3373
3371 service = service()
3374 service = service()
3372
3375
3373 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3376 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3374
3377
3375 def status(ui, repo, *pats, **opts):
3378 def status(ui, repo, *pats, **opts):
3376 """show changed files in the working directory
3379 """show changed files in the working directory
3377
3380
3378 Show status of files in the repository. If names are given, only
3381 Show status of files in the repository. If names are given, only
3379 files that match are shown. Files that are clean or ignored or
3382 files that match are shown. Files that are clean or ignored or
3380 the source of a copy/move operation, are not listed unless
3383 the source of a copy/move operation, are not listed unless
3381 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3384 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3382 Unless options described with "show only ..." are given, the
3385 Unless options described with "show only ..." are given, the
3383 options -mardu are used.
3386 options -mardu are used.
3384
3387
3385 Option -q/--quiet hides untracked (unknown and ignored) files
3388 Option -q/--quiet hides untracked (unknown and ignored) files
3386 unless explicitly requested with -u/--unknown or -i/--ignored.
3389 unless explicitly requested with -u/--unknown or -i/--ignored.
3387
3390
3388 NOTE: status may appear to disagree with diff if permissions have
3391 NOTE: status may appear to disagree with diff if permissions have
3389 changed or a merge has occurred. The standard diff format does not
3392 changed or a merge has occurred. The standard diff format does not
3390 report permission changes and diff only reports changes relative
3393 report permission changes and diff only reports changes relative
3391 to one merge parent.
3394 to one merge parent.
3392
3395
3393 If one revision is given, it is used as the base revision.
3396 If one revision is given, it is used as the base revision.
3394 If two revisions are given, the differences between them are
3397 If two revisions are given, the differences between them are
3395 shown. The --change option can also be used as a shortcut to list
3398 shown. The --change option can also be used as a shortcut to list
3396 the changed files of a revision from its first parent.
3399 the changed files of a revision from its first parent.
3397
3400
3398 The codes used to show the status of files are::
3401 The codes used to show the status of files are::
3399
3402
3400 M = modified
3403 M = modified
3401 A = added
3404 A = added
3402 R = removed
3405 R = removed
3403 C = clean
3406 C = clean
3404 ! = missing (deleted by non-hg command, but still tracked)
3407 ! = missing (deleted by non-hg command, but still tracked)
3405 ? = not tracked
3408 ? = not tracked
3406 I = ignored
3409 I = ignored
3407 = origin of the previous file listed as A (added)
3410 = origin of the previous file listed as A (added)
3408
3411
3409 Returns 0 on success.
3412 Returns 0 on success.
3410 """
3413 """
3411
3414
3412 revs = opts.get('rev')
3415 revs = opts.get('rev')
3413 change = opts.get('change')
3416 change = opts.get('change')
3414
3417
3415 if revs and change:
3418 if revs and change:
3416 msg = _('cannot specify --rev and --change at the same time')
3419 msg = _('cannot specify --rev and --change at the same time')
3417 raise util.Abort(msg)
3420 raise util.Abort(msg)
3418 elif change:
3421 elif change:
3419 node2 = repo.lookup(change)
3422 node2 = repo.lookup(change)
3420 node1 = repo[node2].parents()[0].node()
3423 node1 = repo[node2].parents()[0].node()
3421 else:
3424 else:
3422 node1, node2 = cmdutil.revpair(repo, revs)
3425 node1, node2 = cmdutil.revpair(repo, revs)
3423
3426
3424 cwd = (pats and repo.getcwd()) or ''
3427 cwd = (pats and repo.getcwd()) or ''
3425 end = opts.get('print0') and '\0' or '\n'
3428 end = opts.get('print0') and '\0' or '\n'
3426 copy = {}
3429 copy = {}
3427 states = 'modified added removed deleted unknown ignored clean'.split()
3430 states = 'modified added removed deleted unknown ignored clean'.split()
3428 show = [k for k in states if opts.get(k)]
3431 show = [k for k in states if opts.get(k)]
3429 if opts.get('all'):
3432 if opts.get('all'):
3430 show += ui.quiet and (states[:4] + ['clean']) or states
3433 show += ui.quiet and (states[:4] + ['clean']) or states
3431 if not show:
3434 if not show:
3432 show = ui.quiet and states[:4] or states[:5]
3435 show = ui.quiet and states[:4] or states[:5]
3433
3436
3434 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3437 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3435 'ignored' in show, 'clean' in show, 'unknown' in show)
3438 'ignored' in show, 'clean' in show, 'unknown' in show)
3436 changestates = zip(states, 'MAR!?IC', stat)
3439 changestates = zip(states, 'MAR!?IC', stat)
3437
3440
3438 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3441 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3439 ctxn = repo[nullid]
3442 ctxn = repo[nullid]
3440 ctx1 = repo[node1]
3443 ctx1 = repo[node1]
3441 ctx2 = repo[node2]
3444 ctx2 = repo[node2]
3442 added = stat[1]
3445 added = stat[1]
3443 if node2 is None:
3446 if node2 is None:
3444 added = stat[0] + stat[1] # merged?
3447 added = stat[0] + stat[1] # merged?
3445
3448
3446 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3449 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3447 if k in added:
3450 if k in added:
3448 copy[k] = v
3451 copy[k] = v
3449 elif v in added:
3452 elif v in added:
3450 copy[v] = k
3453 copy[v] = k
3451
3454
3452 for state, char, files in changestates:
3455 for state, char, files in changestates:
3453 if state in show:
3456 if state in show:
3454 format = "%s %%s%s" % (char, end)
3457 format = "%s %%s%s" % (char, end)
3455 if opts.get('no_status'):
3458 if opts.get('no_status'):
3456 format = "%%s%s" % end
3459 format = "%%s%s" % end
3457
3460
3458 for f in files:
3461 for f in files:
3459 ui.write(format % repo.pathto(f, cwd),
3462 ui.write(format % repo.pathto(f, cwd),
3460 label='status.' + state)
3463 label='status.' + state)
3461 if f in copy:
3464 if f in copy:
3462 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3465 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3463 label='status.copied')
3466 label='status.copied')
3464
3467
3465 def summary(ui, repo, **opts):
3468 def summary(ui, repo, **opts):
3466 """summarize working directory state
3469 """summarize working directory state
3467
3470
3468 This generates a brief summary of the working directory state,
3471 This generates a brief summary of the working directory state,
3469 including parents, branch, commit status, and available updates.
3472 including parents, branch, commit status, and available updates.
3470
3473
3471 With the --remote option, this will check the default paths for
3474 With the --remote option, this will check the default paths for
3472 incoming and outgoing changes. This can be time-consuming.
3475 incoming and outgoing changes. This can be time-consuming.
3473
3476
3474 Returns 0 on success.
3477 Returns 0 on success.
3475 """
3478 """
3476
3479
3477 ctx = repo[None]
3480 ctx = repo[None]
3478 parents = ctx.parents()
3481 parents = ctx.parents()
3479 pnode = parents[0].node()
3482 pnode = parents[0].node()
3480
3483
3481 for p in parents:
3484 for p in parents:
3482 # label with log.changeset (instead of log.parent) since this
3485 # label with log.changeset (instead of log.parent) since this
3483 # shows a working directory parent *changeset*:
3486 # shows a working directory parent *changeset*:
3484 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3487 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3485 label='log.changeset')
3488 label='log.changeset')
3486 ui.write(' '.join(p.tags()), label='log.tag')
3489 ui.write(' '.join(p.tags()), label='log.tag')
3487 if p.rev() == -1:
3490 if p.rev() == -1:
3488 if not len(repo):
3491 if not len(repo):
3489 ui.write(_(' (empty repository)'))
3492 ui.write(_(' (empty repository)'))
3490 else:
3493 else:
3491 ui.write(_(' (no revision checked out)'))
3494 ui.write(_(' (no revision checked out)'))
3492 ui.write('\n')
3495 ui.write('\n')
3493 if p.description():
3496 if p.description():
3494 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3497 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3495 label='log.summary')
3498 label='log.summary')
3496
3499
3497 branch = ctx.branch()
3500 branch = ctx.branch()
3498 bheads = repo.branchheads(branch)
3501 bheads = repo.branchheads(branch)
3499 m = _('branch: %s\n') % branch
3502 m = _('branch: %s\n') % branch
3500 if branch != 'default':
3503 if branch != 'default':
3501 ui.write(m, label='log.branch')
3504 ui.write(m, label='log.branch')
3502 else:
3505 else:
3503 ui.status(m, label='log.branch')
3506 ui.status(m, label='log.branch')
3504
3507
3505 st = list(repo.status(unknown=True))[:6]
3508 st = list(repo.status(unknown=True))[:6]
3506
3509
3507 c = repo.dirstate.copies()
3510 c = repo.dirstate.copies()
3508 copied, renamed = [], []
3511 copied, renamed = [], []
3509 for d, s in c.iteritems():
3512 for d, s in c.iteritems():
3510 if s in st[2]:
3513 if s in st[2]:
3511 st[2].remove(s)
3514 st[2].remove(s)
3512 renamed.append(d)
3515 renamed.append(d)
3513 else:
3516 else:
3514 copied.append(d)
3517 copied.append(d)
3515 if d in st[1]:
3518 if d in st[1]:
3516 st[1].remove(d)
3519 st[1].remove(d)
3517 st.insert(3, renamed)
3520 st.insert(3, renamed)
3518 st.insert(4, copied)
3521 st.insert(4, copied)
3519
3522
3520 ms = mergemod.mergestate(repo)
3523 ms = mergemod.mergestate(repo)
3521 st.append([f for f in ms if ms[f] == 'u'])
3524 st.append([f for f in ms if ms[f] == 'u'])
3522
3525
3523 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3526 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3524 st.append(subs)
3527 st.append(subs)
3525
3528
3526 labels = [ui.label(_('%d modified'), 'status.modified'),
3529 labels = [ui.label(_('%d modified'), 'status.modified'),
3527 ui.label(_('%d added'), 'status.added'),
3530 ui.label(_('%d added'), 'status.added'),
3528 ui.label(_('%d removed'), 'status.removed'),
3531 ui.label(_('%d removed'), 'status.removed'),
3529 ui.label(_('%d renamed'), 'status.copied'),
3532 ui.label(_('%d renamed'), 'status.copied'),
3530 ui.label(_('%d copied'), 'status.copied'),
3533 ui.label(_('%d copied'), 'status.copied'),
3531 ui.label(_('%d deleted'), 'status.deleted'),
3534 ui.label(_('%d deleted'), 'status.deleted'),
3532 ui.label(_('%d unknown'), 'status.unknown'),
3535 ui.label(_('%d unknown'), 'status.unknown'),
3533 ui.label(_('%d ignored'), 'status.ignored'),
3536 ui.label(_('%d ignored'), 'status.ignored'),
3534 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3537 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3535 ui.label(_('%d subrepos'), 'status.modified')]
3538 ui.label(_('%d subrepos'), 'status.modified')]
3536 t = []
3539 t = []
3537 for s, l in zip(st, labels):
3540 for s, l in zip(st, labels):
3538 if s:
3541 if s:
3539 t.append(l % len(s))
3542 t.append(l % len(s))
3540
3543
3541 t = ', '.join(t)
3544 t = ', '.join(t)
3542 cleanworkdir = False
3545 cleanworkdir = False
3543
3546
3544 if len(parents) > 1:
3547 if len(parents) > 1:
3545 t += _(' (merge)')
3548 t += _(' (merge)')
3546 elif branch != parents[0].branch():
3549 elif branch != parents[0].branch():
3547 t += _(' (new branch)')
3550 t += _(' (new branch)')
3548 elif (parents[0].extra().get('close') and
3551 elif (parents[0].extra().get('close') and
3549 pnode in repo.branchheads(branch, closed=True)):
3552 pnode in repo.branchheads(branch, closed=True)):
3550 t += _(' (head closed)')
3553 t += _(' (head closed)')
3551 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3554 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3552 t += _(' (clean)')
3555 t += _(' (clean)')
3553 cleanworkdir = True
3556 cleanworkdir = True
3554 elif pnode not in bheads:
3557 elif pnode not in bheads:
3555 t += _(' (new branch head)')
3558 t += _(' (new branch head)')
3556
3559
3557 if cleanworkdir:
3560 if cleanworkdir:
3558 ui.status(_('commit: %s\n') % t.strip())
3561 ui.status(_('commit: %s\n') % t.strip())
3559 else:
3562 else:
3560 ui.write(_('commit: %s\n') % t.strip())
3563 ui.write(_('commit: %s\n') % t.strip())
3561
3564
3562 # all ancestors of branch heads - all ancestors of parent = new csets
3565 # all ancestors of branch heads - all ancestors of parent = new csets
3563 new = [0] * len(repo)
3566 new = [0] * len(repo)
3564 cl = repo.changelog
3567 cl = repo.changelog
3565 for a in [cl.rev(n) for n in bheads]:
3568 for a in [cl.rev(n) for n in bheads]:
3566 new[a] = 1
3569 new[a] = 1
3567 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3570 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3568 new[a] = 1
3571 new[a] = 1
3569 for a in [p.rev() for p in parents]:
3572 for a in [p.rev() for p in parents]:
3570 if a >= 0:
3573 if a >= 0:
3571 new[a] = 0
3574 new[a] = 0
3572 for a in cl.ancestors(*[p.rev() for p in parents]):
3575 for a in cl.ancestors(*[p.rev() for p in parents]):
3573 new[a] = 0
3576 new[a] = 0
3574 new = sum(new)
3577 new = sum(new)
3575
3578
3576 if new == 0:
3579 if new == 0:
3577 ui.status(_('update: (current)\n'))
3580 ui.status(_('update: (current)\n'))
3578 elif pnode not in bheads:
3581 elif pnode not in bheads:
3579 ui.write(_('update: %d new changesets (update)\n') % new)
3582 ui.write(_('update: %d new changesets (update)\n') % new)
3580 else:
3583 else:
3581 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3584 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3582 (new, len(bheads)))
3585 (new, len(bheads)))
3583
3586
3584 if opts.get('remote'):
3587 if opts.get('remote'):
3585 t = []
3588 t = []
3586 source, branches = hg.parseurl(ui.expandpath('default'))
3589 source, branches = hg.parseurl(ui.expandpath('default'))
3587 other = hg.repository(hg.remoteui(repo, {}), source)
3590 other = hg.repository(hg.remoteui(repo, {}), source)
3588 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3591 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3589 ui.debug('comparing with %s\n' % url.hidepassword(source))
3592 ui.debug('comparing with %s\n' % url.hidepassword(source))
3590 repo.ui.pushbuffer()
3593 repo.ui.pushbuffer()
3591 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3594 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3592 repo.ui.popbuffer()
3595 repo.ui.popbuffer()
3593 if incoming:
3596 if incoming:
3594 t.append(_('1 or more incoming'))
3597 t.append(_('1 or more incoming'))
3595
3598
3596 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3599 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3597 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3600 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3598 other = hg.repository(hg.remoteui(repo, {}), dest)
3601 other = hg.repository(hg.remoteui(repo, {}), dest)
3599 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3602 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3600 repo.ui.pushbuffer()
3603 repo.ui.pushbuffer()
3601 o = discovery.findoutgoing(repo, other)
3604 o = discovery.findoutgoing(repo, other)
3602 repo.ui.popbuffer()
3605 repo.ui.popbuffer()
3603 o = repo.changelog.nodesbetween(o, None)[0]
3606 o = repo.changelog.nodesbetween(o, None)[0]
3604 if o:
3607 if o:
3605 t.append(_('%d outgoing') % len(o))
3608 t.append(_('%d outgoing') % len(o))
3606
3609
3607 if t:
3610 if t:
3608 ui.write(_('remote: %s\n') % (', '.join(t)))
3611 ui.write(_('remote: %s\n') % (', '.join(t)))
3609 else:
3612 else:
3610 ui.status(_('remote: (synced)\n'))
3613 ui.status(_('remote: (synced)\n'))
3611
3614
3612 def tag(ui, repo, name1, *names, **opts):
3615 def tag(ui, repo, name1, *names, **opts):
3613 """add one or more tags for the current or given revision
3616 """add one or more tags for the current or given revision
3614
3617
3615 Name a particular revision using <name>.
3618 Name a particular revision using <name>.
3616
3619
3617 Tags are used to name particular revisions of the repository and are
3620 Tags are used to name particular revisions of the repository and are
3618 very useful to compare different revisions, to go back to significant
3621 very useful to compare different revisions, to go back to significant
3619 earlier versions or to mark branch points as releases, etc.
3622 earlier versions or to mark branch points as releases, etc.
3620
3623
3621 If no revision is given, the parent of the working directory is
3624 If no revision is given, the parent of the working directory is
3622 used, or tip if no revision is checked out.
3625 used, or tip if no revision is checked out.
3623
3626
3624 To facilitate version control, distribution, and merging of tags,
3627 To facilitate version control, distribution, and merging of tags,
3625 they are stored as a file named ".hgtags" which is managed
3628 they are stored as a file named ".hgtags" which is managed
3626 similarly to other project files and can be hand-edited if
3629 similarly to other project files and can be hand-edited if
3627 necessary. The file '.hg/localtags' is used for local tags (not
3630 necessary. The file '.hg/localtags' is used for local tags (not
3628 shared among repositories).
3631 shared among repositories).
3629
3632
3630 See :hg:`help dates` for a list of formats valid for -d/--date.
3633 See :hg:`help dates` for a list of formats valid for -d/--date.
3631
3634
3632 Since tag names have priority over branch names during revision
3635 Since tag names have priority over branch names during revision
3633 lookup, using an existing branch name as a tag name is discouraged.
3636 lookup, using an existing branch name as a tag name is discouraged.
3634
3637
3635 Returns 0 on success.
3638 Returns 0 on success.
3636 """
3639 """
3637
3640
3638 rev_ = "."
3641 rev_ = "."
3639 names = [t.strip() for t in (name1,) + names]
3642 names = [t.strip() for t in (name1,) + names]
3640 if len(names) != len(set(names)):
3643 if len(names) != len(set(names)):
3641 raise util.Abort(_('tag names must be unique'))
3644 raise util.Abort(_('tag names must be unique'))
3642 for n in names:
3645 for n in names:
3643 if n in ['tip', '.', 'null']:
3646 if n in ['tip', '.', 'null']:
3644 raise util.Abort(_('the name \'%s\' is reserved') % n)
3647 raise util.Abort(_('the name \'%s\' is reserved') % n)
3645 if opts.get('rev') and opts.get('remove'):
3648 if opts.get('rev') and opts.get('remove'):
3646 raise util.Abort(_("--rev and --remove are incompatible"))
3649 raise util.Abort(_("--rev and --remove are incompatible"))
3647 if opts.get('rev'):
3650 if opts.get('rev'):
3648 rev_ = opts['rev']
3651 rev_ = opts['rev']
3649 message = opts.get('message')
3652 message = opts.get('message')
3650 if opts.get('remove'):
3653 if opts.get('remove'):
3651 expectedtype = opts.get('local') and 'local' or 'global'
3654 expectedtype = opts.get('local') and 'local' or 'global'
3652 for n in names:
3655 for n in names:
3653 if not repo.tagtype(n):
3656 if not repo.tagtype(n):
3654 raise util.Abort(_('tag \'%s\' does not exist') % n)
3657 raise util.Abort(_('tag \'%s\' does not exist') % n)
3655 if repo.tagtype(n) != expectedtype:
3658 if repo.tagtype(n) != expectedtype:
3656 if expectedtype == 'global':
3659 if expectedtype == 'global':
3657 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3660 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3658 else:
3661 else:
3659 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3662 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3660 rev_ = nullid
3663 rev_ = nullid
3661 if not message:
3664 if not message:
3662 # we don't translate commit messages
3665 # we don't translate commit messages
3663 message = 'Removed tag %s' % ', '.join(names)
3666 message = 'Removed tag %s' % ', '.join(names)
3664 elif not opts.get('force'):
3667 elif not opts.get('force'):
3665 for n in names:
3668 for n in names:
3666 if n in repo.tags():
3669 if n in repo.tags():
3667 raise util.Abort(_('tag \'%s\' already exists '
3670 raise util.Abort(_('tag \'%s\' already exists '
3668 '(use -f to force)') % n)
3671 '(use -f to force)') % n)
3669 if not rev_ and repo.dirstate.parents()[1] != nullid:
3672 if not rev_ and repo.dirstate.parents()[1] != nullid:
3670 raise util.Abort(_('uncommitted merge - please provide a '
3673 raise util.Abort(_('uncommitted merge - please provide a '
3671 'specific revision'))
3674 'specific revision'))
3672 r = repo[rev_].node()
3675 r = repo[rev_].node()
3673
3676
3674 if not message:
3677 if not message:
3675 # we don't translate commit messages
3678 # we don't translate commit messages
3676 message = ('Added tag %s for changeset %s' %
3679 message = ('Added tag %s for changeset %s' %
3677 (', '.join(names), short(r)))
3680 (', '.join(names), short(r)))
3678
3681
3679 date = opts.get('date')
3682 date = opts.get('date')
3680 if date:
3683 if date:
3681 date = util.parsedate(date)
3684 date = util.parsedate(date)
3682
3685
3683 if opts.get('edit'):
3686 if opts.get('edit'):
3684 message = ui.edit(message, ui.username())
3687 message = ui.edit(message, ui.username())
3685
3688
3686 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3689 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3687
3690
3688 def tags(ui, repo):
3691 def tags(ui, repo):
3689 """list repository tags
3692 """list repository tags
3690
3693
3691 This lists both regular and local tags. When the -v/--verbose
3694 This lists both regular and local tags. When the -v/--verbose
3692 switch is used, a third column "local" is printed for local tags.
3695 switch is used, a third column "local" is printed for local tags.
3693
3696
3694 Returns 0 on success.
3697 Returns 0 on success.
3695 """
3698 """
3696
3699
3697 hexfunc = ui.debugflag and hex or short
3700 hexfunc = ui.debugflag and hex or short
3698 tagtype = ""
3701 tagtype = ""
3699
3702
3700 for t, n in reversed(repo.tagslist()):
3703 for t, n in reversed(repo.tagslist()):
3701 if ui.quiet:
3704 if ui.quiet:
3702 ui.write("%s\n" % t)
3705 ui.write("%s\n" % t)
3703 continue
3706 continue
3704
3707
3705 try:
3708 try:
3706 hn = hexfunc(n)
3709 hn = hexfunc(n)
3707 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3710 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3708 except error.LookupError:
3711 except error.LookupError:
3709 r = " ?:%s" % hn
3712 r = " ?:%s" % hn
3710 else:
3713 else:
3711 spaces = " " * (30 - encoding.colwidth(t))
3714 spaces = " " * (30 - encoding.colwidth(t))
3712 if ui.verbose:
3715 if ui.verbose:
3713 if repo.tagtype(t) == 'local':
3716 if repo.tagtype(t) == 'local':
3714 tagtype = " local"
3717 tagtype = " local"
3715 else:
3718 else:
3716 tagtype = ""
3719 tagtype = ""
3717 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3720 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3718
3721
3719 def tip(ui, repo, **opts):
3722 def tip(ui, repo, **opts):
3720 """show the tip revision
3723 """show the tip revision
3721
3724
3722 The tip revision (usually just called the tip) is the changeset
3725 The tip revision (usually just called the tip) is the changeset
3723 most recently added to the repository (and therefore the most
3726 most recently added to the repository (and therefore the most
3724 recently changed head).
3727 recently changed head).
3725
3728
3726 If you have just made a commit, that commit will be the tip. If
3729 If you have just made a commit, that commit will be the tip. If
3727 you have just pulled changes from another repository, the tip of
3730 you have just pulled changes from another repository, the tip of
3728 that repository becomes the current tip. The "tip" tag is special
3731 that repository becomes the current tip. The "tip" tag is special
3729 and cannot be renamed or assigned to a different changeset.
3732 and cannot be renamed or assigned to a different changeset.
3730
3733
3731 Returns 0 on success.
3734 Returns 0 on success.
3732 """
3735 """
3733 displayer = cmdutil.show_changeset(ui, repo, opts)
3736 displayer = cmdutil.show_changeset(ui, repo, opts)
3734 displayer.show(repo[len(repo) - 1])
3737 displayer.show(repo[len(repo) - 1])
3735 displayer.close()
3738 displayer.close()
3736
3739
3737 def unbundle(ui, repo, fname1, *fnames, **opts):
3740 def unbundle(ui, repo, fname1, *fnames, **opts):
3738 """apply one or more changegroup files
3741 """apply one or more changegroup files
3739
3742
3740 Apply one or more compressed changegroup files generated by the
3743 Apply one or more compressed changegroup files generated by the
3741 bundle command.
3744 bundle command.
3742
3745
3743 Returns 0 on success, 1 if an update has unresolved files.
3746 Returns 0 on success, 1 if an update has unresolved files.
3744 """
3747 """
3745 fnames = (fname1,) + fnames
3748 fnames = (fname1,) + fnames
3746
3749
3747 lock = repo.lock()
3750 lock = repo.lock()
3748 try:
3751 try:
3749 for fname in fnames:
3752 for fname in fnames:
3750 f = url.open(ui, fname)
3753 f = url.open(ui, fname)
3751 gen = changegroup.readbundle(f, fname)
3754 gen = changegroup.readbundle(f, fname)
3752 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
3755 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
3753 lock=lock)
3756 lock=lock)
3754 finally:
3757 finally:
3755 lock.release()
3758 lock.release()
3756
3759
3757 return postincoming(ui, repo, modheads, opts.get('update'), None)
3760 return postincoming(ui, repo, modheads, opts.get('update'), None)
3758
3761
3759 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3762 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3760 """update working directory (or switch revisions)
3763 """update working directory (or switch revisions)
3761
3764
3762 Update the repository's working directory to the specified
3765 Update the repository's working directory to the specified
3763 changeset.
3766 changeset.
3764
3767
3765 If no changeset is specified, attempt to update to the head of the
3768 If no changeset is specified, attempt to update to the head of the
3766 current branch. If this head is a descendant of the working
3769 current branch. If this head is a descendant of the working
3767 directory's parent, update to it, otherwise abort.
3770 directory's parent, update to it, otherwise abort.
3768
3771
3769 The following rules apply when the working directory contains
3772 The following rules apply when the working directory contains
3770 uncommitted changes:
3773 uncommitted changes:
3771
3774
3772 1. If neither -c/--check nor -C/--clean is specified, and if
3775 1. If neither -c/--check nor -C/--clean is specified, and if
3773 the requested changeset is an ancestor or descendant of
3776 the requested changeset is an ancestor or descendant of
3774 the working directory's parent, the uncommitted changes
3777 the working directory's parent, the uncommitted changes
3775 are merged into the requested changeset and the merged
3778 are merged into the requested changeset and the merged
3776 result is left uncommitted. If the requested changeset is
3779 result is left uncommitted. If the requested changeset is
3777 not an ancestor or descendant (that is, it is on another
3780 not an ancestor or descendant (that is, it is on another
3778 branch), the update is aborted and the uncommitted changes
3781 branch), the update is aborted and the uncommitted changes
3779 are preserved.
3782 are preserved.
3780
3783
3781 2. With the -c/--check option, the update is aborted and the
3784 2. With the -c/--check option, the update is aborted and the
3782 uncommitted changes are preserved.
3785 uncommitted changes are preserved.
3783
3786
3784 3. With the -C/--clean option, uncommitted changes are discarded and
3787 3. With the -C/--clean option, uncommitted changes are discarded and
3785 the working directory is updated to the requested changeset.
3788 the working directory is updated to the requested changeset.
3786
3789
3787 Use null as the changeset to remove the working directory (like
3790 Use null as the changeset to remove the working directory (like
3788 :hg:`clone -U`).
3791 :hg:`clone -U`).
3789
3792
3790 If you want to update just one file to an older changeset, use :hg:`revert`.
3793 If you want to update just one file to an older changeset, use :hg:`revert`.
3791
3794
3792 See :hg:`help dates` for a list of formats valid for -d/--date.
3795 See :hg:`help dates` for a list of formats valid for -d/--date.
3793
3796
3794 Returns 0 on success, 1 if there are unresolved files.
3797 Returns 0 on success, 1 if there are unresolved files.
3795 """
3798 """
3796 if rev and node:
3799 if rev and node:
3797 raise util.Abort(_("please specify just one revision"))
3800 raise util.Abort(_("please specify just one revision"))
3798
3801
3799 if not rev:
3802 if not rev:
3800 rev = node
3803 rev = node
3801
3804
3802 if check and clean:
3805 if check and clean:
3803 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
3806 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
3804
3807
3805 if check:
3808 if check:
3806 # we could use dirty() but we can ignore merge and branch trivia
3809 # we could use dirty() but we can ignore merge and branch trivia
3807 c = repo[None]
3810 c = repo[None]
3808 if c.modified() or c.added() or c.removed():
3811 if c.modified() or c.added() or c.removed():
3809 raise util.Abort(_("uncommitted local changes"))
3812 raise util.Abort(_("uncommitted local changes"))
3810
3813
3811 if date:
3814 if date:
3812 if rev:
3815 if rev:
3813 raise util.Abort(_("you can't specify a revision and a date"))
3816 raise util.Abort(_("you can't specify a revision and a date"))
3814 rev = cmdutil.finddate(ui, repo, date)
3817 rev = cmdutil.finddate(ui, repo, date)
3815
3818
3816 if clean or check:
3819 if clean or check:
3817 return hg.clean(repo, rev)
3820 return hg.clean(repo, rev)
3818 else:
3821 else:
3819 return hg.update(repo, rev)
3822 return hg.update(repo, rev)
3820
3823
3821 def verify(ui, repo):
3824 def verify(ui, repo):
3822 """verify the integrity of the repository
3825 """verify the integrity of the repository
3823
3826
3824 Verify the integrity of the current repository.
3827 Verify the integrity of the current repository.
3825
3828
3826 This will perform an extensive check of the repository's
3829 This will perform an extensive check of the repository's
3827 integrity, validating the hashes and checksums of each entry in
3830 integrity, validating the hashes and checksums of each entry in
3828 the changelog, manifest, and tracked files, as well as the
3831 the changelog, manifest, and tracked files, as well as the
3829 integrity of their crosslinks and indices.
3832 integrity of their crosslinks and indices.
3830
3833
3831 Returns 0 on success, 1 if errors are encountered.
3834 Returns 0 on success, 1 if errors are encountered.
3832 """
3835 """
3833 return hg.verify(repo)
3836 return hg.verify(repo)
3834
3837
3835 def version_(ui):
3838 def version_(ui):
3836 """output version and copyright information"""
3839 """output version and copyright information"""
3837 ui.write(_("Mercurial Distributed SCM (version %s)\n")
3840 ui.write(_("Mercurial Distributed SCM (version %s)\n")
3838 % util.version())
3841 % util.version())
3839 ui.status(_(
3842 ui.status(_(
3840 "\nCopyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
3843 "\nCopyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
3841 "This is free software; see the source for copying conditions. "
3844 "This is free software; see the source for copying conditions. "
3842 "There is NO\nwarranty; "
3845 "There is NO\nwarranty; "
3843 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
3846 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
3844 ))
3847 ))
3845
3848
3846 # Command options and aliases are listed here, alphabetically
3849 # Command options and aliases are listed here, alphabetically
3847
3850
3848 globalopts = [
3851 globalopts = [
3849 ('R', 'repository', '',
3852 ('R', 'repository', '',
3850 _('repository root directory or name of overlay bundle file'),
3853 _('repository root directory or name of overlay bundle file'),
3851 _('REPO')),
3854 _('REPO')),
3852 ('', 'cwd', '',
3855 ('', 'cwd', '',
3853 _('change working directory'), _('DIR')),
3856 _('change working directory'), _('DIR')),
3854 ('y', 'noninteractive', None,
3857 ('y', 'noninteractive', None,
3855 _('do not prompt, assume \'yes\' for any required answers')),
3858 _('do not prompt, assume \'yes\' for any required answers')),
3856 ('q', 'quiet', None, _('suppress output')),
3859 ('q', 'quiet', None, _('suppress output')),
3857 ('v', 'verbose', None, _('enable additional output')),
3860 ('v', 'verbose', None, _('enable additional output')),
3858 ('', 'config', [],
3861 ('', 'config', [],
3859 _('set/override config option (use \'section.name=value\')'),
3862 _('set/override config option (use \'section.name=value\')'),
3860 _('CONFIG')),
3863 _('CONFIG')),
3861 ('', 'debug', None, _('enable debugging output')),
3864 ('', 'debug', None, _('enable debugging output')),
3862 ('', 'debugger', None, _('start debugger')),
3865 ('', 'debugger', None, _('start debugger')),
3863 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
3866 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
3864 _('ENCODE')),
3867 _('ENCODE')),
3865 ('', 'encodingmode', encoding.encodingmode,
3868 ('', 'encodingmode', encoding.encodingmode,
3866 _('set the charset encoding mode'), _('MODE')),
3869 _('set the charset encoding mode'), _('MODE')),
3867 ('', 'traceback', None, _('always print a traceback on exception')),
3870 ('', 'traceback', None, _('always print a traceback on exception')),
3868 ('', 'time', None, _('time how long the command takes')),
3871 ('', 'time', None, _('time how long the command takes')),
3869 ('', 'profile', None, _('print command execution profile')),
3872 ('', 'profile', None, _('print command execution profile')),
3870 ('', 'version', None, _('output version information and exit')),
3873 ('', 'version', None, _('output version information and exit')),
3871 ('h', 'help', None, _('display help and exit')),
3874 ('h', 'help', None, _('display help and exit')),
3872 ]
3875 ]
3873
3876
3874 dryrunopts = [('n', 'dry-run', None,
3877 dryrunopts = [('n', 'dry-run', None,
3875 _('do not perform actions, just print output'))]
3878 _('do not perform actions, just print output'))]
3876
3879
3877 remoteopts = [
3880 remoteopts = [
3878 ('e', 'ssh', '',
3881 ('e', 'ssh', '',
3879 _('specify ssh command to use'), _('CMD')),
3882 _('specify ssh command to use'), _('CMD')),
3880 ('', 'remotecmd', '',
3883 ('', 'remotecmd', '',
3881 _('specify hg command to run on the remote side'), _('CMD')),
3884 _('specify hg command to run on the remote side'), _('CMD')),
3882 ]
3885 ]
3883
3886
3884 walkopts = [
3887 walkopts = [
3885 ('I', 'include', [],
3888 ('I', 'include', [],
3886 _('include names matching the given patterns'), _('PATTERN')),
3889 _('include names matching the given patterns'), _('PATTERN')),
3887 ('X', 'exclude', [],
3890 ('X', 'exclude', [],
3888 _('exclude names matching the given patterns'), _('PATTERN')),
3891 _('exclude names matching the given patterns'), _('PATTERN')),
3889 ]
3892 ]
3890
3893
3891 commitopts = [
3894 commitopts = [
3892 ('m', 'message', '',
3895 ('m', 'message', '',
3893 _('use text as commit message'), _('TEXT')),
3896 _('use text as commit message'), _('TEXT')),
3894 ('l', 'logfile', '',
3897 ('l', 'logfile', '',
3895 _('read commit message from file'), _('FILE')),
3898 _('read commit message from file'), _('FILE')),
3896 ]
3899 ]
3897
3900
3898 commitopts2 = [
3901 commitopts2 = [
3899 ('d', 'date', '',
3902 ('d', 'date', '',
3900 _('record datecode as commit date'), _('DATE')),
3903 _('record datecode as commit date'), _('DATE')),
3901 ('u', 'user', '',
3904 ('u', 'user', '',
3902 _('record the specified user as committer'), _('USER')),
3905 _('record the specified user as committer'), _('USER')),
3903 ]
3906 ]
3904
3907
3905 templateopts = [
3908 templateopts = [
3906 ('', 'style', '',
3909 ('', 'style', '',
3907 _('display using template map file'), _('STYLE')),
3910 _('display using template map file'), _('STYLE')),
3908 ('', 'template', '',
3911 ('', 'template', '',
3909 _('display with template'), _('TEMPLATE')),
3912 _('display with template'), _('TEMPLATE')),
3910 ]
3913 ]
3911
3914
3912 logopts = [
3915 logopts = [
3913 ('p', 'patch', None, _('show patch')),
3916 ('p', 'patch', None, _('show patch')),
3914 ('g', 'git', None, _('use git extended diff format')),
3917 ('g', 'git', None, _('use git extended diff format')),
3915 ('l', 'limit', '',
3918 ('l', 'limit', '',
3916 _('limit number of changes displayed'), _('NUM')),
3919 _('limit number of changes displayed'), _('NUM')),
3917 ('M', 'no-merges', None, _('do not show merges')),
3920 ('M', 'no-merges', None, _('do not show merges')),
3918 ('', 'stat', None, _('output diffstat-style summary of changes')),
3921 ('', 'stat', None, _('output diffstat-style summary of changes')),
3919 ] + templateopts
3922 ] + templateopts
3920
3923
3921 diffopts = [
3924 diffopts = [
3922 ('a', 'text', None, _('treat all files as text')),
3925 ('a', 'text', None, _('treat all files as text')),
3923 ('g', 'git', None, _('use git extended diff format')),
3926 ('g', 'git', None, _('use git extended diff format')),
3924 ('', 'nodates', None, _('omit dates from diff headers'))
3927 ('', 'nodates', None, _('omit dates from diff headers'))
3925 ]
3928 ]
3926
3929
3927 diffopts2 = [
3930 diffopts2 = [
3928 ('p', 'show-function', None, _('show which function each change is in')),
3931 ('p', 'show-function', None, _('show which function each change is in')),
3929 ('', 'reverse', None, _('produce a diff that undoes the changes')),
3932 ('', 'reverse', None, _('produce a diff that undoes the changes')),
3930 ('w', 'ignore-all-space', None,
3933 ('w', 'ignore-all-space', None,
3931 _('ignore white space when comparing lines')),
3934 _('ignore white space when comparing lines')),
3932 ('b', 'ignore-space-change', None,
3935 ('b', 'ignore-space-change', None,
3933 _('ignore changes in the amount of white space')),
3936 _('ignore changes in the amount of white space')),
3934 ('B', 'ignore-blank-lines', None,
3937 ('B', 'ignore-blank-lines', None,
3935 _('ignore changes whose lines are all blank')),
3938 _('ignore changes whose lines are all blank')),
3936 ('U', 'unified', '',
3939 ('U', 'unified', '',
3937 _('number of lines of context to show'), _('NUM')),
3940 _('number of lines of context to show'), _('NUM')),
3938 ('', 'stat', None, _('output diffstat-style summary of changes')),
3941 ('', 'stat', None, _('output diffstat-style summary of changes')),
3939 ]
3942 ]
3940
3943
3941 similarityopts = [
3944 similarityopts = [
3942 ('s', 'similarity', '',
3945 ('s', 'similarity', '',
3943 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
3946 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
3944 ]
3947 ]
3945
3948
3946 table = {
3949 table = {
3947 "^add": (add, walkopts + dryrunopts, _('[OPTION]... [FILE]...')),
3950 "^add": (add, walkopts + dryrunopts, _('[OPTION]... [FILE]...')),
3948 "addremove":
3951 "addremove":
3949 (addremove, similarityopts + walkopts + dryrunopts,
3952 (addremove, similarityopts + walkopts + dryrunopts,
3950 _('[OPTION]... [FILE]...')),
3953 _('[OPTION]... [FILE]...')),
3951 "^annotate|blame":
3954 "^annotate|blame":
3952 (annotate,
3955 (annotate,
3953 [('r', 'rev', '',
3956 [('r', 'rev', '',
3954 _('annotate the specified revision'), _('REV')),
3957 _('annotate the specified revision'), _('REV')),
3955 ('', 'follow', None,
3958 ('', 'follow', None,
3956 _('follow copies/renames and list the filename (DEPRECATED)')),
3959 _('follow copies/renames and list the filename (DEPRECATED)')),
3957 ('', 'no-follow', None, _("don't follow copies and renames")),
3960 ('', 'no-follow', None, _("don't follow copies and renames")),
3958 ('a', 'text', None, _('treat all files as text')),
3961 ('a', 'text', None, _('treat all files as text')),
3959 ('u', 'user', None, _('list the author (long with -v)')),
3962 ('u', 'user', None, _('list the author (long with -v)')),
3960 ('f', 'file', None, _('list the filename')),
3963 ('f', 'file', None, _('list the filename')),
3961 ('d', 'date', None, _('list the date (short with -q)')),
3964 ('d', 'date', None, _('list the date (short with -q)')),
3962 ('n', 'number', None, _('list the revision number (default)')),
3965 ('n', 'number', None, _('list the revision number (default)')),
3963 ('c', 'changeset', None, _('list the changeset')),
3966 ('c', 'changeset', None, _('list the changeset')),
3964 ('l', 'line-number', None,
3967 ('l', 'line-number', None,
3965 _('show line number at the first appearance'))
3968 _('show line number at the first appearance'))
3966 ] + walkopts,
3969 ] + walkopts,
3967 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
3970 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
3968 "archive":
3971 "archive":
3969 (archive,
3972 (archive,
3970 [('', 'no-decode', None, _('do not pass files through decoders')),
3973 [('', 'no-decode', None, _('do not pass files through decoders')),
3971 ('p', 'prefix', '',
3974 ('p', 'prefix', '',
3972 _('directory prefix for files in archive'), _('PREFIX')),
3975 _('directory prefix for files in archive'), _('PREFIX')),
3973 ('r', 'rev', '',
3976 ('r', 'rev', '',
3974 _('revision to distribute'), _('REV')),
3977 _('revision to distribute'), _('REV')),
3975 ('t', 'type', '',
3978 ('t', 'type', '',
3976 _('type of distribution to create'), _('TYPE')),
3979 _('type of distribution to create'), _('TYPE')),
3977 ] + walkopts,
3980 ] + walkopts,
3978 _('[OPTION]... DEST')),
3981 _('[OPTION]... DEST')),
3979 "backout":
3982 "backout":
3980 (backout,
3983 (backout,
3981 [('', 'merge', None,
3984 [('', 'merge', None,
3982 _('merge with old dirstate parent after backout')),
3985 _('merge with old dirstate parent after backout')),
3983 ('', 'parent', '',
3986 ('', 'parent', '',
3984 _('parent to choose when backing out merge'), _('REV')),
3987 _('parent to choose when backing out merge'), _('REV')),
3985 ('r', 'rev', '',
3988 ('r', 'rev', '',
3986 _('revision to backout'), _('REV')),
3989 _('revision to backout'), _('REV')),
3987 ] + walkopts + commitopts + commitopts2,
3990 ] + walkopts + commitopts + commitopts2,
3988 _('[OPTION]... [-r] REV')),
3991 _('[OPTION]... [-r] REV')),
3989 "bisect":
3992 "bisect":
3990 (bisect,
3993 (bisect,
3991 [('r', 'reset', False, _('reset bisect state')),
3994 [('r', 'reset', False, _('reset bisect state')),
3992 ('g', 'good', False, _('mark changeset good')),
3995 ('g', 'good', False, _('mark changeset good')),
3993 ('b', 'bad', False, _('mark changeset bad')),
3996 ('b', 'bad', False, _('mark changeset bad')),
3994 ('s', 'skip', False, _('skip testing changeset')),
3997 ('s', 'skip', False, _('skip testing changeset')),
3995 ('c', 'command', '',
3998 ('c', 'command', '',
3996 _('use command to check changeset state'), _('CMD')),
3999 _('use command to check changeset state'), _('CMD')),
3997 ('U', 'noupdate', False, _('do not update to target'))],
4000 ('U', 'noupdate', False, _('do not update to target'))],
3998 _("[-gbsr] [-U] [-c CMD] [REV]")),
4001 _("[-gbsr] [-U] [-c CMD] [REV]")),
3999 "branch":
4002 "branch":
4000 (branch,
4003 (branch,
4001 [('f', 'force', None,
4004 [('f', 'force', None,
4002 _('set branch name even if it shadows an existing branch')),
4005 _('set branch name even if it shadows an existing branch')),
4003 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4006 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4004 _('[-fC] [NAME]')),
4007 _('[-fC] [NAME]')),
4005 "branches":
4008 "branches":
4006 (branches,
4009 (branches,
4007 [('a', 'active', False,
4010 [('a', 'active', False,
4008 _('show only branches that have unmerged heads')),
4011 _('show only branches that have unmerged heads')),
4009 ('c', 'closed', False,
4012 ('c', 'closed', False,
4010 _('show normal and closed branches'))],
4013 _('show normal and closed branches'))],
4011 _('[-ac]')),
4014 _('[-ac]')),
4012 "bundle":
4015 "bundle":
4013 (bundle,
4016 (bundle,
4014 [('f', 'force', None,
4017 [('f', 'force', None,
4015 _('run even when the destination is unrelated')),
4018 _('run even when the destination is unrelated')),
4016 ('r', 'rev', [],
4019 ('r', 'rev', [],
4017 _('a changeset intended to be added to the destination'),
4020 _('a changeset intended to be added to the destination'),
4018 _('REV')),
4021 _('REV')),
4019 ('b', 'branch', [],
4022 ('b', 'branch', [],
4020 _('a specific branch you would like to bundle'),
4023 _('a specific branch you would like to bundle'),
4021 _('BRANCH')),
4024 _('BRANCH')),
4022 ('', 'base', [],
4025 ('', 'base', [],
4023 _('a base changeset assumed to be available at the destination'),
4026 _('a base changeset assumed to be available at the destination'),
4024 _('REV')),
4027 _('REV')),
4025 ('a', 'all', None, _('bundle all changesets in the repository')),
4028 ('a', 'all', None, _('bundle all changesets in the repository')),
4026 ('t', 'type', 'bzip2',
4029 ('t', 'type', 'bzip2',
4027 _('bundle compression type to use'), _('TYPE')),
4030 _('bundle compression type to use'), _('TYPE')),
4028 ] + remoteopts,
4031 ] + remoteopts,
4029 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4032 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4030 "cat":
4033 "cat":
4031 (cat,
4034 (cat,
4032 [('o', 'output', '',
4035 [('o', 'output', '',
4033 _('print output to file with formatted name'), _('FORMAT')),
4036 _('print output to file with formatted name'), _('FORMAT')),
4034 ('r', 'rev', '',
4037 ('r', 'rev', '',
4035 _('print the given revision'), _('REV')),
4038 _('print the given revision'), _('REV')),
4036 ('', 'decode', None, _('apply any matching decode filter')),
4039 ('', 'decode', None, _('apply any matching decode filter')),
4037 ] + walkopts,
4040 ] + walkopts,
4038 _('[OPTION]... FILE...')),
4041 _('[OPTION]... FILE...')),
4039 "^clone":
4042 "^clone":
4040 (clone,
4043 (clone,
4041 [('U', 'noupdate', None,
4044 [('U', 'noupdate', None,
4042 _('the clone will include an empty working copy (only a repository)')),
4045 _('the clone will include an empty working copy (only a repository)')),
4043 ('u', 'updaterev', '',
4046 ('u', 'updaterev', '',
4044 _('revision, tag or branch to check out'), _('REV')),
4047 _('revision, tag or branch to check out'), _('REV')),
4045 ('r', 'rev', [],
4048 ('r', 'rev', [],
4046 _('include the specified changeset'), _('REV')),
4049 _('include the specified changeset'), _('REV')),
4047 ('b', 'branch', [],
4050 ('b', 'branch', [],
4048 _('clone only the specified branch'), _('BRANCH')),
4051 _('clone only the specified branch'), _('BRANCH')),
4049 ('', 'pull', None, _('use pull protocol to copy metadata')),
4052 ('', 'pull', None, _('use pull protocol to copy metadata')),
4050 ('', 'uncompressed', None,
4053 ('', 'uncompressed', None,
4051 _('use uncompressed transfer (fast over LAN)')),
4054 _('use uncompressed transfer (fast over LAN)')),
4052 ] + remoteopts,
4055 ] + remoteopts,
4053 _('[OPTION]... SOURCE [DEST]')),
4056 _('[OPTION]... SOURCE [DEST]')),
4054 "^commit|ci":
4057 "^commit|ci":
4055 (commit,
4058 (commit,
4056 [('A', 'addremove', None,
4059 [('A', 'addremove', None,
4057 _('mark new/missing files as added/removed before committing')),
4060 _('mark new/missing files as added/removed before committing')),
4058 ('', 'close-branch', None,
4061 ('', 'close-branch', None,
4059 _('mark a branch as closed, hiding it from the branch list')),
4062 _('mark a branch as closed, hiding it from the branch list')),
4060 ] + walkopts + commitopts + commitopts2,
4063 ] + walkopts + commitopts + commitopts2,
4061 _('[OPTION]... [FILE]...')),
4064 _('[OPTION]... [FILE]...')),
4062 "copy|cp":
4065 "copy|cp":
4063 (copy,
4066 (copy,
4064 [('A', 'after', None, _('record a copy that has already occurred')),
4067 [('A', 'after', None, _('record a copy that has already occurred')),
4065 ('f', 'force', None,
4068 ('f', 'force', None,
4066 _('forcibly copy over an existing managed file')),
4069 _('forcibly copy over an existing managed file')),
4067 ] + walkopts + dryrunopts,
4070 ] + walkopts + dryrunopts,
4068 _('[OPTION]... [SOURCE]... DEST')),
4071 _('[OPTION]... [SOURCE]... DEST')),
4069 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4072 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4070 "debugbuilddag":
4073 "debugbuilddag":
4071 (debugbuilddag,
4074 (debugbuilddag,
4072 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4075 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4073 ('a', 'appended-file', None, _('add single file all revs append to')),
4076 ('a', 'appended-file', None, _('add single file all revs append to')),
4074 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4077 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4075 ('n', 'new-file', None, _('add new file at each rev')),
4078 ('n', 'new-file', None, _('add new file at each rev')),
4076 ],
4079 ],
4077 _('[OPTION]... TEXT')),
4080 _('[OPTION]... TEXT')),
4078 "debugcheckstate": (debugcheckstate, [], ''),
4081 "debugcheckstate": (debugcheckstate, [], ''),
4079 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4082 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4080 "debugcomplete":
4083 "debugcomplete":
4081 (debugcomplete,
4084 (debugcomplete,
4082 [('o', 'options', None, _('show the command options'))],
4085 [('o', 'options', None, _('show the command options'))],
4083 _('[-o] CMD')),
4086 _('[-o] CMD')),
4084 "debugdag":
4087 "debugdag":
4085 (debugdag,
4088 (debugdag,
4086 [('t', 'tags', None, _('use tags as labels')),
4089 [('t', 'tags', None, _('use tags as labels')),
4087 ('b', 'branches', None, _('annotate with branch names')),
4090 ('b', 'branches', None, _('annotate with branch names')),
4088 ('', 'dots', None, _('use dots for runs')),
4091 ('', 'dots', None, _('use dots for runs')),
4089 ('s', 'spaces', None, _('separate elements by spaces')),
4092 ('s', 'spaces', None, _('separate elements by spaces')),
4090 ],
4093 ],
4091 _('[OPTION]... [FILE [REV]...]')),
4094 _('[OPTION]... [FILE [REV]...]')),
4092 "debugdate":
4095 "debugdate":
4093 (debugdate,
4096 (debugdate,
4094 [('e', 'extended', None, _('try extended date formats'))],
4097 [('e', 'extended', None, _('try extended date formats'))],
4095 _('[-e] DATE [RANGE]')),
4098 _('[-e] DATE [RANGE]')),
4096 "debugdata": (debugdata, [], _('FILE REV')),
4099 "debugdata": (debugdata, [], _('FILE REV')),
4097 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4100 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4098 "debugindex": (debugindex, [], _('FILE')),
4101 "debugindex": (debugindex, [], _('FILE')),
4099 "debugindexdot": (debugindexdot, [], _('FILE')),
4102 "debugindexdot": (debugindexdot, [], _('FILE')),
4100 "debuginstall": (debuginstall, [], ''),
4103 "debuginstall": (debuginstall, [], ''),
4101 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4104 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4102 "debugrebuildstate":
4105 "debugrebuildstate":
4103 (debugrebuildstate,
4106 (debugrebuildstate,
4104 [('r', 'rev', '',
4107 [('r', 'rev', '',
4105 _('revision to rebuild to'), _('REV'))],
4108 _('revision to rebuild to'), _('REV'))],
4106 _('[-r REV] [REV]')),
4109 _('[-r REV] [REV]')),
4107 "debugrename":
4110 "debugrename":
4108 (debugrename,
4111 (debugrename,
4109 [('r', 'rev', '',
4112 [('r', 'rev', '',
4110 _('revision to debug'), _('REV'))],
4113 _('revision to debug'), _('REV'))],
4111 _('[-r REV] FILE')),
4114 _('[-r REV] FILE')),
4112 "debugrevspec":
4115 "debugrevspec":
4113 (debugrevspec, [], ('REVSPEC')),
4116 (debugrevspec, [], ('REVSPEC')),
4114 "debugsetparents":
4117 "debugsetparents":
4115 (debugsetparents, [], _('REV1 [REV2]')),
4118 (debugsetparents, [], _('REV1 [REV2]')),
4116 "debugstate":
4119 "debugstate":
4117 (debugstate,
4120 (debugstate,
4118 [('', 'nodates', None, _('do not display the saved mtime'))],
4121 [('', 'nodates', None, _('do not display the saved mtime'))],
4119 _('[OPTION]...')),
4122 _('[OPTION]...')),
4120 "debugsub":
4123 "debugsub":
4121 (debugsub,
4124 (debugsub,
4122 [('r', 'rev', '',
4125 [('r', 'rev', '',
4123 _('revision to check'), _('REV'))],
4126 _('revision to check'), _('REV'))],
4124 _('[-r REV] [REV]')),
4127 _('[-r REV] [REV]')),
4125 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4128 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4126 "^diff":
4129 "^diff":
4127 (diff,
4130 (diff,
4128 [('r', 'rev', [],
4131 [('r', 'rev', [],
4129 _('revision'), _('REV')),
4132 _('revision'), _('REV')),
4130 ('c', 'change', '',
4133 ('c', 'change', '',
4131 _('change made by revision'), _('REV'))
4134 _('change made by revision'), _('REV'))
4132 ] + diffopts + diffopts2 + walkopts,
4135 ] + diffopts + diffopts2 + walkopts,
4133 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4136 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4134 "^export":
4137 "^export":
4135 (export,
4138 (export,
4136 [('o', 'output', '',
4139 [('o', 'output', '',
4137 _('print output to file with formatted name'), _('FORMAT')),
4140 _('print output to file with formatted name'), _('FORMAT')),
4138 ('', 'switch-parent', None, _('diff against the second parent')),
4141 ('', 'switch-parent', None, _('diff against the second parent')),
4139 ('r', 'rev', [],
4142 ('r', 'rev', [],
4140 _('revisions to export'), _('REV')),
4143 _('revisions to export'), _('REV')),
4141 ] + diffopts,
4144 ] + diffopts,
4142 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4145 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4143 "^forget":
4146 "^forget":
4144 (forget,
4147 (forget,
4145 [] + walkopts,
4148 [] + walkopts,
4146 _('[OPTION]... FILE...')),
4149 _('[OPTION]... FILE...')),
4147 "grep":
4150 "grep":
4148 (grep,
4151 (grep,
4149 [('0', 'print0', None, _('end fields with NUL')),
4152 [('0', 'print0', None, _('end fields with NUL')),
4150 ('', 'all', None, _('print all revisions that match')),
4153 ('', 'all', None, _('print all revisions that match')),
4151 ('f', 'follow', None,
4154 ('f', 'follow', None,
4152 _('follow changeset history,'
4155 _('follow changeset history,'
4153 ' or file history across copies and renames')),
4156 ' or file history across copies and renames')),
4154 ('i', 'ignore-case', None, _('ignore case when matching')),
4157 ('i', 'ignore-case', None, _('ignore case when matching')),
4155 ('l', 'files-with-matches', None,
4158 ('l', 'files-with-matches', None,
4156 _('print only filenames and revisions that match')),
4159 _('print only filenames and revisions that match')),
4157 ('n', 'line-number', None, _('print matching line numbers')),
4160 ('n', 'line-number', None, _('print matching line numbers')),
4158 ('r', 'rev', [],
4161 ('r', 'rev', [],
4159 _('only search files changed within revision range'), _('REV')),
4162 _('only search files changed within revision range'), _('REV')),
4160 ('u', 'user', None, _('list the author (long with -v)')),
4163 ('u', 'user', None, _('list the author (long with -v)')),
4161 ('d', 'date', None, _('list the date (short with -q)')),
4164 ('d', 'date', None, _('list the date (short with -q)')),
4162 ] + walkopts,
4165 ] + walkopts,
4163 _('[OPTION]... PATTERN [FILE]...')),
4166 _('[OPTION]... PATTERN [FILE]...')),
4164 "heads":
4167 "heads":
4165 (heads,
4168 (heads,
4166 [('r', 'rev', '',
4169 [('r', 'rev', '',
4167 _('show only heads which are descendants of REV'), _('REV')),
4170 _('show only heads which are descendants of REV'), _('REV')),
4168 ('t', 'topo', False, _('show topological heads only')),
4171 ('t', 'topo', False, _('show topological heads only')),
4169 ('a', 'active', False,
4172 ('a', 'active', False,
4170 _('show active branchheads only [DEPRECATED]')),
4173 _('show active branchheads only [DEPRECATED]')),
4171 ('c', 'closed', False,
4174 ('c', 'closed', False,
4172 _('show normal and closed branch heads')),
4175 _('show normal and closed branch heads')),
4173 ] + templateopts,
4176 ] + templateopts,
4174 _('[-ac] [-r REV] [REV]...')),
4177 _('[-ac] [-r REV] [REV]...')),
4175 "help": (help_, [], _('[TOPIC]')),
4178 "help": (help_, [], _('[TOPIC]')),
4176 "identify|id":
4179 "identify|id":
4177 (identify,
4180 (identify,
4178 [('r', 'rev', '',
4181 [('r', 'rev', '',
4179 _('identify the specified revision'), _('REV')),
4182 _('identify the specified revision'), _('REV')),
4180 ('n', 'num', None, _('show local revision number')),
4183 ('n', 'num', None, _('show local revision number')),
4181 ('i', 'id', None, _('show global revision id')),
4184 ('i', 'id', None, _('show global revision id')),
4182 ('b', 'branch', None, _('show branch')),
4185 ('b', 'branch', None, _('show branch')),
4183 ('t', 'tags', None, _('show tags'))],
4186 ('t', 'tags', None, _('show tags'))],
4184 _('[-nibt] [-r REV] [SOURCE]')),
4187 _('[-nibt] [-r REV] [SOURCE]')),
4185 "import|patch":
4188 "import|patch":
4186 (import_,
4189 (import_,
4187 [('p', 'strip', 1,
4190 [('p', 'strip', 1,
4188 _('directory strip option for patch. This has the same '
4191 _('directory strip option for patch. This has the same '
4189 'meaning as the corresponding patch option'),
4192 'meaning as the corresponding patch option'),
4190 _('NUM')),
4193 _('NUM')),
4191 ('b', 'base', '',
4194 ('b', 'base', '',
4192 _('base path'), _('PATH')),
4195 _('base path'), _('PATH')),
4193 ('f', 'force', None,
4196 ('f', 'force', None,
4194 _('skip check for outstanding uncommitted changes')),
4197 _('skip check for outstanding uncommitted changes')),
4195 ('', 'no-commit', None,
4198 ('', 'no-commit', None,
4196 _("don't commit, just update the working directory")),
4199 _("don't commit, just update the working directory")),
4197 ('', 'exact', None,
4200 ('', 'exact', None,
4198 _('apply patch to the nodes from which it was generated')),
4201 _('apply patch to the nodes from which it was generated')),
4199 ('', 'import-branch', None,
4202 ('', 'import-branch', None,
4200 _('use any branch information in patch (implied by --exact)'))] +
4203 _('use any branch information in patch (implied by --exact)'))] +
4201 commitopts + commitopts2 + similarityopts,
4204 commitopts + commitopts2 + similarityopts,
4202 _('[OPTION]... PATCH...')),
4205 _('[OPTION]... PATCH...')),
4203 "incoming|in":
4206 "incoming|in":
4204 (incoming,
4207 (incoming,
4205 [('f', 'force', None,
4208 [('f', 'force', None,
4206 _('run even if remote repository is unrelated')),
4209 _('run even if remote repository is unrelated')),
4207 ('n', 'newest-first', None, _('show newest record first')),
4210 ('n', 'newest-first', None, _('show newest record first')),
4208 ('', 'bundle', '',
4211 ('', 'bundle', '',
4209 _('file to store the bundles into'), _('FILE')),
4212 _('file to store the bundles into'), _('FILE')),
4210 ('r', 'rev', [],
4213 ('r', 'rev', [],
4211 _('a remote changeset intended to be added'), _('REV')),
4214 _('a remote changeset intended to be added'), _('REV')),
4212 ('b', 'branch', [],
4215 ('b', 'branch', [],
4213 _('a specific branch you would like to pull'), _('BRANCH')),
4216 _('a specific branch you would like to pull'), _('BRANCH')),
4214 ] + logopts + remoteopts,
4217 ] + logopts + remoteopts,
4215 _('[-p] [-n] [-M] [-f] [-r REV]...'
4218 _('[-p] [-n] [-M] [-f] [-r REV]...'
4216 ' [--bundle FILENAME] [SOURCE]')),
4219 ' [--bundle FILENAME] [SOURCE]')),
4217 "^init":
4220 "^init":
4218 (init,
4221 (init,
4219 remoteopts,
4222 remoteopts,
4220 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4223 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4221 "locate":
4224 "locate":
4222 (locate,
4225 (locate,
4223 [('r', 'rev', '',
4226 [('r', 'rev', '',
4224 _('search the repository as it is in REV'), _('REV')),
4227 _('search the repository as it is in REV'), _('REV')),
4225 ('0', 'print0', None,
4228 ('0', 'print0', None,
4226 _('end filenames with NUL, for use with xargs')),
4229 _('end filenames with NUL, for use with xargs')),
4227 ('f', 'fullpath', None,
4230 ('f', 'fullpath', None,
4228 _('print complete paths from the filesystem root')),
4231 _('print complete paths from the filesystem root')),
4229 ] + walkopts,
4232 ] + walkopts,
4230 _('[OPTION]... [PATTERN]...')),
4233 _('[OPTION]... [PATTERN]...')),
4231 "^log|history":
4234 "^log|history":
4232 (log,
4235 (log,
4233 [('f', 'follow', None,
4236 [('f', 'follow', None,
4234 _('follow changeset history,'
4237 _('follow changeset history,'
4235 ' or file history across copies and renames')),
4238 ' or file history across copies and renames')),
4236 ('', 'follow-first', None,
4239 ('', 'follow-first', None,
4237 _('only follow the first parent of merge changesets')),
4240 _('only follow the first parent of merge changesets')),
4238 ('d', 'date', '',
4241 ('d', 'date', '',
4239 _('show revisions matching date spec'), _('DATE')),
4242 _('show revisions matching date spec'), _('DATE')),
4240 ('C', 'copies', None, _('show copied files')),
4243 ('C', 'copies', None, _('show copied files')),
4241 ('k', 'keyword', [],
4244 ('k', 'keyword', [],
4242 _('do case-insensitive search for a given text'), _('TEXT')),
4245 _('do case-insensitive search for a given text'), _('TEXT')),
4243 ('r', 'rev', [],
4246 ('r', 'rev', [],
4244 _('show the specified revision or range'), _('REV')),
4247 _('show the specified revision or range'), _('REV')),
4245 ('', 'removed', None, _('include revisions where files were removed')),
4248 ('', 'removed', None, _('include revisions where files were removed')),
4246 ('m', 'only-merges', None, _('show only merges')),
4249 ('m', 'only-merges', None, _('show only merges')),
4247 ('u', 'user', [],
4250 ('u', 'user', [],
4248 _('revisions committed by user'), _('USER')),
4251 _('revisions committed by user'), _('USER')),
4249 ('', 'only-branch', [],
4252 ('', 'only-branch', [],
4250 _('show only changesets within the given named branch (DEPRECATED)'),
4253 _('show only changesets within the given named branch (DEPRECATED)'),
4251 _('BRANCH')),
4254 _('BRANCH')),
4252 ('b', 'branch', [],
4255 ('b', 'branch', [],
4253 _('show changesets within the given named branch'), _('BRANCH')),
4256 _('show changesets within the given named branch'), _('BRANCH')),
4254 ('P', 'prune', [],
4257 ('P', 'prune', [],
4255 _('do not display revision or any of its ancestors'), _('REV')),
4258 _('do not display revision or any of its ancestors'), _('REV')),
4256 ] + logopts + walkopts,
4259 ] + logopts + walkopts,
4257 _('[OPTION]... [FILE]')),
4260 _('[OPTION]... [FILE]')),
4258 "manifest":
4261 "manifest":
4259 (manifest,
4262 (manifest,
4260 [('r', 'rev', '',
4263 [('r', 'rev', '',
4261 _('revision to display'), _('REV'))],
4264 _('revision to display'), _('REV'))],
4262 _('[-r REV]')),
4265 _('[-r REV]')),
4263 "^merge":
4266 "^merge":
4264 (merge,
4267 (merge,
4265 [('f', 'force', None, _('force a merge with outstanding changes')),
4268 [('f', 'force', None, _('force a merge with outstanding changes')),
4266 ('r', 'rev', '',
4269 ('r', 'rev', '',
4267 _('revision to merge'), _('REV')),
4270 _('revision to merge'), _('REV')),
4268 ('P', 'preview', None,
4271 ('P', 'preview', None,
4269 _('review revisions to merge (no merge is performed)'))],
4272 _('review revisions to merge (no merge is performed)'))],
4270 _('[-P] [-f] [[-r] REV]')),
4273 _('[-P] [-f] [[-r] REV]')),
4271 "outgoing|out":
4274 "outgoing|out":
4272 (outgoing,
4275 (outgoing,
4273 [('f', 'force', None,
4276 [('f', 'force', None,
4274 _('run even when the destination is unrelated')),
4277 _('run even when the destination is unrelated')),
4275 ('r', 'rev', [],
4278 ('r', 'rev', [],
4276 _('a changeset intended to be included in the destination'),
4279 _('a changeset intended to be included in the destination'),
4277 _('REV')),
4280 _('REV')),
4278 ('n', 'newest-first', None, _('show newest record first')),
4281 ('n', 'newest-first', None, _('show newest record first')),
4279 ('b', 'branch', [],
4282 ('b', 'branch', [],
4280 _('a specific branch you would like to push'), _('BRANCH')),
4283 _('a specific branch you would like to push'), _('BRANCH')),
4281 ] + logopts + remoteopts,
4284 ] + logopts + remoteopts,
4282 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4285 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4283 "parents":
4286 "parents":
4284 (parents,
4287 (parents,
4285 [('r', 'rev', '',
4288 [('r', 'rev', '',
4286 _('show parents of the specified revision'), _('REV')),
4289 _('show parents of the specified revision'), _('REV')),
4287 ] + templateopts,
4290 ] + templateopts,
4288 _('[-r REV] [FILE]')),
4291 _('[-r REV] [FILE]')),
4289 "paths": (paths, [], _('[NAME]')),
4292 "paths": (paths, [], _('[NAME]')),
4290 "^pull":
4293 "^pull":
4291 (pull,
4294 (pull,
4292 [('u', 'update', None,
4295 [('u', 'update', None,
4293 _('update to new branch head if changesets were pulled')),
4296 _('update to new branch head if changesets were pulled')),
4294 ('f', 'force', None,
4297 ('f', 'force', None,
4295 _('run even when remote repository is unrelated')),
4298 _('run even when remote repository is unrelated')),
4296 ('r', 'rev', [],
4299 ('r', 'rev', [],
4297 _('a remote changeset intended to be added'), _('REV')),
4300 _('a remote changeset intended to be added'), _('REV')),
4298 ('b', 'branch', [],
4301 ('b', 'branch', [],
4299 _('a specific branch you would like to pull'), _('BRANCH')),
4302 _('a specific branch you would like to pull'), _('BRANCH')),
4300 ] + remoteopts,
4303 ] + remoteopts,
4301 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4304 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4302 "^push":
4305 "^push":
4303 (push,
4306 (push,
4304 [('f', 'force', None, _('force push')),
4307 [('f', 'force', None, _('force push')),
4305 ('r', 'rev', [],
4308 ('r', 'rev', [],
4306 _('a changeset intended to be included in the destination'),
4309 _('a changeset intended to be included in the destination'),
4307 _('REV')),
4310 _('REV')),
4308 ('b', 'branch', [],
4311 ('b', 'branch', [],
4309 _('a specific branch you would like to push'), _('BRANCH')),
4312 _('a specific branch you would like to push'), _('BRANCH')),
4310 ('', 'new-branch', False, _('allow pushing a new branch')),
4313 ('', 'new-branch', False, _('allow pushing a new branch')),
4311 ] + remoteopts,
4314 ] + remoteopts,
4312 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4315 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4313 "recover": (recover, []),
4316 "recover": (recover, []),
4314 "^remove|rm":
4317 "^remove|rm":
4315 (remove,
4318 (remove,
4316 [('A', 'after', None, _('record delete for missing files')),
4319 [('A', 'after', None, _('record delete for missing files')),
4317 ('f', 'force', None,
4320 ('f', 'force', None,
4318 _('remove (and delete) file even if added or modified')),
4321 _('remove (and delete) file even if added or modified')),
4319 ] + walkopts,
4322 ] + walkopts,
4320 _('[OPTION]... FILE...')),
4323 _('[OPTION]... FILE...')),
4321 "rename|mv":
4324 "rename|mv":
4322 (rename,
4325 (rename,
4323 [('A', 'after', None, _('record a rename that has already occurred')),
4326 [('A', 'after', None, _('record a rename that has already occurred')),
4324 ('f', 'force', None,
4327 ('f', 'force', None,
4325 _('forcibly copy over an existing managed file')),
4328 _('forcibly copy over an existing managed file')),
4326 ] + walkopts + dryrunopts,
4329 ] + walkopts + dryrunopts,
4327 _('[OPTION]... SOURCE... DEST')),
4330 _('[OPTION]... SOURCE... DEST')),
4328 "resolve":
4331 "resolve":
4329 (resolve,
4332 (resolve,
4330 [('a', 'all', None, _('select all unresolved files')),
4333 [('a', 'all', None, _('select all unresolved files')),
4331 ('l', 'list', None, _('list state of files needing merge')),
4334 ('l', 'list', None, _('list state of files needing merge')),
4332 ('m', 'mark', None, _('mark files as resolved')),
4335 ('m', 'mark', None, _('mark files as resolved')),
4333 ('u', 'unmark', None, _('unmark files as resolved')),
4336 ('u', 'unmark', None, _('unmark files as resolved')),
4334 ('n', 'no-status', None, _('hide status prefix'))]
4337 ('n', 'no-status', None, _('hide status prefix'))]
4335 + walkopts,
4338 + walkopts,
4336 _('[OPTION]... [FILE]...')),
4339 _('[OPTION]... [FILE]...')),
4337 "revert":
4340 "revert":
4338 (revert,
4341 (revert,
4339 [('a', 'all', None, _('revert all changes when no arguments given')),
4342 [('a', 'all', None, _('revert all changes when no arguments given')),
4340 ('d', 'date', '',
4343 ('d', 'date', '',
4341 _('tipmost revision matching date'), _('DATE')),
4344 _('tipmost revision matching date'), _('DATE')),
4342 ('r', 'rev', '',
4345 ('r', 'rev', '',
4343 _('revert to the specified revision'), _('REV')),
4346 _('revert to the specified revision'), _('REV')),
4344 ('', 'no-backup', None, _('do not save backup copies of files')),
4347 ('', 'no-backup', None, _('do not save backup copies of files')),
4345 ] + walkopts + dryrunopts,
4348 ] + walkopts + dryrunopts,
4346 _('[OPTION]... [-r REV] [NAME]...')),
4349 _('[OPTION]... [-r REV] [NAME]...')),
4347 "rollback": (rollback, dryrunopts),
4350 "rollback": (rollback, dryrunopts),
4348 "root": (root, []),
4351 "root": (root, []),
4349 "^serve":
4352 "^serve":
4350 (serve,
4353 (serve,
4351 [('A', 'accesslog', '',
4354 [('A', 'accesslog', '',
4352 _('name of access log file to write to'), _('FILE')),
4355 _('name of access log file to write to'), _('FILE')),
4353 ('d', 'daemon', None, _('run server in background')),
4356 ('d', 'daemon', None, _('run server in background')),
4354 ('', 'daemon-pipefds', '',
4357 ('', 'daemon-pipefds', '',
4355 _('used internally by daemon mode'), _('NUM')),
4358 _('used internally by daemon mode'), _('NUM')),
4356 ('E', 'errorlog', '',
4359 ('E', 'errorlog', '',
4357 _('name of error log file to write to'), _('FILE')),
4360 _('name of error log file to write to'), _('FILE')),
4358 # use string type, then we can check if something was passed
4361 # use string type, then we can check if something was passed
4359 ('p', 'port', '',
4362 ('p', 'port', '',
4360 _('port to listen on (default: 8000)'), _('PORT')),
4363 _('port to listen on (default: 8000)'), _('PORT')),
4361 ('a', 'address', '',
4364 ('a', 'address', '',
4362 _('address to listen on (default: all interfaces)'), _('ADDR')),
4365 _('address to listen on (default: all interfaces)'), _('ADDR')),
4363 ('', 'prefix', '',
4366 ('', 'prefix', '',
4364 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4367 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4365 ('n', 'name', '',
4368 ('n', 'name', '',
4366 _('name to show in web pages (default: working directory)'),
4369 _('name to show in web pages (default: working directory)'),
4367 _('NAME')),
4370 _('NAME')),
4368 ('', 'web-conf', '',
4371 ('', 'web-conf', '',
4369 _('name of the hgweb config file (serve more than one repository)'),
4372 _('name of the hgweb config file (serve more than one repository)'),
4370 _('FILE')),
4373 _('FILE')),
4371 ('', 'webdir-conf', '',
4374 ('', 'webdir-conf', '',
4372 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4375 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4373 ('', 'pid-file', '',
4376 ('', 'pid-file', '',
4374 _('name of file to write process ID to'), _('FILE')),
4377 _('name of file to write process ID to'), _('FILE')),
4375 ('', 'stdio', None, _('for remote clients')),
4378 ('', 'stdio', None, _('for remote clients')),
4376 ('t', 'templates', '',
4379 ('t', 'templates', '',
4377 _('web templates to use'), _('TEMPLATE')),
4380 _('web templates to use'), _('TEMPLATE')),
4378 ('', 'style', '',
4381 ('', 'style', '',
4379 _('template style to use'), _('STYLE')),
4382 _('template style to use'), _('STYLE')),
4380 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4383 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4381 ('', 'certificate', '',
4384 ('', 'certificate', '',
4382 _('SSL certificate file'), _('FILE'))],
4385 _('SSL certificate file'), _('FILE'))],
4383 _('[OPTION]...')),
4386 _('[OPTION]...')),
4384 "showconfig|debugconfig":
4387 "showconfig|debugconfig":
4385 (showconfig,
4388 (showconfig,
4386 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4389 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4387 _('[-u] [NAME]...')),
4390 _('[-u] [NAME]...')),
4388 "^summary|sum":
4391 "^summary|sum":
4389 (summary,
4392 (summary,
4390 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4393 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4391 "^status|st":
4394 "^status|st":
4392 (status,
4395 (status,
4393 [('A', 'all', None, _('show status of all files')),
4396 [('A', 'all', None, _('show status of all files')),
4394 ('m', 'modified', None, _('show only modified files')),
4397 ('m', 'modified', None, _('show only modified files')),
4395 ('a', 'added', None, _('show only added files')),
4398 ('a', 'added', None, _('show only added files')),
4396 ('r', 'removed', None, _('show only removed files')),
4399 ('r', 'removed', None, _('show only removed files')),
4397 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4400 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4398 ('c', 'clean', None, _('show only files without changes')),
4401 ('c', 'clean', None, _('show only files without changes')),
4399 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4402 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4400 ('i', 'ignored', None, _('show only ignored files')),
4403 ('i', 'ignored', None, _('show only ignored files')),
4401 ('n', 'no-status', None, _('hide status prefix')),
4404 ('n', 'no-status', None, _('hide status prefix')),
4402 ('C', 'copies', None, _('show source of copied files')),
4405 ('C', 'copies', None, _('show source of copied files')),
4403 ('0', 'print0', None,
4406 ('0', 'print0', None,
4404 _('end filenames with NUL, for use with xargs')),
4407 _('end filenames with NUL, for use with xargs')),
4405 ('', 'rev', [],
4408 ('', 'rev', [],
4406 _('show difference from revision'), _('REV')),
4409 _('show difference from revision'), _('REV')),
4407 ('', 'change', '',
4410 ('', 'change', '',
4408 _('list the changed files of a revision'), _('REV')),
4411 _('list the changed files of a revision'), _('REV')),
4409 ] + walkopts,
4412 ] + walkopts,
4410 _('[OPTION]... [FILE]...')),
4413 _('[OPTION]... [FILE]...')),
4411 "tag":
4414 "tag":
4412 (tag,
4415 (tag,
4413 [('f', 'force', None, _('replace existing tag')),
4416 [('f', 'force', None, _('replace existing tag')),
4414 ('l', 'local', None, _('make the tag local')),
4417 ('l', 'local', None, _('make the tag local')),
4415 ('r', 'rev', '',
4418 ('r', 'rev', '',
4416 _('revision to tag'), _('REV')),
4419 _('revision to tag'), _('REV')),
4417 ('', 'remove', None, _('remove a tag')),
4420 ('', 'remove', None, _('remove a tag')),
4418 # -l/--local is already there, commitopts cannot be used
4421 # -l/--local is already there, commitopts cannot be used
4419 ('e', 'edit', None, _('edit commit message')),
4422 ('e', 'edit', None, _('edit commit message')),
4420 ('m', 'message', '',
4423 ('m', 'message', '',
4421 _('use <text> as commit message'), _('TEXT')),
4424 _('use <text> as commit message'), _('TEXT')),
4422 ] + commitopts2,
4425 ] + commitopts2,
4423 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4426 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4424 "tags": (tags, [], ''),
4427 "tags": (tags, [], ''),
4425 "tip":
4428 "tip":
4426 (tip,
4429 (tip,
4427 [('p', 'patch', None, _('show patch')),
4430 [('p', 'patch', None, _('show patch')),
4428 ('g', 'git', None, _('use git extended diff format')),
4431 ('g', 'git', None, _('use git extended diff format')),
4429 ] + templateopts,
4432 ] + templateopts,
4430 _('[-p] [-g]')),
4433 _('[-p] [-g]')),
4431 "unbundle":
4434 "unbundle":
4432 (unbundle,
4435 (unbundle,
4433 [('u', 'update', None,
4436 [('u', 'update', None,
4434 _('update to new branch head if changesets were unbundled'))],
4437 _('update to new branch head if changesets were unbundled'))],
4435 _('[-u] FILE...')),
4438 _('[-u] FILE...')),
4436 "^update|up|checkout|co":
4439 "^update|up|checkout|co":
4437 (update,
4440 (update,
4438 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4441 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4439 ('c', 'check', None, _('check for uncommitted changes')),
4442 ('c', 'check', None, _('check for uncommitted changes')),
4440 ('d', 'date', '',
4443 ('d', 'date', '',
4441 _('tipmost revision matching date'), _('DATE')),
4444 _('tipmost revision matching date'), _('DATE')),
4442 ('r', 'rev', '',
4445 ('r', 'rev', '',
4443 _('revision'), _('REV'))],
4446 _('revision'), _('REV'))],
4444 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4447 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4445 "verify": (verify, []),
4448 "verify": (verify, []),
4446 "version": (version_, []),
4449 "version": (version_, []),
4447 }
4450 }
4448
4451
4449 norepo = ("clone init version help debugcommands debugcomplete debugdata"
4452 norepo = ("clone init version help debugcommands debugcomplete debugdata"
4450 " debugindex debugindexdot debugdate debuginstall debugfsinfo"
4453 " debugindex debugindexdot debugdate debuginstall debugfsinfo"
4451 " debugpushkey")
4454 " debugpushkey")
4452 optionalrepo = ("identify paths serve showconfig debugancestor debugdag")
4455 optionalrepo = ("identify paths serve showconfig debugancestor debugdag")
General Comments 0
You need to be logged in to leave comments. Login now