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