##// END OF EJS Templates
commands: revised documentation of 'default' and 'default-push'...
Faheem Mitha -
r11007:a0102da3 stable
parent child Browse files
Show More
@@ -1,3857 +1,3863 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 662 a) null if -U or the source repository has no changesets
663 663 b) if -u . and the source repository is local, the first parent of
664 664 the source repository's working directory
665 665 c) the changeset specified with -u (if a branch name, this means the
666 666 latest head of that branch)
667 667 d) the changeset specified with -r
668 668 e) the tipmost head specified with -b
669 669 f) the tipmost head specified with the url#branch source syntax
670 670 g) the tipmost head of the default branch
671 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 = 80
1162 1162 if not ui.plain():
1163 1163 width = util.termwidth()
1164 1164 ui.write(patch.diffstat(util.iterlines(it), width=width,
1165 1165 git=diffopts.git))
1166 1166 else:
1167 1167 for chunk in it:
1168 1168 ui.write(chunk)
1169 1169
1170 1170 def export(ui, repo, *changesets, **opts):
1171 1171 """dump the header and diffs for one or more changesets
1172 1172
1173 1173 Print the changeset header and diffs for one or more revisions.
1174 1174
1175 1175 The information shown in the changeset header is: author, date,
1176 1176 branch name (if non-default), changeset hash, parent(s) and commit
1177 1177 comment.
1178 1178
1179 1179 NOTE: export may generate unexpected diff output for merge
1180 1180 changesets, as it will compare the merge changeset against its
1181 1181 first parent only.
1182 1182
1183 1183 Output may be to a file, in which case the name of the file is
1184 1184 given using a format string. The formatting rules are as follows:
1185 1185
1186 1186 :``%%``: literal "%" character
1187 1187 :``%H``: changeset hash (40 bytes of hexadecimal)
1188 1188 :``%N``: number of patches being generated
1189 1189 :``%R``: changeset revision number
1190 1190 :``%b``: basename of the exporting repository
1191 1191 :``%h``: short-form changeset hash (12 bytes of hexadecimal)
1192 1192 :``%n``: zero-padded sequence number, starting at 1
1193 1193 :``%r``: zero-padded changeset revision number
1194 1194
1195 1195 Without the -a/--text option, export will avoid generating diffs
1196 1196 of files it detects as binary. With -a, export will generate a
1197 1197 diff anyway, probably with undesirable results.
1198 1198
1199 1199 Use the -g/--git option to generate diffs in the git extended diff
1200 1200 format. See 'hg help diffs' for more information.
1201 1201
1202 1202 With the --switch-parent option, the diff will be against the
1203 1203 second parent. It can be useful to review a merge.
1204 1204 """
1205 1205 changesets += tuple(opts.get('rev', []))
1206 1206 if not changesets:
1207 1207 raise util.Abort(_("export requires at least one changeset"))
1208 1208 revs = cmdutil.revrange(repo, changesets)
1209 1209 if len(revs) > 1:
1210 1210 ui.note(_('exporting patches:\n'))
1211 1211 else:
1212 1212 ui.note(_('exporting patch:\n'))
1213 1213 patch.export(repo, revs, template=opts.get('output'),
1214 1214 switch_parent=opts.get('switch_parent'),
1215 1215 opts=patch.diffopts(ui, opts))
1216 1216
1217 1217 def forget(ui, repo, *pats, **opts):
1218 1218 """forget the specified files on the next commit
1219 1219
1220 1220 Mark the specified files so they will no longer be tracked
1221 1221 after the next commit.
1222 1222
1223 1223 This only removes files from the current branch, not from the
1224 1224 entire project history, and it does not delete them from the
1225 1225 working directory.
1226 1226
1227 1227 To undo a forget before the next commit, see hg add.
1228 1228 """
1229 1229
1230 1230 if not pats:
1231 1231 raise util.Abort(_('no files specified'))
1232 1232
1233 1233 m = cmdutil.match(repo, pats, opts)
1234 1234 s = repo.status(match=m, clean=True)
1235 1235 forget = sorted(s[0] + s[1] + s[3] + s[6])
1236 1236
1237 1237 for f in m.files():
1238 1238 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1239 1239 ui.warn(_('not removing %s: file is already untracked\n')
1240 1240 % m.rel(f))
1241 1241
1242 1242 for f in forget:
1243 1243 if ui.verbose or not m.exact(f):
1244 1244 ui.status(_('removing %s\n') % m.rel(f))
1245 1245
1246 1246 repo.remove(forget, unlink=False)
1247 1247
1248 1248 def grep(ui, repo, pattern, *pats, **opts):
1249 1249 """search for a pattern in specified files and revisions
1250 1250
1251 1251 Search revisions of files for a regular expression.
1252 1252
1253 1253 This command behaves differently than Unix grep. It only accepts
1254 1254 Python/Perl regexps. It searches repository history, not the
1255 1255 working directory. It always prints the revision number in which a
1256 1256 match appears.
1257 1257
1258 1258 By default, grep only prints output for the first revision of a
1259 1259 file in which it finds a match. To get it to print every revision
1260 1260 that contains a change in match status ("-" for a match that
1261 1261 becomes a non-match, or "+" for a non-match that becomes a match),
1262 1262 use the --all flag.
1263 1263 """
1264 1264 reflags = 0
1265 1265 if opts.get('ignore_case'):
1266 1266 reflags |= re.I
1267 1267 try:
1268 1268 regexp = re.compile(pattern, reflags)
1269 1269 except Exception, inst:
1270 1270 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1271 1271 return None
1272 1272 sep, eol = ':', '\n'
1273 1273 if opts.get('print0'):
1274 1274 sep = eol = '\0'
1275 1275
1276 1276 getfile = util.lrucachefunc(repo.file)
1277 1277
1278 1278 def matchlines(body):
1279 1279 begin = 0
1280 1280 linenum = 0
1281 1281 while True:
1282 1282 match = regexp.search(body, begin)
1283 1283 if not match:
1284 1284 break
1285 1285 mstart, mend = match.span()
1286 1286 linenum += body.count('\n', begin, mstart) + 1
1287 1287 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1288 1288 begin = body.find('\n', mend) + 1 or len(body)
1289 1289 lend = begin - 1
1290 1290 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1291 1291
1292 1292 class linestate(object):
1293 1293 def __init__(self, line, linenum, colstart, colend):
1294 1294 self.line = line
1295 1295 self.linenum = linenum
1296 1296 self.colstart = colstart
1297 1297 self.colend = colend
1298 1298
1299 1299 def __hash__(self):
1300 1300 return hash((self.linenum, self.line))
1301 1301
1302 1302 def __eq__(self, other):
1303 1303 return self.line == other.line
1304 1304
1305 1305 matches = {}
1306 1306 copies = {}
1307 1307 def grepbody(fn, rev, body):
1308 1308 matches[rev].setdefault(fn, [])
1309 1309 m = matches[rev][fn]
1310 1310 for lnum, cstart, cend, line in matchlines(body):
1311 1311 s = linestate(line, lnum, cstart, cend)
1312 1312 m.append(s)
1313 1313
1314 1314 def difflinestates(a, b):
1315 1315 sm = difflib.SequenceMatcher(None, a, b)
1316 1316 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1317 1317 if tag == 'insert':
1318 1318 for i in xrange(blo, bhi):
1319 1319 yield ('+', b[i])
1320 1320 elif tag == 'delete':
1321 1321 for i in xrange(alo, ahi):
1322 1322 yield ('-', a[i])
1323 1323 elif tag == 'replace':
1324 1324 for i in xrange(alo, ahi):
1325 1325 yield ('-', a[i])
1326 1326 for i in xrange(blo, bhi):
1327 1327 yield ('+', b[i])
1328 1328
1329 1329 def display(fn, ctx, pstates, states):
1330 1330 rev = ctx.rev()
1331 1331 datefunc = ui.quiet and util.shortdate or util.datestr
1332 1332 found = False
1333 1333 filerevmatches = {}
1334 1334 if opts.get('all'):
1335 1335 iter = difflinestates(pstates, states)
1336 1336 else:
1337 1337 iter = [('', l) for l in states]
1338 1338 for change, l in iter:
1339 1339 cols = [fn, str(rev)]
1340 1340 if opts.get('line_number'):
1341 1341 cols.append(str(l.linenum))
1342 1342 if opts.get('all'):
1343 1343 cols.append(change)
1344 1344 if opts.get('user'):
1345 1345 cols.append(ui.shortuser(ctx.user()))
1346 1346 if opts.get('date'):
1347 1347 cols.append(datefunc(ctx.date()))
1348 1348 if opts.get('files_with_matches'):
1349 1349 c = (fn, rev)
1350 1350 if c in filerevmatches:
1351 1351 continue
1352 1352 filerevmatches[c] = 1
1353 1353 else:
1354 1354 cols.append(l.line)
1355 1355 ui.write(sep.join(cols), eol)
1356 1356 found = True
1357 1357 return found
1358 1358
1359 1359 skip = {}
1360 1360 revfiles = {}
1361 1361 matchfn = cmdutil.match(repo, pats, opts)
1362 1362 found = False
1363 1363 follow = opts.get('follow')
1364 1364
1365 1365 def prep(ctx, fns):
1366 1366 rev = ctx.rev()
1367 1367 pctx = ctx.parents()[0]
1368 1368 parent = pctx.rev()
1369 1369 matches.setdefault(rev, {})
1370 1370 matches.setdefault(parent, {})
1371 1371 files = revfiles.setdefault(rev, [])
1372 1372 for fn in fns:
1373 1373 flog = getfile(fn)
1374 1374 try:
1375 1375 fnode = ctx.filenode(fn)
1376 1376 except error.LookupError:
1377 1377 continue
1378 1378
1379 1379 copied = flog.renamed(fnode)
1380 1380 copy = follow and copied and copied[0]
1381 1381 if copy:
1382 1382 copies.setdefault(rev, {})[fn] = copy
1383 1383 if fn in skip:
1384 1384 if copy:
1385 1385 skip[copy] = True
1386 1386 continue
1387 1387 files.append(fn)
1388 1388
1389 1389 if fn not in matches[rev]:
1390 1390 grepbody(fn, rev, flog.read(fnode))
1391 1391
1392 1392 pfn = copy or fn
1393 1393 if pfn not in matches[parent]:
1394 1394 try:
1395 1395 fnode = pctx.filenode(pfn)
1396 1396 grepbody(pfn, parent, flog.read(fnode))
1397 1397 except error.LookupError:
1398 1398 pass
1399 1399
1400 1400 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1401 1401 rev = ctx.rev()
1402 1402 parent = ctx.parents()[0].rev()
1403 1403 for fn in sorted(revfiles.get(rev, [])):
1404 1404 states = matches[rev][fn]
1405 1405 copy = copies.get(rev, {}).get(fn)
1406 1406 if fn in skip:
1407 1407 if copy:
1408 1408 skip[copy] = True
1409 1409 continue
1410 1410 pstates = matches.get(parent, {}).get(copy or fn, [])
1411 1411 if pstates or states:
1412 1412 r = display(fn, ctx, pstates, states)
1413 1413 found = found or r
1414 1414 if r and not opts.get('all'):
1415 1415 skip[fn] = True
1416 1416 if copy:
1417 1417 skip[copy] = True
1418 1418 del matches[rev]
1419 1419 del revfiles[rev]
1420 1420
1421 1421 def heads(ui, repo, *branchrevs, **opts):
1422 1422 """show current repository heads or show branch heads
1423 1423
1424 1424 With no arguments, show all repository branch heads.
1425 1425
1426 1426 Repository "heads" are changesets with no child changesets. They are
1427 1427 where development generally takes place and are the usual targets
1428 1428 for update and merge operations. Branch heads are changesets that have
1429 1429 no child changeset on the same branch.
1430 1430
1431 1431 If one or more REVs are given, only branch heads on the branches
1432 1432 associated with the specified changesets are shown.
1433 1433
1434 1434 If -c/--closed is specified, also show branch heads marked closed
1435 1435 (see hg commit --close-branch).
1436 1436
1437 1437 If STARTREV is specified, only those heads that are descendants of
1438 1438 STARTREV will be displayed.
1439 1439
1440 1440 If -t/--topo is specified, named branch mechanics will be ignored and only
1441 1441 changesets without children will be shown.
1442 1442 """
1443 1443
1444 1444 if opts.get('rev'):
1445 1445 start = repo.lookup(opts['rev'])
1446 1446 else:
1447 1447 start = None
1448 1448
1449 1449 if opts.get('topo'):
1450 1450 heads = [repo[h] for h in repo.heads(start)]
1451 1451 else:
1452 1452 heads = []
1453 1453 for b, ls in repo.branchmap().iteritems():
1454 1454 if start is None:
1455 1455 heads += [repo[h] for h in ls]
1456 1456 continue
1457 1457 startrev = repo.changelog.rev(start)
1458 1458 descendants = set(repo.changelog.descendants(startrev))
1459 1459 descendants.add(startrev)
1460 1460 rev = repo.changelog.rev
1461 1461 heads += [repo[h] for h in ls if rev(h) in descendants]
1462 1462
1463 1463 if branchrevs:
1464 1464 decode, encode = encoding.fromlocal, encoding.tolocal
1465 1465 branches = set(repo[decode(br)].branch() for br in branchrevs)
1466 1466 heads = [h for h in heads if h.branch() in branches]
1467 1467
1468 1468 if not opts.get('closed'):
1469 1469 heads = [h for h in heads if not h.extra().get('close')]
1470 1470
1471 1471 if opts.get('active') and branchrevs:
1472 1472 dagheads = repo.heads(start)
1473 1473 heads = [h for h in heads if h.node() in dagheads]
1474 1474
1475 1475 if branchrevs:
1476 1476 haveheads = set(h.branch() for h in heads)
1477 1477 if branches - haveheads:
1478 1478 headless = ', '.join(encode(b) for b in branches - haveheads)
1479 1479 msg = _('no open branch heads found on branches %s')
1480 1480 if opts.get('rev'):
1481 1481 msg += _(' (started at %s)' % opts['rev'])
1482 1482 ui.warn((msg + '\n') % headless)
1483 1483
1484 1484 if not heads:
1485 1485 return 1
1486 1486
1487 1487 heads = sorted(heads, key=lambda x: -x.rev())
1488 1488 displayer = cmdutil.show_changeset(ui, repo, opts)
1489 1489 for ctx in heads:
1490 1490 displayer.show(ctx)
1491 1491 displayer.close()
1492 1492
1493 1493 def help_(ui, name=None, with_version=False, unknowncmd=False):
1494 1494 """show help for a given topic or a help overview
1495 1495
1496 1496 With no arguments, print a list of commands with short help messages.
1497 1497
1498 1498 Given a topic, extension, or command name, print help for that
1499 1499 topic."""
1500 1500 option_lists = []
1501 1501 textwidth = util.termwidth() - 2
1502 1502
1503 1503 def addglobalopts(aliases):
1504 1504 if ui.verbose:
1505 1505 option_lists.append((_("global options:"), globalopts))
1506 1506 if name == 'shortlist':
1507 1507 option_lists.append((_('use "hg help" for the full list '
1508 1508 'of commands'), ()))
1509 1509 else:
1510 1510 if name == 'shortlist':
1511 1511 msg = _('use "hg help" for the full list of commands '
1512 1512 'or "hg -v" for details')
1513 1513 elif aliases:
1514 1514 msg = _('use "hg -v help%s" to show aliases and '
1515 1515 'global options') % (name and " " + name or "")
1516 1516 else:
1517 1517 msg = _('use "hg -v help %s" to show global options') % name
1518 1518 option_lists.append((msg, ()))
1519 1519
1520 1520 def helpcmd(name):
1521 1521 if with_version:
1522 1522 version_(ui)
1523 1523 ui.write('\n')
1524 1524
1525 1525 try:
1526 1526 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1527 1527 except error.AmbiguousCommand, inst:
1528 1528 # py3k fix: except vars can't be used outside the scope of the
1529 1529 # except block, nor can be used inside a lambda. python issue4617
1530 1530 prefix = inst.args[0]
1531 1531 select = lambda c: c.lstrip('^').startswith(prefix)
1532 1532 helplist(_('list of commands:\n\n'), select)
1533 1533 return
1534 1534
1535 1535 # check if it's an invalid alias and display its error if it is
1536 1536 if getattr(entry[0], 'badalias', False):
1537 1537 if not unknowncmd:
1538 1538 entry[0](ui)
1539 1539 return
1540 1540
1541 1541 # synopsis
1542 1542 if len(entry) > 2:
1543 1543 if entry[2].startswith('hg'):
1544 1544 ui.write("%s\n" % entry[2])
1545 1545 else:
1546 1546 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
1547 1547 else:
1548 1548 ui.write('hg %s\n' % aliases[0])
1549 1549
1550 1550 # aliases
1551 1551 if not ui.quiet and len(aliases) > 1:
1552 1552 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1553 1553
1554 1554 # description
1555 1555 doc = gettext(entry[0].__doc__)
1556 1556 if not doc:
1557 1557 doc = _("(no help text available)")
1558 1558 if hasattr(entry[0], 'definition'): # aliased command
1559 1559 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
1560 1560 if ui.quiet:
1561 1561 doc = doc.splitlines()[0]
1562 1562 keep = ui.verbose and ['verbose'] or []
1563 1563 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
1564 1564 ui.write("\n%s\n" % formatted)
1565 1565 if pruned:
1566 1566 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
1567 1567
1568 1568 if not ui.quiet:
1569 1569 # options
1570 1570 if entry[1]:
1571 1571 option_lists.append((_("options:\n"), entry[1]))
1572 1572
1573 1573 addglobalopts(False)
1574 1574
1575 1575 def helplist(header, select=None):
1576 1576 h = {}
1577 1577 cmds = {}
1578 1578 for c, e in table.iteritems():
1579 1579 f = c.split("|", 1)[0]
1580 1580 if select and not select(f):
1581 1581 continue
1582 1582 if (not select and name != 'shortlist' and
1583 1583 e[0].__module__ != __name__):
1584 1584 continue
1585 1585 if name == "shortlist" and not f.startswith("^"):
1586 1586 continue
1587 1587 f = f.lstrip("^")
1588 1588 if not ui.debugflag and f.startswith("debug"):
1589 1589 continue
1590 1590 doc = e[0].__doc__
1591 1591 if doc and 'DEPRECATED' in doc and not ui.verbose:
1592 1592 continue
1593 1593 doc = gettext(doc)
1594 1594 if not doc:
1595 1595 doc = _("(no help text available)")
1596 1596 h[f] = doc.splitlines()[0].rstrip()
1597 1597 cmds[f] = c.lstrip("^")
1598 1598
1599 1599 if not h:
1600 1600 ui.status(_('no commands defined\n'))
1601 1601 return
1602 1602
1603 1603 ui.status(header)
1604 1604 fns = sorted(h)
1605 1605 m = max(map(len, fns))
1606 1606 for f in fns:
1607 1607 if ui.verbose:
1608 1608 commands = cmds[f].replace("|",", ")
1609 1609 ui.write(" %s:\n %s\n"%(commands, h[f]))
1610 1610 else:
1611 1611 ui.write(' %-*s %s\n' % (m, f, util.wrap(h[f], m + 4)))
1612 1612
1613 1613 if not ui.quiet:
1614 1614 addglobalopts(True)
1615 1615
1616 1616 def helptopic(name):
1617 1617 for names, header, doc in help.helptable:
1618 1618 if name in names:
1619 1619 break
1620 1620 else:
1621 1621 raise error.UnknownCommand(name)
1622 1622
1623 1623 # description
1624 1624 if not doc:
1625 1625 doc = _("(no help text available)")
1626 1626 if hasattr(doc, '__call__'):
1627 1627 doc = doc()
1628 1628
1629 1629 ui.write("%s\n\n" % header)
1630 1630 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
1631 1631
1632 1632 def helpext(name):
1633 1633 try:
1634 1634 mod = extensions.find(name)
1635 1635 doc = gettext(mod.__doc__) or _('no help text available')
1636 1636 except KeyError:
1637 1637 mod = None
1638 1638 doc = extensions.disabledext(name)
1639 1639 if not doc:
1640 1640 raise error.UnknownCommand(name)
1641 1641
1642 1642 if '\n' not in doc:
1643 1643 head, tail = doc, ""
1644 1644 else:
1645 1645 head, tail = doc.split('\n', 1)
1646 1646 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
1647 1647 if tail:
1648 1648 ui.write(minirst.format(tail, textwidth))
1649 1649 ui.status('\n\n')
1650 1650
1651 1651 if mod:
1652 1652 try:
1653 1653 ct = mod.cmdtable
1654 1654 except AttributeError:
1655 1655 ct = {}
1656 1656 modcmds = set([c.split('|', 1)[0] for c in ct])
1657 1657 helplist(_('list of commands:\n\n'), modcmds.__contains__)
1658 1658 else:
1659 1659 ui.write(_('use "hg help extensions" for information on enabling '
1660 1660 'extensions\n'))
1661 1661
1662 1662 def helpextcmd(name):
1663 1663 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
1664 1664 doc = gettext(mod.__doc__).splitlines()[0]
1665 1665
1666 1666 msg = help.listexts(_("'%s' is provided by the following "
1667 1667 "extension:") % cmd, {ext: doc}, len(ext),
1668 1668 indent=4)
1669 1669 ui.write(minirst.format(msg, textwidth))
1670 1670 ui.write('\n\n')
1671 1671 ui.write(_('use "hg help extensions" for information on enabling '
1672 1672 'extensions\n'))
1673 1673
1674 1674 if name and name != 'shortlist':
1675 1675 i = None
1676 1676 if unknowncmd:
1677 1677 queries = (helpextcmd,)
1678 1678 else:
1679 1679 queries = (helptopic, helpcmd, helpext, helpextcmd)
1680 1680 for f in queries:
1681 1681 try:
1682 1682 f(name)
1683 1683 i = None
1684 1684 break
1685 1685 except error.UnknownCommand, inst:
1686 1686 i = inst
1687 1687 if i:
1688 1688 raise i
1689 1689
1690 1690 else:
1691 1691 # program name
1692 1692 if ui.verbose or with_version:
1693 1693 version_(ui)
1694 1694 else:
1695 1695 ui.status(_("Mercurial Distributed SCM\n"))
1696 1696 ui.status('\n')
1697 1697
1698 1698 # list of commands
1699 1699 if name == "shortlist":
1700 1700 header = _('basic commands:\n\n')
1701 1701 else:
1702 1702 header = _('list of commands:\n\n')
1703 1703
1704 1704 helplist(header)
1705 1705 if name != 'shortlist':
1706 1706 exts, maxlength = extensions.enabled()
1707 1707 text = help.listexts(_('enabled extensions:'), exts, maxlength)
1708 1708 if text:
1709 1709 ui.write("\n%s\n" % minirst.format(text, textwidth))
1710 1710
1711 1711 # list all option lists
1712 1712 opt_output = []
1713 1713 for title, options in option_lists:
1714 1714 opt_output.append(("\n%s" % title, None))
1715 1715 for shortopt, longopt, default, desc in options:
1716 1716 if _("DEPRECATED") in desc and not ui.verbose:
1717 1717 continue
1718 1718 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1719 1719 longopt and " --%s" % longopt),
1720 1720 "%s%s" % (desc,
1721 1721 default
1722 1722 and _(" (default: %s)") % default
1723 1723 or "")))
1724 1724
1725 1725 if not name:
1726 1726 ui.write(_("\nadditional help topics:\n\n"))
1727 1727 topics = []
1728 1728 for names, header, doc in help.helptable:
1729 1729 topics.append((sorted(names, key=len, reverse=True)[0], header))
1730 1730 topics_len = max([len(s[0]) for s in topics])
1731 1731 for t, desc in topics:
1732 1732 ui.write(" %-*s %s\n" % (topics_len, t, desc))
1733 1733
1734 1734 if opt_output:
1735 1735 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1736 1736 for first, second in opt_output:
1737 1737 if second:
1738 1738 second = util.wrap(second, opts_len + 3)
1739 1739 ui.write(" %-*s %s\n" % (opts_len, first, second))
1740 1740 else:
1741 1741 ui.write("%s\n" % first)
1742 1742
1743 1743 def identify(ui, repo, source=None,
1744 1744 rev=None, num=None, id=None, branch=None, tags=None):
1745 1745 """identify the working copy or specified revision
1746 1746
1747 1747 With no revision, print a summary of the current state of the
1748 1748 repository.
1749 1749
1750 1750 Specifying a path to a repository root or Mercurial bundle will
1751 1751 cause lookup to operate on that repository/bundle.
1752 1752
1753 1753 This summary identifies the repository state using one or two
1754 1754 parent hash identifiers, followed by a "+" if there are
1755 1755 uncommitted changes in the working directory, a list of tags for
1756 1756 this revision and a branch name for non-default branches.
1757 1757 """
1758 1758
1759 1759 if not repo and not source:
1760 1760 raise util.Abort(_("There is no Mercurial repository here "
1761 1761 "(.hg not found)"))
1762 1762
1763 1763 hexfunc = ui.debugflag and hex or short
1764 1764 default = not (num or id or branch or tags)
1765 1765 output = []
1766 1766
1767 1767 revs = []
1768 1768 if source:
1769 1769 source, branches = hg.parseurl(ui.expandpath(source))
1770 1770 repo = hg.repository(ui, source)
1771 1771 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
1772 1772
1773 1773 if not repo.local():
1774 1774 if not rev and revs:
1775 1775 rev = revs[0]
1776 1776 if not rev:
1777 1777 rev = "tip"
1778 1778 if num or branch or tags:
1779 1779 raise util.Abort(
1780 1780 "can't query remote revision number, branch, or tags")
1781 1781 output = [hexfunc(repo.lookup(rev))]
1782 1782 elif not rev:
1783 1783 ctx = repo[None]
1784 1784 parents = ctx.parents()
1785 1785 changed = False
1786 1786 if default or id or num:
1787 1787 changed = util.any(repo.status())
1788 1788 if default or id:
1789 1789 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
1790 1790 (changed) and "+" or "")]
1791 1791 if num:
1792 1792 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
1793 1793 (changed) and "+" or ""))
1794 1794 else:
1795 1795 ctx = repo[rev]
1796 1796 if default or id:
1797 1797 output = [hexfunc(ctx.node())]
1798 1798 if num:
1799 1799 output.append(str(ctx.rev()))
1800 1800
1801 1801 if repo.local() and default and not ui.quiet:
1802 1802 b = encoding.tolocal(ctx.branch())
1803 1803 if b != 'default':
1804 1804 output.append("(%s)" % b)
1805 1805
1806 1806 # multiple tags for a single parent separated by '/'
1807 1807 t = "/".join(ctx.tags())
1808 1808 if t:
1809 1809 output.append(t)
1810 1810
1811 1811 if branch:
1812 1812 output.append(encoding.tolocal(ctx.branch()))
1813 1813
1814 1814 if tags:
1815 1815 output.extend(ctx.tags())
1816 1816
1817 1817 ui.write("%s\n" % ' '.join(output))
1818 1818
1819 1819 def import_(ui, repo, patch1, *patches, **opts):
1820 1820 """import an ordered set of patches
1821 1821
1822 1822 Import a list of patches and commit them individually (unless
1823 1823 --no-commit is specified).
1824 1824
1825 1825 If there are outstanding changes in the working directory, import
1826 1826 will abort unless given the -f/--force flag.
1827 1827
1828 1828 You can import a patch straight from a mail message. Even patches
1829 1829 as attachments work (to use the body part, it must have type
1830 1830 text/plain or text/x-patch). From and Subject headers of email
1831 1831 message are used as default committer and commit message. All
1832 1832 text/plain body parts before first diff are added to commit
1833 1833 message.
1834 1834
1835 1835 If the imported patch was generated by hg export, user and
1836 1836 description from patch override values from message headers and
1837 1837 body. Values given on command line with -m/--message and -u/--user
1838 1838 override these.
1839 1839
1840 1840 If --exact is specified, import will set the working directory to
1841 1841 the parent of each patch before applying it, and will abort if the
1842 1842 resulting changeset has a different ID than the one recorded in
1843 1843 the patch. This may happen due to character set problems or other
1844 1844 deficiencies in the text patch format.
1845 1845
1846 1846 With -s/--similarity, hg will attempt to discover renames and
1847 1847 copies in the patch in the same way as 'addremove'.
1848 1848
1849 1849 To read a patch from standard input, use "-" as the patch name. If
1850 1850 a URL is specified, the patch will be downloaded from it.
1851 1851 See 'hg help dates' for a list of formats valid for -d/--date.
1852 1852 """
1853 1853 patches = (patch1,) + patches
1854 1854
1855 1855 date = opts.get('date')
1856 1856 if date:
1857 1857 opts['date'] = util.parsedate(date)
1858 1858
1859 1859 try:
1860 1860 sim = float(opts.get('similarity') or 0)
1861 1861 except ValueError:
1862 1862 raise util.Abort(_('similarity must be a number'))
1863 1863 if sim < 0 or sim > 100:
1864 1864 raise util.Abort(_('similarity must be between 0 and 100'))
1865 1865
1866 1866 if opts.get('exact') or not opts.get('force'):
1867 1867 cmdutil.bail_if_changed(repo)
1868 1868
1869 1869 d = opts["base"]
1870 1870 strip = opts["strip"]
1871 1871 wlock = lock = None
1872 1872
1873 1873 def tryone(ui, hunk):
1874 1874 tmpname, message, user, date, branch, nodeid, p1, p2 = \
1875 1875 patch.extract(ui, hunk)
1876 1876
1877 1877 if not tmpname:
1878 1878 return None
1879 1879 commitid = _('to working directory')
1880 1880
1881 1881 try:
1882 1882 cmdline_message = cmdutil.logmessage(opts)
1883 1883 if cmdline_message:
1884 1884 # pickup the cmdline msg
1885 1885 message = cmdline_message
1886 1886 elif message:
1887 1887 # pickup the patch msg
1888 1888 message = message.strip()
1889 1889 else:
1890 1890 # launch the editor
1891 1891 message = None
1892 1892 ui.debug('message:\n%s\n' % message)
1893 1893
1894 1894 wp = repo.parents()
1895 1895 if opts.get('exact'):
1896 1896 if not nodeid or not p1:
1897 1897 raise util.Abort(_('not a Mercurial patch'))
1898 1898 p1 = repo.lookup(p1)
1899 1899 p2 = repo.lookup(p2 or hex(nullid))
1900 1900
1901 1901 if p1 != wp[0].node():
1902 1902 hg.clean(repo, p1)
1903 1903 repo.dirstate.setparents(p1, p2)
1904 1904 elif p2:
1905 1905 try:
1906 1906 p1 = repo.lookup(p1)
1907 1907 p2 = repo.lookup(p2)
1908 1908 if p1 == wp[0].node():
1909 1909 repo.dirstate.setparents(p1, p2)
1910 1910 except error.RepoError:
1911 1911 pass
1912 1912 if opts.get('exact') or opts.get('import_branch'):
1913 1913 repo.dirstate.setbranch(branch or 'default')
1914 1914
1915 1915 files = {}
1916 1916 try:
1917 1917 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1918 1918 files=files, eolmode=None)
1919 1919 finally:
1920 1920 files = patch.updatedir(ui, repo, files,
1921 1921 similarity=sim / 100.0)
1922 1922 if not opts.get('no_commit'):
1923 1923 if opts.get('exact'):
1924 1924 m = None
1925 1925 else:
1926 1926 m = cmdutil.matchfiles(repo, files or [])
1927 1927 n = repo.commit(message, opts.get('user') or user,
1928 1928 opts.get('date') or date, match=m,
1929 1929 editor=cmdutil.commiteditor)
1930 1930 if opts.get('exact'):
1931 1931 if hex(n) != nodeid:
1932 1932 repo.rollback()
1933 1933 raise util.Abort(_('patch is damaged'
1934 1934 ' or loses information'))
1935 1935 # Force a dirstate write so that the next transaction
1936 1936 # backups an up-do-date file.
1937 1937 repo.dirstate.write()
1938 1938 if n:
1939 1939 commitid = short(n)
1940 1940
1941 1941 return commitid
1942 1942 finally:
1943 1943 os.unlink(tmpname)
1944 1944
1945 1945 try:
1946 1946 wlock = repo.wlock()
1947 1947 lock = repo.lock()
1948 1948 lastcommit = None
1949 1949 for p in patches:
1950 1950 pf = os.path.join(d, p)
1951 1951
1952 1952 if pf == '-':
1953 1953 ui.status(_("applying patch from stdin\n"))
1954 1954 pf = sys.stdin
1955 1955 else:
1956 1956 ui.status(_("applying %s\n") % p)
1957 1957 pf = url.open(ui, pf)
1958 1958
1959 1959 haspatch = False
1960 1960 for hunk in patch.split(pf):
1961 1961 commitid = tryone(ui, hunk)
1962 1962 if commitid:
1963 1963 haspatch = True
1964 1964 if lastcommit:
1965 1965 ui.status(_('applied %s\n') % lastcommit)
1966 1966 lastcommit = commitid
1967 1967
1968 1968 if not haspatch:
1969 1969 raise util.Abort(_('no diffs found'))
1970 1970
1971 1971 finally:
1972 1972 release(lock, wlock)
1973 1973
1974 1974 def incoming(ui, repo, source="default", **opts):
1975 1975 """show new changesets found in source
1976 1976
1977 1977 Show new changesets found in the specified path/URL or the default
1978 1978 pull location. These are the changesets that would have been pulled
1979 1979 if a pull at the time you issued this command.
1980 1980
1981 1981 For remote repository, using --bundle avoids downloading the
1982 1982 changesets twice if the incoming is followed by a pull.
1983 1983
1984 1984 See pull for valid source format details.
1985 1985 """
1986 1986 limit = cmdutil.loglimit(opts)
1987 1987 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
1988 1988 other = hg.repository(cmdutil.remoteui(repo, opts), source)
1989 1989 ui.status(_('comparing with %s\n') % url.hidepassword(source))
1990 1990 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
1991 1991 if revs:
1992 1992 revs = [other.lookup(rev) for rev in revs]
1993 1993 common, incoming, rheads = repo.findcommonincoming(other, heads=revs,
1994 1994 force=opts["force"])
1995 1995 if not incoming:
1996 1996 try:
1997 1997 os.unlink(opts["bundle"])
1998 1998 except:
1999 1999 pass
2000 2000 ui.status(_("no changes found\n"))
2001 2001 return 1
2002 2002
2003 2003 cleanup = None
2004 2004 try:
2005 2005 fname = opts["bundle"]
2006 2006 if fname or not other.local():
2007 2007 # create a bundle (uncompressed if other repo is not local)
2008 2008
2009 2009 if revs is None and other.capable('changegroupsubset'):
2010 2010 revs = rheads
2011 2011
2012 2012 if revs is None:
2013 2013 cg = other.changegroup(incoming, "incoming")
2014 2014 else:
2015 2015 cg = other.changegroupsubset(incoming, revs, 'incoming')
2016 2016 bundletype = other.local() and "HG10BZ" or "HG10UN"
2017 2017 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
2018 2018 # keep written bundle?
2019 2019 if opts["bundle"]:
2020 2020 cleanup = None
2021 2021 if not other.local():
2022 2022 # use the created uncompressed bundlerepo
2023 2023 other = bundlerepo.bundlerepository(ui, repo.root, fname)
2024 2024
2025 2025 o = other.changelog.nodesbetween(incoming, revs)[0]
2026 2026 if opts.get('newest_first'):
2027 2027 o.reverse()
2028 2028 displayer = cmdutil.show_changeset(ui, other, opts)
2029 2029 count = 0
2030 2030 for n in o:
2031 2031 if limit is not None and count >= limit:
2032 2032 break
2033 2033 parents = [p for p in other.changelog.parents(n) if p != nullid]
2034 2034 if opts.get('no_merges') and len(parents) == 2:
2035 2035 continue
2036 2036 count += 1
2037 2037 displayer.show(other[n])
2038 2038 displayer.close()
2039 2039 finally:
2040 2040 if hasattr(other, 'close'):
2041 2041 other.close()
2042 2042 if cleanup:
2043 2043 os.unlink(cleanup)
2044 2044
2045 2045 def init(ui, dest=".", **opts):
2046 2046 """create a new repository in the given directory
2047 2047
2048 2048 Initialize a new repository in the given directory. If the given
2049 2049 directory does not exist, it will be created.
2050 2050
2051 2051 If no directory is given, the current directory is used.
2052 2052
2053 2053 It is possible to specify an ``ssh://`` URL as the destination.
2054 2054 See 'hg help urls' for more information.
2055 2055 """
2056 2056 hg.repository(cmdutil.remoteui(ui, opts), dest, create=1)
2057 2057
2058 2058 def locate(ui, repo, *pats, **opts):
2059 2059 """locate files matching specific patterns
2060 2060
2061 2061 Print files under Mercurial control in the working directory whose
2062 2062 names match the given patterns.
2063 2063
2064 2064 By default, this command searches all directories in the working
2065 2065 directory. To search just the current directory and its
2066 2066 subdirectories, use "--include .".
2067 2067
2068 2068 If no patterns are given to match, this command prints the names
2069 2069 of all files under Mercurial control in the working directory.
2070 2070
2071 2071 If you want to feed the output of this command into the "xargs"
2072 2072 command, use the -0 option to both this command and "xargs". This
2073 2073 will avoid the problem of "xargs" treating single filenames that
2074 2074 contain whitespace as multiple filenames.
2075 2075 """
2076 2076 end = opts.get('print0') and '\0' or '\n'
2077 2077 rev = opts.get('rev') or None
2078 2078
2079 2079 ret = 1
2080 2080 m = cmdutil.match(repo, pats, opts, default='relglob')
2081 2081 m.bad = lambda x, y: False
2082 2082 for abs in repo[rev].walk(m):
2083 2083 if not rev and abs not in repo.dirstate:
2084 2084 continue
2085 2085 if opts.get('fullpath'):
2086 2086 ui.write(repo.wjoin(abs), end)
2087 2087 else:
2088 2088 ui.write(((pats and m.rel(abs)) or abs), end)
2089 2089 ret = 0
2090 2090
2091 2091 return ret
2092 2092
2093 2093 def log(ui, repo, *pats, **opts):
2094 2094 """show revision history of entire repository or files
2095 2095
2096 2096 Print the revision history of the specified files or the entire
2097 2097 project.
2098 2098
2099 2099 File history is shown without following rename or copy history of
2100 2100 files. Use -f/--follow with a filename to follow history across
2101 2101 renames and copies. --follow without a filename will only show
2102 2102 ancestors or descendants of the starting revision. --follow-first
2103 2103 only follows the first parent of merge revisions.
2104 2104
2105 2105 If no revision range is specified, the default is tip:0 unless
2106 2106 --follow is set, in which case the working directory parent is
2107 2107 used as the starting revision.
2108 2108
2109 2109 See 'hg help dates' for a list of formats valid for -d/--date.
2110 2110
2111 2111 By default this command prints revision number and changeset id,
2112 2112 tags, non-trivial parents, user, date and time, and a summary for
2113 2113 each commit. When the -v/--verbose switch is used, the list of
2114 2114 changed files and full commit message are shown.
2115 2115
2116 2116 NOTE: log -p/--patch may generate unexpected diff output for merge
2117 2117 changesets, as it will only compare the merge changeset against
2118 2118 its first parent. Also, only files different from BOTH parents
2119 2119 will appear in files:.
2120 2120 """
2121 2121
2122 2122 matchfn = cmdutil.match(repo, pats, opts)
2123 2123 limit = cmdutil.loglimit(opts)
2124 2124 count = 0
2125 2125
2126 2126 endrev = None
2127 2127 if opts.get('copies') and opts.get('rev'):
2128 2128 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2129 2129
2130 2130 df = False
2131 2131 if opts["date"]:
2132 2132 df = util.matchdate(opts["date"])
2133 2133
2134 2134 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
2135 2135 def prep(ctx, fns):
2136 2136 rev = ctx.rev()
2137 2137 parents = [p for p in repo.changelog.parentrevs(rev)
2138 2138 if p != nullrev]
2139 2139 if opts.get('no_merges') and len(parents) == 2:
2140 2140 return
2141 2141 if opts.get('only_merges') and len(parents) != 2:
2142 2142 return
2143 2143 if opts.get('only_branch') and ctx.branch() not in opts['only_branch']:
2144 2144 return
2145 2145 if df and not df(ctx.date()[0]):
2146 2146 return
2147 2147 if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
2148 2148 return
2149 2149 if opts.get('keyword'):
2150 2150 for k in [kw.lower() for kw in opts['keyword']]:
2151 2151 if (k in ctx.user().lower() or
2152 2152 k in ctx.description().lower() or
2153 2153 k in " ".join(ctx.files()).lower()):
2154 2154 break
2155 2155 else:
2156 2156 return
2157 2157
2158 2158 copies = None
2159 2159 if opts.get('copies') and rev:
2160 2160 copies = []
2161 2161 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2162 2162 for fn in ctx.files():
2163 2163 rename = getrenamed(fn, rev)
2164 2164 if rename:
2165 2165 copies.append((fn, rename[0]))
2166 2166
2167 2167 displayer.show(ctx, copies=copies)
2168 2168
2169 2169 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2170 2170 if count == limit:
2171 2171 break
2172 2172 if displayer.flush(ctx.rev()):
2173 2173 count += 1
2174 2174 displayer.close()
2175 2175
2176 2176 def manifest(ui, repo, node=None, rev=None):
2177 2177 """output the current or given revision of the project manifest
2178 2178
2179 2179 Print a list of version controlled files for the given revision.
2180 2180 If no revision is given, the first parent of the working directory
2181 2181 is used, or the null revision if no revision is checked out.
2182 2182
2183 2183 With -v, print file permissions, symlink and executable bits.
2184 2184 With --debug, print file revision hashes.
2185 2185 """
2186 2186
2187 2187 if rev and node:
2188 2188 raise util.Abort(_("please specify just one revision"))
2189 2189
2190 2190 if not node:
2191 2191 node = rev
2192 2192
2193 2193 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2194 2194 ctx = repo[node]
2195 2195 for f in ctx:
2196 2196 if ui.debugflag:
2197 2197 ui.write("%40s " % hex(ctx.manifest()[f]))
2198 2198 if ui.verbose:
2199 2199 ui.write(decor[ctx.flags(f)])
2200 2200 ui.write("%s\n" % f)
2201 2201
2202 2202 def merge(ui, repo, node=None, **opts):
2203 2203 """merge working directory with another revision
2204 2204
2205 2205 The current working directory is updated with all changes made in
2206 2206 the requested revision since the last common predecessor revision.
2207 2207
2208 2208 Files that changed between either parent are marked as changed for
2209 2209 the next commit and a commit must be performed before any further
2210 2210 updates to the repository are allowed. The next commit will have
2211 2211 two parents.
2212 2212
2213 2213 If no revision is specified, the working directory's parent is a
2214 2214 head revision, and the current branch contains exactly one other
2215 2215 head, the other head is merged with by default. Otherwise, an
2216 2216 explicit revision with which to merge with must be provided.
2217 2217 """
2218 2218
2219 2219 if opts.get('rev') and node:
2220 2220 raise util.Abort(_("please specify just one revision"))
2221 2221 if not node:
2222 2222 node = opts.get('rev')
2223 2223
2224 2224 if not node:
2225 2225 branch = repo.changectx(None).branch()
2226 2226 bheads = repo.branchheads(branch)
2227 2227 if len(bheads) > 2:
2228 2228 ui.warn(_("abort: branch '%s' has %d heads - "
2229 2229 "please merge with an explicit rev\n")
2230 2230 % (branch, len(bheads)))
2231 2231 ui.status(_("(run 'hg heads .' to see heads)\n"))
2232 2232 return False
2233 2233
2234 2234 parent = repo.dirstate.parents()[0]
2235 2235 if len(bheads) == 1:
2236 2236 if len(repo.heads()) > 1:
2237 2237 ui.warn(_("abort: branch '%s' has one head - "
2238 2238 "please merge with an explicit rev\n" % branch))
2239 2239 ui.status(_("(run 'hg heads' to see all heads)\n"))
2240 2240 return False
2241 2241 msg = _('there is nothing to merge')
2242 2242 if parent != repo.lookup(repo[None].branch()):
2243 2243 msg = _('%s - use "hg update" instead') % msg
2244 2244 raise util.Abort(msg)
2245 2245
2246 2246 if parent not in bheads:
2247 2247 raise util.Abort(_('working dir not at a head rev - '
2248 2248 'use "hg update" or merge with an explicit rev'))
2249 2249 node = parent == bheads[0] and bheads[-1] or bheads[0]
2250 2250
2251 2251 if opts.get('preview'):
2252 2252 # find nodes that are ancestors of p2 but not of p1
2253 2253 p1 = repo.lookup('.')
2254 2254 p2 = repo.lookup(node)
2255 2255 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2256 2256
2257 2257 displayer = cmdutil.show_changeset(ui, repo, opts)
2258 2258 for node in nodes:
2259 2259 displayer.show(repo[node])
2260 2260 displayer.close()
2261 2261 return 0
2262 2262
2263 2263 return hg.merge(repo, node, force=opts.get('force'))
2264 2264
2265 2265 def outgoing(ui, repo, dest=None, **opts):
2266 2266 """show changesets not found in the destination
2267 2267
2268 2268 Show changesets not found in the specified destination repository
2269 2269 or the default push location. These are the changesets that would
2270 2270 be pushed if a push was requested.
2271 2271
2272 2272 See pull for details of valid destination formats.
2273 2273 """
2274 2274 limit = cmdutil.loglimit(opts)
2275 2275 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2276 2276 dest, branches = hg.parseurl(dest, opts.get('branch'))
2277 2277 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2278 2278 if revs:
2279 2279 revs = [repo.lookup(rev) for rev in revs]
2280 2280
2281 2281 other = hg.repository(cmdutil.remoteui(repo, opts), dest)
2282 2282 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2283 2283 o = repo.findoutgoing(other, force=opts.get('force'))
2284 2284 if not o:
2285 2285 ui.status(_("no changes found\n"))
2286 2286 return 1
2287 2287 o = repo.changelog.nodesbetween(o, revs)[0]
2288 2288 if opts.get('newest_first'):
2289 2289 o.reverse()
2290 2290 displayer = cmdutil.show_changeset(ui, repo, opts)
2291 2291 count = 0
2292 2292 for n in o:
2293 2293 if limit is not None and count >= limit:
2294 2294 break
2295 2295 parents = [p for p in repo.changelog.parents(n) if p != nullid]
2296 2296 if opts.get('no_merges') and len(parents) == 2:
2297 2297 continue
2298 2298 count += 1
2299 2299 displayer.show(repo[n])
2300 2300 displayer.close()
2301 2301
2302 2302 def parents(ui, repo, file_=None, **opts):
2303 2303 """show the parents of the working directory or revision
2304 2304
2305 2305 Print the working directory's parent revisions. If a revision is
2306 2306 given via -r/--rev, the parent of that revision will be printed.
2307 2307 If a file argument is given, the revision in which the file was
2308 2308 last changed (before the working directory revision or the
2309 2309 argument to --rev if given) is printed.
2310 2310 """
2311 2311 rev = opts.get('rev')
2312 2312 if rev:
2313 2313 ctx = repo[rev]
2314 2314 else:
2315 2315 ctx = repo[None]
2316 2316
2317 2317 if file_:
2318 2318 m = cmdutil.match(repo, (file_,), opts)
2319 2319 if m.anypats() or len(m.files()) != 1:
2320 2320 raise util.Abort(_('can only specify an explicit filename'))
2321 2321 file_ = m.files()[0]
2322 2322 filenodes = []
2323 2323 for cp in ctx.parents():
2324 2324 if not cp:
2325 2325 continue
2326 2326 try:
2327 2327 filenodes.append(cp.filenode(file_))
2328 2328 except error.LookupError:
2329 2329 pass
2330 2330 if not filenodes:
2331 2331 raise util.Abort(_("'%s' not found in manifest!") % file_)
2332 2332 fl = repo.file(file_)
2333 2333 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2334 2334 else:
2335 2335 p = [cp.node() for cp in ctx.parents()]
2336 2336
2337 2337 displayer = cmdutil.show_changeset(ui, repo, opts)
2338 2338 for n in p:
2339 2339 if n != nullid:
2340 2340 displayer.show(repo[n])
2341 2341 displayer.close()
2342 2342
2343 2343 def paths(ui, repo, search=None):
2344 2344 """show aliases for remote repositories
2345 2345
2346 2346 Show definition of symbolic path name NAME. If no name is given,
2347 2347 show definition of all available names.
2348 2348
2349 2349 Path names are defined in the [paths] section of /etc/mercurial/hgrc
2350 2350 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
2351 2351
2352 The names 'default' and 'default-push' have a special meaning.
2353 They are the locations used when pulling and pushing respectively
2354 unless a location is specified. When cloning a repository, the
2355 clone source is written as 'default' in .hg/hgrc.
2352 The path names ``default`` and ``default-push`` have a special
2353 meaning. When performing a push or pull operation, they are used
2354 as fallbacks if no location is specified on the command-line.
2355 When ``default-push`` is set, it will be used for push and
2356 ``default`` will be used for pull; otherwise ``default`` is used
2357 as the fallback for both. When cloning a repository, the clone
2358 source is written as ``default`` in ``.hg/hgrc``. Note that
2359 ``default`` and ``default-push`` apply to all inbound (e.g. ``hg
2360 incoming``) and outbound (e.g. ``hg outgoing``, ``hg email`` and
2361 ``hg bundle``) operations.
2356 2362
2357 2363 See 'hg help urls' for more information.
2358 2364 """
2359 2365 if search:
2360 2366 for name, path in ui.configitems("paths"):
2361 2367 if name == search:
2362 2368 ui.write("%s\n" % url.hidepassword(path))
2363 2369 return
2364 2370 ui.warn(_("not found!\n"))
2365 2371 return 1
2366 2372 else:
2367 2373 for name, path in ui.configitems("paths"):
2368 2374 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2369 2375
2370 2376 def postincoming(ui, repo, modheads, optupdate, checkout):
2371 2377 if modheads == 0:
2372 2378 return
2373 2379 if optupdate:
2374 2380 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2375 2381 return hg.update(repo, checkout)
2376 2382 else:
2377 2383 ui.status(_("not updating, since new heads added\n"))
2378 2384 if modheads > 1:
2379 2385 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2380 2386 else:
2381 2387 ui.status(_("(run 'hg update' to get a working copy)\n"))
2382 2388
2383 2389 def pull(ui, repo, source="default", **opts):
2384 2390 """pull changes from the specified source
2385 2391
2386 2392 Pull changes from a remote repository to a local one.
2387 2393
2388 2394 This finds all changes from the repository at the specified path
2389 2395 or URL and adds them to a local repository (the current one unless
2390 2396 -R is specified). By default, this does not update the copy of the
2391 2397 project in the working directory.
2392 2398
2393 2399 Use hg incoming if you want to see what would have been added by a
2394 2400 pull at the time you issued this command. If you then decide to
2395 2401 added those changes to the repository, you should use pull -r X
2396 2402 where X is the last changeset listed by hg incoming.
2397 2403
2398 2404 If SOURCE is omitted, the 'default' path will be used.
2399 2405 See 'hg help urls' for more information.
2400 2406 """
2401 2407 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2402 2408 other = hg.repository(cmdutil.remoteui(repo, opts), source)
2403 2409 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2404 2410 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2405 2411 if revs:
2406 2412 try:
2407 2413 revs = [other.lookup(rev) for rev in revs]
2408 2414 except error.CapabilityError:
2409 2415 err = _("Other repository doesn't support revision lookup, "
2410 2416 "so a rev cannot be specified.")
2411 2417 raise util.Abort(err)
2412 2418
2413 2419 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2414 2420 if checkout:
2415 2421 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2416 2422 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2417 2423
2418 2424 def push(ui, repo, dest=None, **opts):
2419 2425 """push changes to the specified destination
2420 2426
2421 2427 Push changes from the local repository to the specified destination.
2422 2428
2423 2429 This is the symmetrical operation for pull. It moves changes from
2424 2430 the current repository to a different one. If the destination is
2425 2431 local this is identical to a pull in that directory from the
2426 2432 current one.
2427 2433
2428 2434 By default, push will refuse to run if it detects the result would
2429 2435 increase the number of remote heads. This generally indicates the
2430 2436 user forgot to pull and merge before pushing.
2431 2437
2432 2438 If -r/--rev is used, the named revision and all its ancestors will
2433 2439 be pushed to the remote repository.
2434 2440
2435 2441 Please see 'hg help urls' for important details about ``ssh://``
2436 2442 URLs. If DESTINATION is omitted, a default path will be used.
2437 2443 """
2438 2444 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2439 2445 dest, branches = hg.parseurl(dest, opts.get('branch'))
2440 2446 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2441 2447 other = hg.repository(cmdutil.remoteui(repo, opts), dest)
2442 2448 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2443 2449 if revs:
2444 2450 revs = [repo.lookup(rev) for rev in revs]
2445 2451
2446 2452 # push subrepos depth-first for coherent ordering
2447 2453 c = repo['']
2448 2454 subs = c.substate # only repos that are committed
2449 2455 for s in sorted(subs):
2450 2456 c.sub(s).push(opts.get('force'))
2451 2457
2452 2458 r = repo.push(other, opts.get('force'), revs=revs)
2453 2459 return r == 0
2454 2460
2455 2461 def recover(ui, repo):
2456 2462 """roll back an interrupted transaction
2457 2463
2458 2464 Recover from an interrupted commit or pull.
2459 2465
2460 2466 This command tries to fix the repository status after an
2461 2467 interrupted operation. It should only be necessary when Mercurial
2462 2468 suggests it.
2463 2469 """
2464 2470 if repo.recover():
2465 2471 return hg.verify(repo)
2466 2472 return 1
2467 2473
2468 2474 def remove(ui, repo, *pats, **opts):
2469 2475 """remove the specified files on the next commit
2470 2476
2471 2477 Schedule the indicated files for removal from the repository.
2472 2478
2473 2479 This only removes files from the current branch, not from the
2474 2480 entire project history. -A/--after can be used to remove only
2475 2481 files that have already been deleted, -f/--force can be used to
2476 2482 force deletion, and -Af can be used to remove files from the next
2477 2483 revision without deleting them from the working directory.
2478 2484
2479 2485 The following table details the behavior of remove for different
2480 2486 file states (columns) and option combinations (rows). The file
2481 2487 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
2482 2488 reported by hg status). The actions are Warn, Remove (from branch)
2483 2489 and Delete (from disk)::
2484 2490
2485 2491 A C M !
2486 2492 none W RD W R
2487 2493 -f R RD RD R
2488 2494 -A W W W R
2489 2495 -Af R R R R
2490 2496
2491 2497 This command schedules the files to be removed at the next commit.
2492 2498 To undo a remove before that, see hg revert.
2493 2499 """
2494 2500
2495 2501 after, force = opts.get('after'), opts.get('force')
2496 2502 if not pats and not after:
2497 2503 raise util.Abort(_('no files specified'))
2498 2504
2499 2505 m = cmdutil.match(repo, pats, opts)
2500 2506 s = repo.status(match=m, clean=True)
2501 2507 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2502 2508
2503 2509 for f in m.files():
2504 2510 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2505 2511 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2506 2512
2507 2513 def warn(files, reason):
2508 2514 for f in files:
2509 2515 ui.warn(_('not removing %s: file %s (use -f to force removal)\n')
2510 2516 % (m.rel(f), reason))
2511 2517
2512 2518 if force:
2513 2519 remove, forget = modified + deleted + clean, added
2514 2520 elif after:
2515 2521 remove, forget = deleted, []
2516 2522 warn(modified + added + clean, _('still exists'))
2517 2523 else:
2518 2524 remove, forget = deleted + clean, []
2519 2525 warn(modified, _('is modified'))
2520 2526 warn(added, _('has been marked for add'))
2521 2527
2522 2528 for f in sorted(remove + forget):
2523 2529 if ui.verbose or not m.exact(f):
2524 2530 ui.status(_('removing %s\n') % m.rel(f))
2525 2531
2526 2532 repo.forget(forget)
2527 2533 repo.remove(remove, unlink=not after)
2528 2534
2529 2535 def rename(ui, repo, *pats, **opts):
2530 2536 """rename files; equivalent of copy + remove
2531 2537
2532 2538 Mark dest as copies of sources; mark sources for deletion. If dest
2533 2539 is a directory, copies are put in that directory. If dest is a
2534 2540 file, there can only be one source.
2535 2541
2536 2542 By default, this command copies the contents of files as they
2537 2543 exist in the working directory. If invoked with -A/--after, the
2538 2544 operation is recorded, but no copying is performed.
2539 2545
2540 2546 This command takes effect at the next commit. To undo a rename
2541 2547 before that, see hg revert.
2542 2548 """
2543 2549 wlock = repo.wlock(False)
2544 2550 try:
2545 2551 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2546 2552 finally:
2547 2553 wlock.release()
2548 2554
2549 2555 def resolve(ui, repo, *pats, **opts):
2550 2556 """various operations to help finish a merge
2551 2557
2552 2558 This command includes several actions that are often useful while
2553 2559 performing a merge, after running ``merge`` but before running
2554 2560 ``commit``. (It is only meaningful if your working directory has
2555 2561 two parents.) It is most relevant for merges with unresolved
2556 2562 conflicts, which are typically a result of non-interactive merging with
2557 2563 ``internal:merge`` or a command-line merge tool like ``diff3``.
2558 2564
2559 2565 The available actions are:
2560 2566
2561 2567 1) list files that were merged with conflicts (U, for unresolved)
2562 2568 and without conflicts (R, for resolved): ``hg resolve -l``
2563 2569 (this is like ``status`` for merges)
2564 2570 2) record that you have resolved conflicts in certain files:
2565 2571 ``hg resolve -m [file ...]`` (default: mark all unresolved files)
2566 2572 3) forget that you have resolved conflicts in certain files:
2567 2573 ``hg resolve -u [file ...]`` (default: unmark all resolved files)
2568 2574 4) discard your current attempt(s) at resolving conflicts and
2569 2575 restart the merge from scratch: ``hg resolve file...``
2570 2576 (or ``-a`` for all unresolved files)
2571 2577
2572 2578 Note that Mercurial will not let you commit files with unresolved merge
2573 2579 conflicts. You must use ``hg resolve -m ...`` before you can commit
2574 2580 after a conflicting merge.
2575 2581 """
2576 2582
2577 2583 all, mark, unmark, show, nostatus = \
2578 2584 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
2579 2585
2580 2586 if (show and (mark or unmark)) or (mark and unmark):
2581 2587 raise util.Abort(_("too many options specified"))
2582 2588 if pats and all:
2583 2589 raise util.Abort(_("can't specify --all and patterns"))
2584 2590 if not (all or pats or show or mark or unmark):
2585 2591 raise util.Abort(_('no files or directories specified; '
2586 2592 'use --all to remerge all files'))
2587 2593
2588 2594 ms = merge_.mergestate(repo)
2589 2595 m = cmdutil.match(repo, pats, opts)
2590 2596
2591 2597 for f in ms:
2592 2598 if m(f):
2593 2599 if show:
2594 2600 if nostatus:
2595 2601 ui.write("%s\n" % f)
2596 2602 else:
2597 2603 ui.write("%s %s\n" % (ms[f].upper(), f))
2598 2604 elif mark:
2599 2605 ms.mark(f, "r")
2600 2606 elif unmark:
2601 2607 ms.mark(f, "u")
2602 2608 else:
2603 2609 wctx = repo[None]
2604 2610 mctx = wctx.parents()[-1]
2605 2611
2606 2612 # backup pre-resolve (merge uses .orig for its own purposes)
2607 2613 a = repo.wjoin(f)
2608 2614 util.copyfile(a, a + ".resolve")
2609 2615
2610 2616 # resolve file
2611 2617 ms.resolve(f, wctx, mctx)
2612 2618
2613 2619 # replace filemerge's .orig file with our resolve file
2614 2620 util.rename(a + ".resolve", a + ".orig")
2615 2621
2616 2622 def revert(ui, repo, *pats, **opts):
2617 2623 """restore individual files or directories to an earlier state
2618 2624
2619 2625 (Use update -r to check out earlier revisions, revert does not
2620 2626 change the working directory parents.)
2621 2627
2622 2628 With no revision specified, revert the named files or directories
2623 2629 to the contents they had in the parent of the working directory.
2624 2630 This restores the contents of the affected files to an unmodified
2625 2631 state and unschedules adds, removes, copies, and renames. If the
2626 2632 working directory has two parents, you must explicitly specify a
2627 2633 revision.
2628 2634
2629 2635 Using the -r/--rev option, revert the given files or directories
2630 2636 to their contents as of a specific revision. This can be helpful
2631 2637 to "roll back" some or all of an earlier change. See 'hg help
2632 2638 dates' for a list of formats valid for -d/--date.
2633 2639
2634 2640 Revert modifies the working directory. It does not commit any
2635 2641 changes, or change the parent of the working directory. If you
2636 2642 revert to a revision other than the parent of the working
2637 2643 directory, the reverted files will thus appear modified
2638 2644 afterwards.
2639 2645
2640 2646 If a file has been deleted, it is restored. If the executable mode
2641 2647 of a file was changed, it is reset.
2642 2648
2643 2649 If names are given, all files matching the names are reverted.
2644 2650 If no arguments are given, no files are reverted.
2645 2651
2646 2652 Modified files are saved with a .orig suffix before reverting.
2647 2653 To disable these backups, use --no-backup.
2648 2654 """
2649 2655
2650 2656 if opts["date"]:
2651 2657 if opts["rev"]:
2652 2658 raise util.Abort(_("you can't specify a revision and a date"))
2653 2659 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2654 2660
2655 2661 if not pats and not opts.get('all'):
2656 2662 raise util.Abort(_('no files or directories specified; '
2657 2663 'use --all to revert the whole repo'))
2658 2664
2659 2665 parent, p2 = repo.dirstate.parents()
2660 2666 if not opts.get('rev') and p2 != nullid:
2661 2667 raise util.Abort(_('uncommitted merge - please provide a '
2662 2668 'specific revision'))
2663 2669 ctx = repo[opts.get('rev')]
2664 2670 node = ctx.node()
2665 2671 mf = ctx.manifest()
2666 2672 if node == parent:
2667 2673 pmf = mf
2668 2674 else:
2669 2675 pmf = None
2670 2676
2671 2677 # need all matching names in dirstate and manifest of target rev,
2672 2678 # so have to walk both. do not print errors if files exist in one
2673 2679 # but not other.
2674 2680
2675 2681 names = {}
2676 2682
2677 2683 wlock = repo.wlock()
2678 2684 try:
2679 2685 # walk dirstate.
2680 2686
2681 2687 m = cmdutil.match(repo, pats, opts)
2682 2688 m.bad = lambda x, y: False
2683 2689 for abs in repo.walk(m):
2684 2690 names[abs] = m.rel(abs), m.exact(abs)
2685 2691
2686 2692 # walk target manifest.
2687 2693
2688 2694 def badfn(path, msg):
2689 2695 if path in names:
2690 2696 return
2691 2697 path_ = path + '/'
2692 2698 for f in names:
2693 2699 if f.startswith(path_):
2694 2700 return
2695 2701 ui.warn("%s: %s\n" % (m.rel(path), msg))
2696 2702
2697 2703 m = cmdutil.match(repo, pats, opts)
2698 2704 m.bad = badfn
2699 2705 for abs in repo[node].walk(m):
2700 2706 if abs not in names:
2701 2707 names[abs] = m.rel(abs), m.exact(abs)
2702 2708
2703 2709 m = cmdutil.matchfiles(repo, names)
2704 2710 changes = repo.status(match=m)[:4]
2705 2711 modified, added, removed, deleted = map(set, changes)
2706 2712
2707 2713 # if f is a rename, also revert the source
2708 2714 cwd = repo.getcwd()
2709 2715 for f in added:
2710 2716 src = repo.dirstate.copied(f)
2711 2717 if src and src not in names and repo.dirstate[src] == 'r':
2712 2718 removed.add(src)
2713 2719 names[src] = (repo.pathto(src, cwd), True)
2714 2720
2715 2721 def removeforget(abs):
2716 2722 if repo.dirstate[abs] == 'a':
2717 2723 return _('forgetting %s\n')
2718 2724 return _('removing %s\n')
2719 2725
2720 2726 revert = ([], _('reverting %s\n'))
2721 2727 add = ([], _('adding %s\n'))
2722 2728 remove = ([], removeforget)
2723 2729 undelete = ([], _('undeleting %s\n'))
2724 2730
2725 2731 disptable = (
2726 2732 # dispatch table:
2727 2733 # file state
2728 2734 # action if in target manifest
2729 2735 # action if not in target manifest
2730 2736 # make backup if in target manifest
2731 2737 # make backup if not in target manifest
2732 2738 (modified, revert, remove, True, True),
2733 2739 (added, revert, remove, True, False),
2734 2740 (removed, undelete, None, False, False),
2735 2741 (deleted, revert, remove, False, False),
2736 2742 )
2737 2743
2738 2744 for abs, (rel, exact) in sorted(names.items()):
2739 2745 mfentry = mf.get(abs)
2740 2746 target = repo.wjoin(abs)
2741 2747 def handle(xlist, dobackup):
2742 2748 xlist[0].append(abs)
2743 2749 if dobackup and not opts.get('no_backup') and util.lexists(target):
2744 2750 bakname = "%s.orig" % rel
2745 2751 ui.note(_('saving current version of %s as %s\n') %
2746 2752 (rel, bakname))
2747 2753 if not opts.get('dry_run'):
2748 2754 util.copyfile(target, bakname)
2749 2755 if ui.verbose or not exact:
2750 2756 msg = xlist[1]
2751 2757 if not isinstance(msg, basestring):
2752 2758 msg = msg(abs)
2753 2759 ui.status(msg % rel)
2754 2760 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2755 2761 if abs not in table:
2756 2762 continue
2757 2763 # file has changed in dirstate
2758 2764 if mfentry:
2759 2765 handle(hitlist, backuphit)
2760 2766 elif misslist is not None:
2761 2767 handle(misslist, backupmiss)
2762 2768 break
2763 2769 else:
2764 2770 if abs not in repo.dirstate:
2765 2771 if mfentry:
2766 2772 handle(add, True)
2767 2773 elif exact:
2768 2774 ui.warn(_('file not managed: %s\n') % rel)
2769 2775 continue
2770 2776 # file has not changed in dirstate
2771 2777 if node == parent:
2772 2778 if exact:
2773 2779 ui.warn(_('no changes needed to %s\n') % rel)
2774 2780 continue
2775 2781 if pmf is None:
2776 2782 # only need parent manifest in this unlikely case,
2777 2783 # so do not read by default
2778 2784 pmf = repo[parent].manifest()
2779 2785 if abs in pmf:
2780 2786 if mfentry:
2781 2787 # if version of file is same in parent and target
2782 2788 # manifests, do nothing
2783 2789 if (pmf[abs] != mfentry or
2784 2790 pmf.flags(abs) != mf.flags(abs)):
2785 2791 handle(revert, False)
2786 2792 else:
2787 2793 handle(remove, False)
2788 2794
2789 2795 if not opts.get('dry_run'):
2790 2796 def checkout(f):
2791 2797 fc = ctx[f]
2792 2798 repo.wwrite(f, fc.data(), fc.flags())
2793 2799
2794 2800 audit_path = util.path_auditor(repo.root)
2795 2801 for f in remove[0]:
2796 2802 if repo.dirstate[f] == 'a':
2797 2803 repo.dirstate.forget(f)
2798 2804 continue
2799 2805 audit_path(f)
2800 2806 try:
2801 2807 util.unlink(repo.wjoin(f))
2802 2808 except OSError:
2803 2809 pass
2804 2810 repo.dirstate.remove(f)
2805 2811
2806 2812 normal = None
2807 2813 if node == parent:
2808 2814 # We're reverting to our parent. If possible, we'd like status
2809 2815 # to report the file as clean. We have to use normallookup for
2810 2816 # merges to avoid losing information about merged/dirty files.
2811 2817 if p2 != nullid:
2812 2818 normal = repo.dirstate.normallookup
2813 2819 else:
2814 2820 normal = repo.dirstate.normal
2815 2821 for f in revert[0]:
2816 2822 checkout(f)
2817 2823 if normal:
2818 2824 normal(f)
2819 2825
2820 2826 for f in add[0]:
2821 2827 checkout(f)
2822 2828 repo.dirstate.add(f)
2823 2829
2824 2830 normal = repo.dirstate.normallookup
2825 2831 if node == parent and p2 == nullid:
2826 2832 normal = repo.dirstate.normal
2827 2833 for f in undelete[0]:
2828 2834 checkout(f)
2829 2835 normal(f)
2830 2836
2831 2837 finally:
2832 2838 wlock.release()
2833 2839
2834 2840 def rollback(ui, repo):
2835 2841 """roll back the last transaction
2836 2842
2837 2843 This command should be used with care. There is only one level of
2838 2844 rollback, and there is no way to undo a rollback. It will also
2839 2845 restore the dirstate at the time of the last transaction, losing
2840 2846 any dirstate changes since that time. This command does not alter
2841 2847 the working directory.
2842 2848
2843 2849 Transactions are used to encapsulate the effects of all commands
2844 2850 that create new changesets or propagate existing changesets into a
2845 2851 repository. For example, the following commands are transactional,
2846 2852 and their effects can be rolled back:
2847 2853
2848 2854 - commit
2849 2855 - import
2850 2856 - pull
2851 2857 - push (with this repository as the destination)
2852 2858 - unbundle
2853 2859
2854 2860 This command is not intended for use on public repositories. Once
2855 2861 changes are visible for pull by other users, rolling a transaction
2856 2862 back locally is ineffective (someone else may already have pulled
2857 2863 the changes). Furthermore, a race is possible with readers of the
2858 2864 repository; for example an in-progress pull from the repository
2859 2865 may fail if a rollback is performed.
2860 2866 """
2861 2867 repo.rollback()
2862 2868
2863 2869 def root(ui, repo):
2864 2870 """print the root (top) of the current working directory
2865 2871
2866 2872 Print the root directory of the current repository.
2867 2873 """
2868 2874 ui.write(repo.root + "\n")
2869 2875
2870 2876 def serve(ui, repo, **opts):
2871 2877 """export the repository via HTTP
2872 2878
2873 2879 Start a local HTTP repository browser and pull server.
2874 2880
2875 2881 By default, the server logs accesses to stdout and errors to
2876 2882 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
2877 2883 files.
2878 2884 """
2879 2885
2880 2886 if opts["stdio"]:
2881 2887 if repo is None:
2882 2888 raise error.RepoError(_("There is no Mercurial repository here"
2883 2889 " (.hg not found)"))
2884 2890 s = sshserver.sshserver(ui, repo)
2885 2891 s.serve_forever()
2886 2892
2887 2893 baseui = repo and repo.baseui or ui
2888 2894 optlist = ("name templates style address port prefix ipv6"
2889 2895 " accesslog errorlog webdir_conf certificate encoding")
2890 2896 for o in optlist.split():
2891 2897 if opts.get(o, None):
2892 2898 baseui.setconfig("web", o, str(opts[o]))
2893 2899 if (repo is not None) and (repo.ui != baseui):
2894 2900 repo.ui.setconfig("web", o, str(opts[o]))
2895 2901
2896 2902 if repo is None and not ui.config("web", "webdir_conf"):
2897 2903 raise error.RepoError(_("There is no Mercurial repository here"
2898 2904 " (.hg not found)"))
2899 2905
2900 2906 class service(object):
2901 2907 def init(self):
2902 2908 util.set_signal_handler()
2903 2909 self.httpd = server.create_server(baseui, repo)
2904 2910
2905 2911 if not ui.verbose:
2906 2912 return
2907 2913
2908 2914 if self.httpd.prefix:
2909 2915 prefix = self.httpd.prefix.strip('/') + '/'
2910 2916 else:
2911 2917 prefix = ''
2912 2918
2913 2919 port = ':%d' % self.httpd.port
2914 2920 if port == ':80':
2915 2921 port = ''
2916 2922
2917 2923 bindaddr = self.httpd.addr
2918 2924 if bindaddr == '0.0.0.0':
2919 2925 bindaddr = '*'
2920 2926 elif ':' in bindaddr: # IPv6
2921 2927 bindaddr = '[%s]' % bindaddr
2922 2928
2923 2929 fqaddr = self.httpd.fqaddr
2924 2930 if ':' in fqaddr:
2925 2931 fqaddr = '[%s]' % fqaddr
2926 2932 ui.status(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
2927 2933 (fqaddr, port, prefix, bindaddr, self.httpd.port))
2928 2934
2929 2935 def run(self):
2930 2936 self.httpd.serve_forever()
2931 2937
2932 2938 service = service()
2933 2939
2934 2940 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2935 2941
2936 2942 def status(ui, repo, *pats, **opts):
2937 2943 """show changed files in the working directory
2938 2944
2939 2945 Show status of files in the repository. If names are given, only
2940 2946 files that match are shown. Files that are clean or ignored or
2941 2947 the source of a copy/move operation, are not listed unless
2942 2948 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
2943 2949 Unless options described with "show only ..." are given, the
2944 2950 options -mardu are used.
2945 2951
2946 2952 Option -q/--quiet hides untracked (unknown and ignored) files
2947 2953 unless explicitly requested with -u/--unknown or -i/--ignored.
2948 2954
2949 2955 NOTE: status may appear to disagree with diff if permissions have
2950 2956 changed or a merge has occurred. The standard diff format does not
2951 2957 report permission changes and diff only reports changes relative
2952 2958 to one merge parent.
2953 2959
2954 2960 If one revision is given, it is used as the base revision.
2955 2961 If two revisions are given, the differences between them are
2956 2962 shown. The --change option can also be used as a shortcut to list
2957 2963 the changed files of a revision from its first parent.
2958 2964
2959 2965 The codes used to show the status of files are::
2960 2966
2961 2967 M = modified
2962 2968 A = added
2963 2969 R = removed
2964 2970 C = clean
2965 2971 ! = missing (deleted by non-hg command, but still tracked)
2966 2972 ? = not tracked
2967 2973 I = ignored
2968 2974 = origin of the previous file listed as A (added)
2969 2975 """
2970 2976
2971 2977 revs = opts.get('rev')
2972 2978 change = opts.get('change')
2973 2979
2974 2980 if revs and change:
2975 2981 msg = _('cannot specify --rev and --change at the same time')
2976 2982 raise util.Abort(msg)
2977 2983 elif change:
2978 2984 node2 = repo.lookup(change)
2979 2985 node1 = repo[node2].parents()[0].node()
2980 2986 else:
2981 2987 node1, node2 = cmdutil.revpair(repo, revs)
2982 2988
2983 2989 cwd = (pats and repo.getcwd()) or ''
2984 2990 end = opts.get('print0') and '\0' or '\n'
2985 2991 copy = {}
2986 2992 states = 'modified added removed deleted unknown ignored clean'.split()
2987 2993 show = [k for k in states if opts.get(k)]
2988 2994 if opts.get('all'):
2989 2995 show += ui.quiet and (states[:4] + ['clean']) or states
2990 2996 if not show:
2991 2997 show = ui.quiet and states[:4] or states[:5]
2992 2998
2993 2999 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
2994 3000 'ignored' in show, 'clean' in show, 'unknown' in show)
2995 3001 changestates = zip(states, 'MAR!?IC', stat)
2996 3002
2997 3003 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
2998 3004 ctxn = repo[nullid]
2999 3005 ctx1 = repo[node1]
3000 3006 ctx2 = repo[node2]
3001 3007 added = stat[1]
3002 3008 if node2 is None:
3003 3009 added = stat[0] + stat[1] # merged?
3004 3010
3005 3011 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3006 3012 if k in added:
3007 3013 copy[k] = v
3008 3014 elif v in added:
3009 3015 copy[v] = k
3010 3016
3011 3017 for state, char, files in changestates:
3012 3018 if state in show:
3013 3019 format = "%s %%s%s" % (char, end)
3014 3020 if opts.get('no_status'):
3015 3021 format = "%%s%s" % end
3016 3022
3017 3023 for f in files:
3018 3024 ui.write(format % repo.pathto(f, cwd))
3019 3025 if f in copy:
3020 3026 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end))
3021 3027
3022 3028 def summary(ui, repo, **opts):
3023 3029 """summarize working directory state
3024 3030
3025 3031 This generates a brief summary of the working directory state,
3026 3032 including parents, branch, commit status, and available updates.
3027 3033
3028 3034 With the --remote option, this will check the default paths for
3029 3035 incoming and outgoing changes. This can be time-consuming.
3030 3036 """
3031 3037
3032 3038 ctx = repo[None]
3033 3039 parents = ctx.parents()
3034 3040 pnode = parents[0].node()
3035 3041 tags = repo.tags()
3036 3042
3037 3043 for p in parents:
3038 3044 t = ' '.join([t for t in tags if tags[t] == p.node()])
3039 3045 if p.rev() == -1:
3040 3046 if not len(repo):
3041 3047 t += _(' (empty repository)')
3042 3048 else:
3043 3049 t += _(' (no revision checked out)')
3044 3050 ui.write(_('parent: %d:%s %s\n') % (p.rev(), str(p), t))
3045 3051 if p.description():
3046 3052 ui.status(' ' + p.description().splitlines()[0].strip() + '\n')
3047 3053
3048 3054 branch = ctx.branch()
3049 3055 bheads = repo.branchheads(branch)
3050 3056 m = _('branch: %s\n') % branch
3051 3057 if branch != 'default':
3052 3058 ui.write(m)
3053 3059 else:
3054 3060 ui.status(m)
3055 3061
3056 3062 st = list(repo.status(unknown=True))[:6]
3057 3063 ms = merge_.mergestate(repo)
3058 3064 st.append([f for f in ms if ms[f] == 'u'])
3059 3065 labels = [_('%d modified'), _('%d added'), _('%d removed'),
3060 3066 _('%d deleted'), _('%d unknown'), _('%d ignored'),
3061 3067 _('%d unresolved')]
3062 3068 t = []
3063 3069 for s, l in zip(st, labels):
3064 3070 if s:
3065 3071 t.append(l % len(s))
3066 3072
3067 3073 t = ', '.join(t)
3068 3074 cleanworkdir = False
3069 3075
3070 3076 if len(parents) > 1:
3071 3077 t += _(' (merge)')
3072 3078 elif branch != parents[0].branch():
3073 3079 t += _(' (new branch)')
3074 3080 elif (not st[0] and not st[1] and not st[2]):
3075 3081 t += _(' (clean)')
3076 3082 cleanworkdir = True
3077 3083 elif pnode not in bheads:
3078 3084 t += _(' (new branch head)')
3079 3085
3080 3086 if cleanworkdir:
3081 3087 ui.status(_('commit: %s\n') % t.strip())
3082 3088 else:
3083 3089 ui.write(_('commit: %s\n') % t.strip())
3084 3090
3085 3091 # all ancestors of branch heads - all ancestors of parent = new csets
3086 3092 new = [0] * len(repo)
3087 3093 cl = repo.changelog
3088 3094 for a in [cl.rev(n) for n in bheads]:
3089 3095 new[a] = 1
3090 3096 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3091 3097 new[a] = 1
3092 3098 for a in [p.rev() for p in parents]:
3093 3099 if a >= 0:
3094 3100 new[a] = 0
3095 3101 for a in cl.ancestors(*[p.rev() for p in parents]):
3096 3102 new[a] = 0
3097 3103 new = sum(new)
3098 3104
3099 3105 if new == 0:
3100 3106 ui.status(_('update: (current)\n'))
3101 3107 elif pnode not in bheads:
3102 3108 ui.write(_('update: %d new changesets (update)\n') % new)
3103 3109 else:
3104 3110 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3105 3111 (new, len(bheads)))
3106 3112
3107 3113 if opts.get('remote'):
3108 3114 t = []
3109 3115 source, branches = hg.parseurl(ui.expandpath('default'))
3110 3116 other = hg.repository(cmdutil.remoteui(repo, {}), source)
3111 3117 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3112 3118 ui.debug('comparing with %s\n' % url.hidepassword(source))
3113 3119 repo.ui.pushbuffer()
3114 3120 common, incoming, rheads = repo.findcommonincoming(other)
3115 3121 repo.ui.popbuffer()
3116 3122 if incoming:
3117 3123 t.append(_('1 or more incoming'))
3118 3124
3119 3125 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3120 3126 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3121 3127 other = hg.repository(cmdutil.remoteui(repo, {}), dest)
3122 3128 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3123 3129 repo.ui.pushbuffer()
3124 3130 o = repo.findoutgoing(other)
3125 3131 repo.ui.popbuffer()
3126 3132 o = repo.changelog.nodesbetween(o, None)[0]
3127 3133 if o:
3128 3134 t.append(_('%d outgoing') % len(o))
3129 3135
3130 3136 if t:
3131 3137 ui.write(_('remote: %s\n') % (', '.join(t)))
3132 3138 else:
3133 3139 ui.status(_('remote: (synced)\n'))
3134 3140
3135 3141 def tag(ui, repo, name1, *names, **opts):
3136 3142 """add one or more tags for the current or given revision
3137 3143
3138 3144 Name a particular revision using <name>.
3139 3145
3140 3146 Tags are used to name particular revisions of the repository and are
3141 3147 very useful to compare different revisions, to go back to significant
3142 3148 earlier versions or to mark branch points as releases, etc.
3143 3149
3144 3150 If no revision is given, the parent of the working directory is
3145 3151 used, or tip if no revision is checked out.
3146 3152
3147 3153 To facilitate version control, distribution, and merging of tags,
3148 3154 they are stored as a file named ".hgtags" which is managed
3149 3155 similarly to other project files and can be hand-edited if
3150 3156 necessary. The file '.hg/localtags' is used for local tags (not
3151 3157 shared among repositories).
3152 3158
3153 3159 See 'hg help dates' for a list of formats valid for -d/--date.
3154 3160 """
3155 3161
3156 3162 rev_ = "."
3157 3163 names = (name1,) + names
3158 3164 if len(names) != len(set(names)):
3159 3165 raise util.Abort(_('tag names must be unique'))
3160 3166 for n in names:
3161 3167 if n in ['tip', '.', 'null']:
3162 3168 raise util.Abort(_('the name \'%s\' is reserved') % n)
3163 3169 if opts.get('rev') and opts.get('remove'):
3164 3170 raise util.Abort(_("--rev and --remove are incompatible"))
3165 3171 if opts.get('rev'):
3166 3172 rev_ = opts['rev']
3167 3173 message = opts.get('message')
3168 3174 if opts.get('remove'):
3169 3175 expectedtype = opts.get('local') and 'local' or 'global'
3170 3176 for n in names:
3171 3177 if not repo.tagtype(n):
3172 3178 raise util.Abort(_('tag \'%s\' does not exist') % n)
3173 3179 if repo.tagtype(n) != expectedtype:
3174 3180 if expectedtype == 'global':
3175 3181 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3176 3182 else:
3177 3183 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3178 3184 rev_ = nullid
3179 3185 if not message:
3180 3186 # we don't translate commit messages
3181 3187 message = 'Removed tag %s' % ', '.join(names)
3182 3188 elif not opts.get('force'):
3183 3189 for n in names:
3184 3190 if n in repo.tags():
3185 3191 raise util.Abort(_('tag \'%s\' already exists '
3186 3192 '(use -f to force)') % n)
3187 3193 if not rev_ and repo.dirstate.parents()[1] != nullid:
3188 3194 raise util.Abort(_('uncommitted merge - please provide a '
3189 3195 'specific revision'))
3190 3196 r = repo[rev_].node()
3191 3197
3192 3198 if not message:
3193 3199 # we don't translate commit messages
3194 3200 message = ('Added tag %s for changeset %s' %
3195 3201 (', '.join(names), short(r)))
3196 3202
3197 3203 date = opts.get('date')
3198 3204 if date:
3199 3205 date = util.parsedate(date)
3200 3206
3201 3207 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3202 3208
3203 3209 def tags(ui, repo):
3204 3210 """list repository tags
3205 3211
3206 3212 This lists both regular and local tags. When the -v/--verbose
3207 3213 switch is used, a third column "local" is printed for local tags.
3208 3214 """
3209 3215
3210 3216 hexfunc = ui.debugflag and hex or short
3211 3217 tagtype = ""
3212 3218
3213 3219 for t, n in reversed(repo.tagslist()):
3214 3220 if ui.quiet:
3215 3221 ui.write("%s\n" % t)
3216 3222 continue
3217 3223
3218 3224 try:
3219 3225 hn = hexfunc(n)
3220 3226 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3221 3227 except error.LookupError:
3222 3228 r = " ?:%s" % hn
3223 3229 else:
3224 3230 spaces = " " * (30 - encoding.colwidth(t))
3225 3231 if ui.verbose:
3226 3232 if repo.tagtype(t) == 'local':
3227 3233 tagtype = " local"
3228 3234 else:
3229 3235 tagtype = ""
3230 3236 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3231 3237
3232 3238 def tip(ui, repo, **opts):
3233 3239 """show the tip revision
3234 3240
3235 3241 The tip revision (usually just called the tip) is the changeset
3236 3242 most recently added to the repository (and therefore the most
3237 3243 recently changed head).
3238 3244
3239 3245 If you have just made a commit, that commit will be the tip. If
3240 3246 you have just pulled changes from another repository, the tip of
3241 3247 that repository becomes the current tip. The "tip" tag is special
3242 3248 and cannot be renamed or assigned to a different changeset.
3243 3249 """
3244 3250 displayer = cmdutil.show_changeset(ui, repo, opts)
3245 3251 displayer.show(repo[len(repo) - 1])
3246 3252 displayer.close()
3247 3253
3248 3254 def unbundle(ui, repo, fname1, *fnames, **opts):
3249 3255 """apply one or more changegroup files
3250 3256
3251 3257 Apply one or more compressed changegroup files generated by the
3252 3258 bundle command.
3253 3259 """
3254 3260 fnames = (fname1,) + fnames
3255 3261
3256 3262 lock = repo.lock()
3257 3263 try:
3258 3264 for fname in fnames:
3259 3265 f = url.open(ui, fname)
3260 3266 gen = changegroup.readbundle(f, fname)
3261 3267 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
3262 3268 finally:
3263 3269 lock.release()
3264 3270
3265 3271 return postincoming(ui, repo, modheads, opts.get('update'), None)
3266 3272
3267 3273 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3268 3274 """update working directory
3269 3275
3270 3276 Update the repository's working directory to the specified
3271 3277 changeset.
3272 3278
3273 3279 If no changeset is specified, attempt to update to the head of the
3274 3280 current branch. If this head is a descendant of the working
3275 3281 directory's parent, update to it, otherwise abort.
3276 3282
3277 3283 The following rules apply when the working directory contains
3278 3284 uncommitted changes:
3279 3285
3280 3286 1. If neither -c/--check nor -C/--clean is specified, and if
3281 3287 the requested changeset is an ancestor or descendant of
3282 3288 the working directory's parent, the uncommitted changes
3283 3289 are merged into the requested changeset and the merged
3284 3290 result is left uncommitted. If the requested changeset is
3285 3291 not an ancestor or descendant (that is, it is on another
3286 3292 branch), the update is aborted and the uncommitted changes
3287 3293 are preserved.
3288 3294
3289 3295 2. With the -c/--check option, the update is aborted and the
3290 3296 uncommitted changes are preserved.
3291 3297
3292 3298 3. With the -C/--clean option, uncommitted changes are discarded and
3293 3299 the working directory is updated to the requested changeset.
3294 3300
3295 3301 Use null as the changeset to remove the working directory (like 'hg
3296 3302 clone -U').
3297 3303
3298 3304 If you want to update just one file to an older changeset, use 'hg revert'.
3299 3305
3300 3306 See 'hg help dates' for a list of formats valid for -d/--date.
3301 3307 """
3302 3308 if rev and node:
3303 3309 raise util.Abort(_("please specify just one revision"))
3304 3310
3305 3311 if not rev:
3306 3312 rev = node
3307 3313
3308 3314 if check and clean:
3309 3315 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
3310 3316
3311 3317 if check:
3312 3318 # we could use dirty() but we can ignore merge and branch trivia
3313 3319 c = repo[None]
3314 3320 if c.modified() or c.added() or c.removed():
3315 3321 raise util.Abort(_("uncommitted local changes"))
3316 3322
3317 3323 if date:
3318 3324 if rev:
3319 3325 raise util.Abort(_("you can't specify a revision and a date"))
3320 3326 rev = cmdutil.finddate(ui, repo, date)
3321 3327
3322 3328 if clean or check:
3323 3329 return hg.clean(repo, rev)
3324 3330 else:
3325 3331 return hg.update(repo, rev)
3326 3332
3327 3333 def verify(ui, repo):
3328 3334 """verify the integrity of the repository
3329 3335
3330 3336 Verify the integrity of the current repository.
3331 3337
3332 3338 This will perform an extensive check of the repository's
3333 3339 integrity, validating the hashes and checksums of each entry in
3334 3340 the changelog, manifest, and tracked files, as well as the
3335 3341 integrity of their crosslinks and indices.
3336 3342 """
3337 3343 return hg.verify(repo)
3338 3344
3339 3345 def version_(ui):
3340 3346 """output version and copyright information"""
3341 3347 ui.write(_("Mercurial Distributed SCM (version %s)\n")
3342 3348 % util.version())
3343 3349 ui.status(_(
3344 3350 "\nCopyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
3345 3351 "This is free software; see the source for copying conditions. "
3346 3352 "There is NO\nwarranty; "
3347 3353 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
3348 3354 ))
3349 3355
3350 3356 # Command options and aliases are listed here, alphabetically
3351 3357
3352 3358 globalopts = [
3353 3359 ('R', 'repository', '',
3354 3360 _('repository root directory or name of overlay bundle file')),
3355 3361 ('', 'cwd', '', _('change working directory')),
3356 3362 ('y', 'noninteractive', None,
3357 3363 _('do not prompt, assume \'yes\' for any required answers')),
3358 3364 ('q', 'quiet', None, _('suppress output')),
3359 3365 ('v', 'verbose', None, _('enable additional output')),
3360 3366 ('', 'config', [],
3361 3367 _('set/override config option (use \'section.name=value\')')),
3362 3368 ('', 'debug', None, _('enable debugging output')),
3363 3369 ('', 'debugger', None, _('start debugger')),
3364 3370 ('', 'encoding', encoding.encoding, _('set the charset encoding')),
3365 3371 ('', 'encodingmode', encoding.encodingmode,
3366 3372 _('set the charset encoding mode')),
3367 3373 ('', 'traceback', None, _('always print a traceback on exception')),
3368 3374 ('', 'time', None, _('time how long the command takes')),
3369 3375 ('', 'profile', None, _('print command execution profile')),
3370 3376 ('', 'version', None, _('output version information and exit')),
3371 3377 ('h', 'help', None, _('display help and exit')),
3372 3378 ]
3373 3379
3374 3380 dryrunopts = [('n', 'dry-run', None,
3375 3381 _('do not perform actions, just print output'))]
3376 3382
3377 3383 remoteopts = [
3378 3384 ('e', 'ssh', '', _('specify ssh command to use')),
3379 3385 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
3380 3386 ]
3381 3387
3382 3388 walkopts = [
3383 3389 ('I', 'include', [], _('include names matching the given patterns')),
3384 3390 ('X', 'exclude', [], _('exclude names matching the given patterns')),
3385 3391 ]
3386 3392
3387 3393 commitopts = [
3388 3394 ('m', 'message', '', _('use <text> as commit message')),
3389 3395 ('l', 'logfile', '', _('read commit message from <file>')),
3390 3396 ]
3391 3397
3392 3398 commitopts2 = [
3393 3399 ('d', 'date', '', _('record datecode as commit date')),
3394 3400 ('u', 'user', '', _('record the specified user as committer')),
3395 3401 ]
3396 3402
3397 3403 templateopts = [
3398 3404 ('', 'style', '', _('display using template map file')),
3399 3405 ('', 'template', '', _('display with template')),
3400 3406 ]
3401 3407
3402 3408 logopts = [
3403 3409 ('p', 'patch', None, _('show patch')),
3404 3410 ('g', 'git', None, _('use git extended diff format')),
3405 3411 ('l', 'limit', '', _('limit number of changes displayed')),
3406 3412 ('M', 'no-merges', None, _('do not show merges')),
3407 3413 ] + templateopts
3408 3414
3409 3415 diffopts = [
3410 3416 ('a', 'text', None, _('treat all files as text')),
3411 3417 ('g', 'git', None, _('use git extended diff format')),
3412 3418 ('', 'nodates', None, _('omit dates from diff headers'))
3413 3419 ]
3414 3420
3415 3421 diffopts2 = [
3416 3422 ('p', 'show-function', None, _('show which function each change is in')),
3417 3423 ('', 'reverse', None, _('produce a diff that undoes the changes')),
3418 3424 ('w', 'ignore-all-space', None,
3419 3425 _('ignore white space when comparing lines')),
3420 3426 ('b', 'ignore-space-change', None,
3421 3427 _('ignore changes in the amount of white space')),
3422 3428 ('B', 'ignore-blank-lines', None,
3423 3429 _('ignore changes whose lines are all blank')),
3424 3430 ('U', 'unified', '', _('number of lines of context to show')),
3425 3431 ('', 'stat', None, _('output diffstat-style summary of changes')),
3426 3432 ]
3427 3433
3428 3434 similarityopts = [
3429 3435 ('s', 'similarity', '',
3430 3436 _('guess renamed files by similarity (0<=s<=100)'))
3431 3437 ]
3432 3438
3433 3439 table = {
3434 3440 "^add": (add, walkopts + dryrunopts, _('[OPTION]... [FILE]...')),
3435 3441 "addremove":
3436 3442 (addremove, similarityopts + walkopts + dryrunopts,
3437 3443 _('[OPTION]... [FILE]...')),
3438 3444 "^annotate|blame":
3439 3445 (annotate,
3440 3446 [('r', 'rev', '', _('annotate the specified revision')),
3441 3447 ('', 'follow', None,
3442 3448 _('follow copies/renames and list the filename (DEPRECATED)')),
3443 3449 ('', 'no-follow', None, _("don't follow copies and renames")),
3444 3450 ('a', 'text', None, _('treat all files as text')),
3445 3451 ('u', 'user', None, _('list the author (long with -v)')),
3446 3452 ('f', 'file', None, _('list the filename')),
3447 3453 ('d', 'date', None, _('list the date (short with -q)')),
3448 3454 ('n', 'number', None, _('list the revision number (default)')),
3449 3455 ('c', 'changeset', None, _('list the changeset')),
3450 3456 ('l', 'line-number', None,
3451 3457 _('show line number at the first appearance'))
3452 3458 ] + walkopts,
3453 3459 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
3454 3460 "archive":
3455 3461 (archive,
3456 3462 [('', 'no-decode', None, _('do not pass files through decoders')),
3457 3463 ('p', 'prefix', '', _('directory prefix for files in archive')),
3458 3464 ('r', 'rev', '', _('revision to distribute')),
3459 3465 ('t', 'type', '', _('type of distribution to create')),
3460 3466 ] + walkopts,
3461 3467 _('[OPTION]... DEST')),
3462 3468 "backout":
3463 3469 (backout,
3464 3470 [('', 'merge', None,
3465 3471 _('merge with old dirstate parent after backout')),
3466 3472 ('', 'parent', '', _('parent to choose when backing out merge')),
3467 3473 ('r', 'rev', '', _('revision to backout')),
3468 3474 ] + walkopts + commitopts + commitopts2,
3469 3475 _('[OPTION]... [-r] REV')),
3470 3476 "bisect":
3471 3477 (bisect,
3472 3478 [('r', 'reset', False, _('reset bisect state')),
3473 3479 ('g', 'good', False, _('mark changeset good')),
3474 3480 ('b', 'bad', False, _('mark changeset bad')),
3475 3481 ('s', 'skip', False, _('skip testing changeset')),
3476 3482 ('c', 'command', '', _('use command to check changeset state')),
3477 3483 ('U', 'noupdate', False, _('do not update to target'))],
3478 3484 _("[-gbsr] [-U] [-c CMD] [REV]")),
3479 3485 "branch":
3480 3486 (branch,
3481 3487 [('f', 'force', None,
3482 3488 _('set branch name even if it shadows an existing branch')),
3483 3489 ('C', 'clean', None, _('reset branch name to parent branch name'))],
3484 3490 _('[-fC] [NAME]')),
3485 3491 "branches":
3486 3492 (branches,
3487 3493 [('a', 'active', False,
3488 3494 _('show only branches that have unmerged heads')),
3489 3495 ('c', 'closed', False,
3490 3496 _('show normal and closed branches'))],
3491 3497 _('[-ac]')),
3492 3498 "bundle":
3493 3499 (bundle,
3494 3500 [('f', 'force', None,
3495 3501 _('run even when the destination is unrelated')),
3496 3502 ('r', 'rev', [],
3497 3503 _('a changeset intended to be added to the destination')),
3498 3504 ('b', 'branch', [],
3499 3505 _('a specific branch you would like to bundle')),
3500 3506 ('', 'base', [],
3501 3507 _('a base changeset assumed to be available at the destination')),
3502 3508 ('a', 'all', None, _('bundle all changesets in the repository')),
3503 3509 ('t', 'type', 'bzip2', _('bundle compression type to use')),
3504 3510 ] + remoteopts,
3505 3511 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
3506 3512 "cat":
3507 3513 (cat,
3508 3514 [('o', 'output', '', _('print output to file with formatted name')),
3509 3515 ('r', 'rev', '', _('print the given revision')),
3510 3516 ('', 'decode', None, _('apply any matching decode filter')),
3511 3517 ] + walkopts,
3512 3518 _('[OPTION]... FILE...')),
3513 3519 "^clone":
3514 3520 (clone,
3515 3521 [('U', 'noupdate', None,
3516 3522 _('the clone will include an empty working copy (only a repository)')),
3517 3523 ('u', 'updaterev', '',
3518 3524 _('revision, tag or branch to check out')),
3519 3525 ('r', 'rev', [],
3520 3526 _('include the specified changeset')),
3521 3527 ('b', 'branch', [],
3522 3528 _('clone only the specified branch')),
3523 3529 ('', 'pull', None, _('use pull protocol to copy metadata')),
3524 3530 ('', 'uncompressed', None,
3525 3531 _('use uncompressed transfer (fast over LAN)')),
3526 3532 ] + remoteopts,
3527 3533 _('[OPTION]... SOURCE [DEST]')),
3528 3534 "^commit|ci":
3529 3535 (commit,
3530 3536 [('A', 'addremove', None,
3531 3537 _('mark new/missing files as added/removed before committing')),
3532 3538 ('', 'close-branch', None,
3533 3539 _('mark a branch as closed, hiding it from the branch list')),
3534 3540 ] + walkopts + commitopts + commitopts2,
3535 3541 _('[OPTION]... [FILE]...')),
3536 3542 "copy|cp":
3537 3543 (copy,
3538 3544 [('A', 'after', None, _('record a copy that has already occurred')),
3539 3545 ('f', 'force', None,
3540 3546 _('forcibly copy over an existing managed file')),
3541 3547 ] + walkopts + dryrunopts,
3542 3548 _('[OPTION]... [SOURCE]... DEST')),
3543 3549 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
3544 3550 "debugcheckstate": (debugcheckstate, [], ''),
3545 3551 "debugcommands": (debugcommands, [], _('[COMMAND]')),
3546 3552 "debugcomplete":
3547 3553 (debugcomplete,
3548 3554 [('o', 'options', None, _('show the command options'))],
3549 3555 _('[-o] CMD')),
3550 3556 "debugdate":
3551 3557 (debugdate,
3552 3558 [('e', 'extended', None, _('try extended date formats'))],
3553 3559 _('[-e] DATE [RANGE]')),
3554 3560 "debugdata": (debugdata, [], _('FILE REV')),
3555 3561 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
3556 3562 "debugindex": (debugindex, [], _('FILE')),
3557 3563 "debugindexdot": (debugindexdot, [], _('FILE')),
3558 3564 "debuginstall": (debuginstall, [], ''),
3559 3565 "debugrebuildstate":
3560 3566 (debugrebuildstate,
3561 3567 [('r', 'rev', '', _('revision to rebuild to'))],
3562 3568 _('[-r REV] [REV]')),
3563 3569 "debugrename":
3564 3570 (debugrename,
3565 3571 [('r', 'rev', '', _('revision to debug'))],
3566 3572 _('[-r REV] FILE')),
3567 3573 "debugsetparents":
3568 3574 (debugsetparents, [], _('REV1 [REV2]')),
3569 3575 "debugstate":
3570 3576 (debugstate,
3571 3577 [('', 'nodates', None, _('do not display the saved mtime'))],
3572 3578 _('[OPTION]...')),
3573 3579 "debugsub":
3574 3580 (debugsub,
3575 3581 [('r', 'rev', '', _('revision to check'))],
3576 3582 _('[-r REV] [REV]')),
3577 3583 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
3578 3584 "^diff":
3579 3585 (diff,
3580 3586 [('r', 'rev', [], _('revision')),
3581 3587 ('c', 'change', '', _('change made by revision'))
3582 3588 ] + diffopts + diffopts2 + walkopts,
3583 3589 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
3584 3590 "^export":
3585 3591 (export,
3586 3592 [('o', 'output', '', _('print output to file with formatted name')),
3587 3593 ('', 'switch-parent', None, _('diff against the second parent')),
3588 3594 ('r', 'rev', [], _('revisions to export')),
3589 3595 ] + diffopts,
3590 3596 _('[OPTION]... [-o OUTFILESPEC] REV...')),
3591 3597 "^forget":
3592 3598 (forget,
3593 3599 [] + walkopts,
3594 3600 _('[OPTION]... FILE...')),
3595 3601 "grep":
3596 3602 (grep,
3597 3603 [('0', 'print0', None, _('end fields with NUL')),
3598 3604 ('', 'all', None, _('print all revisions that match')),
3599 3605 ('f', 'follow', None,
3600 3606 _('follow changeset history,'
3601 3607 ' or file history across copies and renames')),
3602 3608 ('i', 'ignore-case', None, _('ignore case when matching')),
3603 3609 ('l', 'files-with-matches', None,
3604 3610 _('print only filenames and revisions that match')),
3605 3611 ('n', 'line-number', None, _('print matching line numbers')),
3606 3612 ('r', 'rev', [], _('search in given revision range')),
3607 3613 ('u', 'user', None, _('list the author (long with -v)')),
3608 3614 ('d', 'date', None, _('list the date (short with -q)')),
3609 3615 ] + walkopts,
3610 3616 _('[OPTION]... PATTERN [FILE]...')),
3611 3617 "heads":
3612 3618 (heads,
3613 3619 [('r', 'rev', '', _('show only heads which are descendants of REV')),
3614 3620 ('t', 'topo', False, _('show topological heads only')),
3615 3621 ('a', 'active', False,
3616 3622 _('show active branchheads only [DEPRECATED]')),
3617 3623 ('c', 'closed', False,
3618 3624 _('show normal and closed branch heads')),
3619 3625 ] + templateopts,
3620 3626 _('[-ac] [-r STARTREV] [REV]...')),
3621 3627 "help": (help_, [], _('[TOPIC]')),
3622 3628 "identify|id":
3623 3629 (identify,
3624 3630 [('r', 'rev', '', _('identify the specified revision')),
3625 3631 ('n', 'num', None, _('show local revision number')),
3626 3632 ('i', 'id', None, _('show global revision id')),
3627 3633 ('b', 'branch', None, _('show branch')),
3628 3634 ('t', 'tags', None, _('show tags'))],
3629 3635 _('[-nibt] [-r REV] [SOURCE]')),
3630 3636 "import|patch":
3631 3637 (import_,
3632 3638 [('p', 'strip', 1,
3633 3639 _('directory strip option for patch. This has the same '
3634 3640 'meaning as the corresponding patch option')),
3635 3641 ('b', 'base', '', _('base path')),
3636 3642 ('f', 'force', None,
3637 3643 _('skip check for outstanding uncommitted changes')),
3638 3644 ('', 'no-commit', None,
3639 3645 _("don't commit, just update the working directory")),
3640 3646 ('', 'exact', None,
3641 3647 _('apply patch to the nodes from which it was generated')),
3642 3648 ('', 'import-branch', None,
3643 3649 _('use any branch information in patch (implied by --exact)'))] +
3644 3650 commitopts + commitopts2 + similarityopts,
3645 3651 _('[OPTION]... PATCH...')),
3646 3652 "incoming|in":
3647 3653 (incoming,
3648 3654 [('f', 'force', None,
3649 3655 _('run even if remote repository is unrelated')),
3650 3656 ('n', 'newest-first', None, _('show newest record first')),
3651 3657 ('', 'bundle', '', _('file to store the bundles into')),
3652 3658 ('r', 'rev', [],
3653 3659 _('a remote changeset intended to be added')),
3654 3660 ('b', 'branch', [],
3655 3661 _('a specific branch you would like to pull')),
3656 3662 ] + logopts + remoteopts,
3657 3663 _('[-p] [-n] [-M] [-f] [-r REV]...'
3658 3664 ' [--bundle FILENAME] [SOURCE]')),
3659 3665 "^init":
3660 3666 (init,
3661 3667 remoteopts,
3662 3668 _('[-e CMD] [--remotecmd CMD] [DEST]')),
3663 3669 "locate":
3664 3670 (locate,
3665 3671 [('r', 'rev', '', _('search the repository as it is in REV')),
3666 3672 ('0', 'print0', None,
3667 3673 _('end filenames with NUL, for use with xargs')),
3668 3674 ('f', 'fullpath', None,
3669 3675 _('print complete paths from the filesystem root')),
3670 3676 ] + walkopts,
3671 3677 _('[OPTION]... [PATTERN]...')),
3672 3678 "^log|history":
3673 3679 (log,
3674 3680 [('f', 'follow', None,
3675 3681 _('follow changeset history,'
3676 3682 ' or file history across copies and renames')),
3677 3683 ('', 'follow-first', None,
3678 3684 _('only follow the first parent of merge changesets')),
3679 3685 ('d', 'date', '', _('show revisions matching date spec')),
3680 3686 ('C', 'copies', None, _('show copied files')),
3681 3687 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
3682 3688 ('r', 'rev', [], _('show the specified revision or range')),
3683 3689 ('', 'removed', None, _('include revisions where files were removed')),
3684 3690 ('m', 'only-merges', None, _('show only merges')),
3685 3691 ('u', 'user', [], _('revisions committed by user')),
3686 3692 ('b', 'only-branch', [],
3687 3693 _('show only changesets within the given named branch')),
3688 3694 ('P', 'prune', [],
3689 3695 _('do not display revision or any of its ancestors')),
3690 3696 ] + logopts + walkopts,
3691 3697 _('[OPTION]... [FILE]')),
3692 3698 "manifest":
3693 3699 (manifest,
3694 3700 [('r', 'rev', '', _('revision to display'))],
3695 3701 _('[-r REV]')),
3696 3702 "^merge":
3697 3703 (merge,
3698 3704 [('f', 'force', None, _('force a merge with outstanding changes')),
3699 3705 ('r', 'rev', '', _('revision to merge')),
3700 3706 ('P', 'preview', None,
3701 3707 _('review revisions to merge (no merge is performed)'))],
3702 3708 _('[-P] [-f] [[-r] REV]')),
3703 3709 "outgoing|out":
3704 3710 (outgoing,
3705 3711 [('f', 'force', None,
3706 3712 _('run even when the destination is unrelated')),
3707 3713 ('r', 'rev', [],
3708 3714 _('a changeset intended to be included in the destination')),
3709 3715 ('n', 'newest-first', None, _('show newest record first')),
3710 3716 ('b', 'branch', [],
3711 3717 _('a specific branch you would like to push')),
3712 3718 ] + logopts + remoteopts,
3713 3719 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
3714 3720 "parents":
3715 3721 (parents,
3716 3722 [('r', 'rev', '', _('show parents of the specified revision')),
3717 3723 ] + templateopts,
3718 3724 _('[-r REV] [FILE]')),
3719 3725 "paths": (paths, [], _('[NAME]')),
3720 3726 "^pull":
3721 3727 (pull,
3722 3728 [('u', 'update', None,
3723 3729 _('update to new branch head if changesets were pulled')),
3724 3730 ('f', 'force', None,
3725 3731 _('run even when remote repository is unrelated')),
3726 3732 ('r', 'rev', [],
3727 3733 _('a remote changeset intended to be added')),
3728 3734 ('b', 'branch', [],
3729 3735 _('a specific branch you would like to pull')),
3730 3736 ] + remoteopts,
3731 3737 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
3732 3738 "^push":
3733 3739 (push,
3734 3740 [('f', 'force', None, _('force push')),
3735 3741 ('r', 'rev', [],
3736 3742 _('a changeset intended to be included in the destination')),
3737 3743 ('b', 'branch', [],
3738 3744 _('a specific branch you would like to push')),
3739 3745 ] + remoteopts,
3740 3746 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
3741 3747 "recover": (recover, []),
3742 3748 "^remove|rm":
3743 3749 (remove,
3744 3750 [('A', 'after', None, _('record delete for missing files')),
3745 3751 ('f', 'force', None,
3746 3752 _('remove (and delete) file even if added or modified')),
3747 3753 ] + walkopts,
3748 3754 _('[OPTION]... FILE...')),
3749 3755 "rename|mv":
3750 3756 (rename,
3751 3757 [('A', 'after', None, _('record a rename that has already occurred')),
3752 3758 ('f', 'force', None,
3753 3759 _('forcibly copy over an existing managed file')),
3754 3760 ] + walkopts + dryrunopts,
3755 3761 _('[OPTION]... SOURCE... DEST')),
3756 3762 "resolve":
3757 3763 (resolve,
3758 3764 [('a', 'all', None, _('select all unresolved files')),
3759 3765 ('l', 'list', None, _('list state of files needing merge')),
3760 3766 ('m', 'mark', None, _('mark files as resolved')),
3761 3767 ('u', 'unmark', None, _('unmark files as resolved')),
3762 3768 ('n', 'no-status', None, _('hide status prefix'))]
3763 3769 + walkopts,
3764 3770 _('[OPTION]... [FILE]...')),
3765 3771 "revert":
3766 3772 (revert,
3767 3773 [('a', 'all', None, _('revert all changes when no arguments given')),
3768 3774 ('d', 'date', '', _('tipmost revision matching date')),
3769 3775 ('r', 'rev', '', _('revert to the specified revision')),
3770 3776 ('', 'no-backup', None, _('do not save backup copies of files')),
3771 3777 ] + walkopts + dryrunopts,
3772 3778 _('[OPTION]... [-r REV] [NAME]...')),
3773 3779 "rollback": (rollback, []),
3774 3780 "root": (root, []),
3775 3781 "^serve":
3776 3782 (serve,
3777 3783 [('A', 'accesslog', '', _('name of access log file to write to')),
3778 3784 ('d', 'daemon', None, _('run server in background')),
3779 3785 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3780 3786 ('E', 'errorlog', '', _('name of error log file to write to')),
3781 3787 ('p', 'port', 0, _('port to listen on (default: 8000)')),
3782 3788 ('a', 'address', '',
3783 3789 _('address to listen on (default: all interfaces)')),
3784 3790 ('', 'prefix', '',
3785 3791 _('prefix path to serve from (default: server root)')),
3786 3792 ('n', 'name', '',
3787 3793 _('name to show in web pages (default: working directory)')),
3788 3794 ('', 'webdir-conf', '', _('name of the webdir config file'
3789 3795 ' (serve more than one repository)')),
3790 3796 ('', 'pid-file', '', _('name of file to write process ID to')),
3791 3797 ('', 'stdio', None, _('for remote clients')),
3792 3798 ('t', 'templates', '', _('web templates to use')),
3793 3799 ('', 'style', '', _('template style to use')),
3794 3800 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3795 3801 ('', 'certificate', '', _('SSL certificate file'))],
3796 3802 _('[OPTION]...')),
3797 3803 "showconfig|debugconfig":
3798 3804 (showconfig,
3799 3805 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3800 3806 _('[-u] [NAME]...')),
3801 3807 "^summary|sum":
3802 3808 (summary,
3803 3809 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
3804 3810 "^status|st":
3805 3811 (status,
3806 3812 [('A', 'all', None, _('show status of all files')),
3807 3813 ('m', 'modified', None, _('show only modified files')),
3808 3814 ('a', 'added', None, _('show only added files')),
3809 3815 ('r', 'removed', None, _('show only removed files')),
3810 3816 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3811 3817 ('c', 'clean', None, _('show only files without changes')),
3812 3818 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3813 3819 ('i', 'ignored', None, _('show only ignored files')),
3814 3820 ('n', 'no-status', None, _('hide status prefix')),
3815 3821 ('C', 'copies', None, _('show source of copied files')),
3816 3822 ('0', 'print0', None,
3817 3823 _('end filenames with NUL, for use with xargs')),
3818 3824 ('', 'rev', [], _('show difference from revision')),
3819 3825 ('', 'change', '', _('list the changed files of a revision')),
3820 3826 ] + walkopts,
3821 3827 _('[OPTION]... [FILE]...')),
3822 3828 "tag":
3823 3829 (tag,
3824 3830 [('f', 'force', None, _('replace existing tag')),
3825 3831 ('l', 'local', None, _('make the tag local')),
3826 3832 ('r', 'rev', '', _('revision to tag')),
3827 3833 ('', 'remove', None, _('remove a tag')),
3828 3834 # -l/--local is already there, commitopts cannot be used
3829 3835 ('m', 'message', '', _('use <text> as commit message')),
3830 3836 ] + commitopts2,
3831 3837 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
3832 3838 "tags": (tags, [], ''),
3833 3839 "tip":
3834 3840 (tip,
3835 3841 [('p', 'patch', None, _('show patch')),
3836 3842 ('g', 'git', None, _('use git extended diff format')),
3837 3843 ] + templateopts,
3838 3844 _('[-p] [-g]')),
3839 3845 "unbundle":
3840 3846 (unbundle,
3841 3847 [('u', 'update', None,
3842 3848 _('update to new branch head if changesets were unbundled'))],
3843 3849 _('[-u] FILE...')),
3844 3850 "^update|up|checkout|co":
3845 3851 (update,
3846 3852 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
3847 3853 ('c', 'check', None, _('check for uncommitted changes')),
3848 3854 ('d', 'date', '', _('tipmost revision matching date')),
3849 3855 ('r', 'rev', '', _('revision'))],
3850 3856 _('[-c] [-C] [-d DATE] [[-r] REV]')),
3851 3857 "verify": (verify, []),
3852 3858 "version": (version_, []),
3853 3859 }
3854 3860
3855 3861 norepo = ("clone init version help debugcommands debugcomplete debugdata"
3856 3862 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3857 3863 optionalrepo = ("identify paths serve showconfig debugancestor")
General Comments 0
You need to be logged in to leave comments. Login now