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