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