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