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