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