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