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