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