##// END OF EJS Templates
"C" status code considered harmful, so changed to "=" (issue899)...
Thomas Arendsen Hein -
r5762:c2a21fe6 default
parent child Browse files
Show More
@@ -1,2994 +1,2994 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
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 from node import *
9 9 from i18n import _
10 10 import os, re, sys, urllib
11 11 import hg, util, revlog, bundlerepo, extensions
12 12 import difflib, patch, time, help, mdiff, tempfile
13 13 import errno, version, socket
14 14 import archival, changegroup, cmdutil, hgweb.server, sshserver
15 15
16 16 # Commands start here, listed alphabetically
17 17
18 18 def add(ui, repo, *pats, **opts):
19 19 """add the specified files on the next commit
20 20
21 21 Schedule files to be version controlled and added to the repository.
22 22
23 23 The files will be added to the repository at the next commit. To
24 24 undo an add before that, see hg revert.
25 25
26 26 If no names are given, add all files in the repository.
27 27 """
28 28
29 29 rejected = None
30 30 exacts = {}
31 31 names = []
32 32 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
33 33 badmatch=util.always):
34 34 if exact:
35 35 if ui.verbose:
36 36 ui.status(_('adding %s\n') % rel)
37 37 names.append(abs)
38 38 exacts[abs] = 1
39 39 elif abs not in repo.dirstate:
40 40 ui.status(_('adding %s\n') % rel)
41 41 names.append(abs)
42 42 if not opts.get('dry_run'):
43 43 rejected = repo.add(names)
44 44 rejected = [p for p in rejected if p in exacts]
45 45 return rejected and 1 or 0
46 46
47 47 def addremove(ui, repo, *pats, **opts):
48 48 """add all new files, delete all missing files
49 49
50 50 Add all new files and remove all missing files from the repository.
51 51
52 52 New files are ignored if they match any of the patterns in .hgignore. As
53 53 with add, these changes take effect at the next commit.
54 54
55 55 Use the -s option to detect renamed files. With a parameter > 0,
56 56 this compares every removed file with every added file and records
57 57 those similar enough as renames. This option takes a percentage
58 58 between 0 (disabled) and 100 (files must be identical) as its
59 59 parameter. Detecting renamed files this way can be expensive.
60 60 """
61 61 try:
62 62 sim = float(opts.get('similarity') or 0)
63 63 except ValueError:
64 64 raise util.Abort(_('similarity must be a number'))
65 65 if sim < 0 or sim > 100:
66 66 raise util.Abort(_('similarity must be between 0 and 100'))
67 67 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
68 68
69 69 def annotate(ui, repo, *pats, **opts):
70 70 """show changeset information per file line
71 71
72 72 List changes in files, showing the revision id responsible for each line
73 73
74 74 This command is useful to discover who did a change or when a change took
75 75 place.
76 76
77 77 Without the -a option, annotate will avoid processing files it
78 78 detects as binary. With -a, annotate will generate an annotation
79 79 anyway, probably with undesirable results.
80 80 """
81 81 getdate = util.cachefunc(lambda x: util.datestr(x[0].date()))
82 82
83 83 if not pats:
84 84 raise util.Abort(_('at least one file name or pattern required'))
85 85
86 86 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
87 87 ('number', lambda x: str(x[0].rev())),
88 88 ('changeset', lambda x: short(x[0].node())),
89 89 ('date', getdate),
90 90 ('follow', lambda x: x[0].path()),
91 91 ]
92 92
93 93 if (not opts['user'] and not opts['changeset'] and not opts['date']
94 94 and not opts['follow']):
95 95 opts['number'] = 1
96 96
97 97 linenumber = opts.get('line_number') is not None
98 98 if (linenumber and (not opts['changeset']) and (not opts['number'])):
99 99 raise util.Abort(_('at least one of -n/-c is required for -l'))
100 100
101 101 funcmap = [func for op, func in opmap if opts.get(op)]
102 102 if linenumber:
103 103 lastfunc = funcmap[-1]
104 104 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
105 105
106 106 ctx = repo.changectx(opts['rev'])
107 107
108 108 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
109 109 node=ctx.node()):
110 110 fctx = ctx.filectx(abs)
111 111 if not opts['text'] and util.binary(fctx.data()):
112 112 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
113 113 continue
114 114
115 115 lines = fctx.annotate(follow=opts.get('follow'),
116 116 linenumber=linenumber)
117 117 pieces = []
118 118
119 119 for f in funcmap:
120 120 l = [f(n) for n, dummy in lines]
121 121 if l:
122 122 m = max(map(len, l))
123 123 pieces.append(["%*s" % (m, x) for x in l])
124 124
125 125 if pieces:
126 126 for p, l in zip(zip(*pieces), lines):
127 127 ui.write("%s: %s" % (" ".join(p), l[1]))
128 128
129 129 def archive(ui, repo, dest, **opts):
130 130 '''create unversioned archive of a repository revision
131 131
132 132 By default, the revision used is the parent of the working
133 133 directory; use "-r" to specify a different revision.
134 134
135 135 To specify the type of archive to create, use "-t". Valid
136 136 types are:
137 137
138 138 "files" (default): a directory full of files
139 139 "tar": tar archive, uncompressed
140 140 "tbz2": tar archive, compressed using bzip2
141 141 "tgz": tar archive, compressed using gzip
142 142 "uzip": zip archive, uncompressed
143 143 "zip": zip archive, compressed using deflate
144 144
145 145 The exact name of the destination archive or directory is given
146 146 using a format string; see "hg help export" for details.
147 147
148 148 Each member added to an archive file has a directory prefix
149 149 prepended. Use "-p" to specify a format string for the prefix.
150 150 The default is the basename of the archive, with suffixes removed.
151 151 '''
152 152
153 153 ctx = repo.changectx(opts['rev'])
154 154 if not ctx:
155 155 raise util.Abort(_('repository has no revisions'))
156 156 node = ctx.node()
157 157 dest = cmdutil.make_filename(repo, dest, node)
158 158 if os.path.realpath(dest) == repo.root:
159 159 raise util.Abort(_('repository root cannot be destination'))
160 160 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
161 161 kind = opts.get('type') or 'files'
162 162 prefix = opts['prefix']
163 163 if dest == '-':
164 164 if kind == 'files':
165 165 raise util.Abort(_('cannot archive plain files to stdout'))
166 166 dest = sys.stdout
167 167 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
168 168 prefix = cmdutil.make_filename(repo, prefix, node)
169 169 archival.archive(repo, dest, node, kind, not opts['no_decode'],
170 170 matchfn, prefix)
171 171
172 172 def backout(ui, repo, node=None, rev=None, **opts):
173 173 '''reverse effect of earlier changeset
174 174
175 175 Commit the backed out changes as a new changeset. The new
176 176 changeset is a child of the backed out changeset.
177 177
178 178 If you back out a changeset other than the tip, a new head is
179 179 created. This head is the parent of the working directory. If
180 180 you back out an old changeset, your working directory will appear
181 181 old after the backout. You should merge the backout changeset
182 182 with another head.
183 183
184 184 The --merge option remembers the parent of the working directory
185 185 before starting the backout, then merges the new head with that
186 186 changeset afterwards. This saves you from doing the merge by
187 187 hand. The result of this merge is not committed, as for a normal
188 188 merge.'''
189 189 if rev and node:
190 190 raise util.Abort(_("please specify just one revision"))
191 191
192 192 if not rev:
193 193 rev = node
194 194
195 195 if not rev:
196 196 raise util.Abort(_("please specify a revision to backout"))
197 197
198 198 cmdutil.bail_if_changed(repo)
199 199 node = repo.lookup(rev)
200 200
201 201 op1, op2 = repo.dirstate.parents()
202 202 a = repo.changelog.ancestor(op1, node)
203 203 if a != node:
204 204 raise util.Abort(_('cannot back out change on a different branch'))
205 205
206 206 p1, p2 = repo.changelog.parents(node)
207 207 if p1 == nullid:
208 208 raise util.Abort(_('cannot back out a change with no parents'))
209 209 if p2 != nullid:
210 210 if not opts['parent']:
211 211 raise util.Abort(_('cannot back out a merge changeset without '
212 212 '--parent'))
213 213 p = repo.lookup(opts['parent'])
214 214 if p not in (p1, p2):
215 215 raise util.Abort(_('%s is not a parent of %s') %
216 216 (short(p), short(node)))
217 217 parent = p
218 218 else:
219 219 if opts['parent']:
220 220 raise util.Abort(_('cannot use --parent on non-merge changeset'))
221 221 parent = p1
222 222
223 223 hg.clean(repo, node, show_stats=False)
224 224 revert_opts = opts.copy()
225 225 revert_opts['date'] = None
226 226 revert_opts['all'] = True
227 227 revert_opts['rev'] = hex(parent)
228 228 revert(ui, repo, **revert_opts)
229 229 commit_opts = opts.copy()
230 230 commit_opts['addremove'] = False
231 231 if not commit_opts['message'] and not commit_opts['logfile']:
232 232 commit_opts['message'] = _("Backed out changeset %s") % (short(node))
233 233 commit_opts['force_editor'] = True
234 234 commit(ui, repo, **commit_opts)
235 235 def nice(node):
236 236 return '%d:%s' % (repo.changelog.rev(node), short(node))
237 237 ui.status(_('changeset %s backs out changeset %s\n') %
238 238 (nice(repo.changelog.tip()), nice(node)))
239 239 if op1 != node:
240 240 if opts['merge']:
241 241 ui.status(_('merging with changeset %s\n') % nice(op1))
242 242 hg.merge(repo, hex(op1))
243 243 else:
244 244 ui.status(_('the backout changeset is a new head - '
245 245 'do not forget to merge\n'))
246 246 ui.status(_('(use "backout --merge" '
247 247 'if you want to auto-merge)\n'))
248 248
249 249 def branch(ui, repo, label=None, **opts):
250 250 """set or show the current branch name
251 251
252 252 With no argument, show the current branch name. With one argument,
253 253 set the working directory branch name (the branch does not exist in
254 254 the repository until the next commit).
255 255
256 256 Unless --force is specified, branch will not let you set a
257 257 branch name that shadows an existing branch.
258 258 """
259 259
260 260 if label:
261 261 if not opts.get('force') and label in repo.branchtags():
262 262 if label not in [p.branch() for p in repo.workingctx().parents()]:
263 263 raise util.Abort(_('a branch of the same name already exists'
264 264 ' (use --force to override)'))
265 265 repo.dirstate.setbranch(util.fromlocal(label))
266 266 ui.status(_('marked working directory as branch %s\n') % label)
267 267 else:
268 268 ui.write("%s\n" % util.tolocal(repo.dirstate.branch()))
269 269
270 270 def branches(ui, repo, active=False):
271 271 """list repository named branches
272 272
273 273 List the repository's named branches, indicating which ones are
274 274 inactive. If active is specified, only show active branches.
275 275
276 276 A branch is considered active if it contains unmerged heads.
277 277 """
278 278 b = repo.branchtags()
279 279 heads = dict.fromkeys(repo.heads(), 1)
280 280 l = [((n in heads), repo.changelog.rev(n), n, t) for t, n in b.items()]
281 281 l.sort()
282 282 l.reverse()
283 283 for ishead, r, n, t in l:
284 284 if active and not ishead:
285 285 # If we're only displaying active branches, abort the loop on
286 286 # encountering the first inactive head
287 287 break
288 288 else:
289 289 hexfunc = ui.debugflag and hex or short
290 290 if ui.quiet:
291 291 ui.write("%s\n" % t)
292 292 else:
293 293 spaces = " " * (30 - util.locallen(t))
294 294 # The code only gets here if inactive branches are being
295 295 # displayed or the branch is active.
296 296 isinactive = ((not ishead) and " (inactive)") or ''
297 297 ui.write("%s%s %s:%s%s\n" % (t, spaces, r, hexfunc(n), isinactive))
298 298
299 299 def bundle(ui, repo, fname, dest=None, **opts):
300 300 """create a changegroup file
301 301
302 302 Generate a compressed changegroup file collecting changesets not
303 303 found in the other repository.
304 304
305 305 If no destination repository is specified the destination is assumed
306 306 to have all the nodes specified by one or more --base parameters.
307 307
308 308 The bundle file can then be transferred using conventional means and
309 309 applied to another repository with the unbundle or pull command.
310 310 This is useful when direct push and pull are not available or when
311 311 exporting an entire repository is undesirable.
312 312
313 313 Applying bundles preserves all changeset contents including
314 314 permissions, copy/rename information, and revision history.
315 315 """
316 316 revs = opts.get('rev') or None
317 317 if revs:
318 318 revs = [repo.lookup(rev) for rev in revs]
319 319 base = opts.get('base')
320 320 if base:
321 321 if dest:
322 322 raise util.Abort(_("--base is incompatible with specifiying "
323 323 "a destination"))
324 324 base = [repo.lookup(rev) for rev in base]
325 325 # create the right base
326 326 # XXX: nodesbetween / changegroup* should be "fixed" instead
327 327 o = []
328 328 has = {nullid: None}
329 329 for n in base:
330 330 has.update(repo.changelog.reachable(n))
331 331 if revs:
332 332 visit = list(revs)
333 333 else:
334 334 visit = repo.changelog.heads()
335 335 seen = {}
336 336 while visit:
337 337 n = visit.pop(0)
338 338 parents = [p for p in repo.changelog.parents(n) if p not in has]
339 339 if len(parents) == 0:
340 340 o.insert(0, n)
341 341 else:
342 342 for p in parents:
343 343 if p not in seen:
344 344 seen[p] = 1
345 345 visit.append(p)
346 346 else:
347 347 cmdutil.setremoteconfig(ui, opts)
348 348 dest, revs, checkout = hg.parseurl(
349 349 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
350 350 other = hg.repository(ui, dest)
351 351 o = repo.findoutgoing(other, force=opts['force'])
352 352
353 353 if revs:
354 354 cg = repo.changegroupsubset(o, revs, 'bundle')
355 355 else:
356 356 cg = repo.changegroup(o, 'bundle')
357 357 changegroup.writebundle(cg, fname, "HG10BZ")
358 358
359 359 def cat(ui, repo, file1, *pats, **opts):
360 360 """output the current or given revision of files
361 361
362 362 Print the specified files as they were at the given revision.
363 363 If no revision is given, the parent of the working directory is used,
364 364 or tip if no revision is checked out.
365 365
366 366 Output may be to a file, in which case the name of the file is
367 367 given using a format string. The formatting rules are the same as
368 368 for the export command, with the following additions:
369 369
370 370 %s basename of file being printed
371 371 %d dirname of file being printed, or '.' if in repo root
372 372 %p root-relative path name of file being printed
373 373 """
374 374 ctx = repo.changectx(opts['rev'])
375 375 err = 1
376 376 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
377 377 ctx.node()):
378 378 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
379 379 fp.write(ctx.filectx(abs).data())
380 380 err = 0
381 381 return err
382 382
383 383 def clone(ui, source, dest=None, **opts):
384 384 """make a copy of an existing repository
385 385
386 386 Create a copy of an existing repository in a new directory.
387 387
388 388 If no destination directory name is specified, it defaults to the
389 389 basename of the source.
390 390
391 391 The location of the source is added to the new repository's
392 392 .hg/hgrc file, as the default to be used for future pulls.
393 393
394 394 For efficiency, hardlinks are used for cloning whenever the source
395 395 and destination are on the same filesystem (note this applies only
396 396 to the repository data, not to the checked out files). Some
397 397 filesystems, such as AFS, implement hardlinking incorrectly, but
398 398 do not report errors. In these cases, use the --pull option to
399 399 avoid hardlinking.
400 400
401 401 You can safely clone repositories and checked out files using full
402 402 hardlinks with
403 403
404 404 $ cp -al REPO REPOCLONE
405 405
406 406 which is the fastest way to clone. However, the operation is not
407 407 atomic (making sure REPO is not modified during the operation is
408 408 up to you) and you have to make sure your editor breaks hardlinks
409 409 (Emacs and most Linux Kernel tools do so).
410 410
411 411 If you use the -r option to clone up to a specific revision, no
412 412 subsequent revisions will be present in the cloned repository.
413 413 This option implies --pull, even on local repositories.
414 414
415 415 See pull for valid source format details.
416 416
417 417 It is possible to specify an ssh:// URL as the destination, but no
418 418 .hg/hgrc and working directory will be created on the remote side.
419 419 Look at the help text for the pull command for important details
420 420 about ssh:// URLs.
421 421 """
422 422 cmdutil.setremoteconfig(ui, opts)
423 423 hg.clone(ui, source, dest,
424 424 pull=opts['pull'],
425 425 stream=opts['uncompressed'],
426 426 rev=opts['rev'],
427 427 update=not opts['noupdate'])
428 428
429 429 def commit(ui, repo, *pats, **opts):
430 430 """commit the specified files or all outstanding changes
431 431
432 432 Commit changes to the given files into the repository.
433 433
434 434 If a list of files is omitted, all changes reported by "hg status"
435 435 will be committed.
436 436
437 437 If no commit message is specified, the configured editor is started to
438 438 enter a message.
439 439 """
440 440 def commitfunc(ui, repo, files, message, match, opts):
441 441 return repo.commit(files, message, opts['user'], opts['date'], match,
442 442 force_editor=opts.get('force_editor'))
443 443 cmdutil.commit(ui, repo, commitfunc, pats, opts)
444 444
445 445 def copy(ui, repo, *pats, **opts):
446 446 """mark files as copied for the next commit
447 447
448 448 Mark dest as having copies of source files. If dest is a
449 449 directory, copies are put in that directory. If dest is a file,
450 450 there can only be one source.
451 451
452 452 By default, this command copies the contents of files as they
453 453 stand in the working directory. If invoked with --after, the
454 454 operation is recorded, but no copying is performed.
455 455
456 456 This command takes effect in the next commit. To undo a copy
457 457 before that, see hg revert.
458 458 """
459 459 wlock = repo.wlock(False)
460 460 try:
461 461 return cmdutil.copy(ui, repo, pats, opts)
462 462 finally:
463 463 del wlock
464 464
465 465 def debugancestor(ui, index, rev1, rev2):
466 466 """find the ancestor revision of two revisions in a given index"""
467 467 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
468 468 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
469 469 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
470 470
471 471 def debugcomplete(ui, cmd='', **opts):
472 472 """returns the completion list associated with the given command"""
473 473
474 474 if opts['options']:
475 475 options = []
476 476 otables = [globalopts]
477 477 if cmd:
478 478 aliases, entry = cmdutil.findcmd(ui, cmd, table)
479 479 otables.append(entry[1])
480 480 for t in otables:
481 481 for o in t:
482 482 if o[0]:
483 483 options.append('-%s' % o[0])
484 484 options.append('--%s' % o[1])
485 485 ui.write("%s\n" % "\n".join(options))
486 486 return
487 487
488 488 clist = cmdutil.findpossible(ui, cmd, table).keys()
489 489 clist.sort()
490 490 ui.write("%s\n" % "\n".join(clist))
491 491
492 492 def debugfsinfo(ui, path = "."):
493 493 file('.debugfsinfo', 'w').write('')
494 494 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
495 495 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
496 496 ui.write('case-sensitive: %s\n' % (util.checkfolding('.debugfsinfo')
497 497 and 'yes' or 'no'))
498 498 os.unlink('.debugfsinfo')
499 499
500 500 def debugrebuildstate(ui, repo, rev=""):
501 501 """rebuild the dirstate as it would look like for the given revision"""
502 502 if rev == "":
503 503 rev = repo.changelog.tip()
504 504 ctx = repo.changectx(rev)
505 505 files = ctx.manifest()
506 506 wlock = repo.wlock()
507 507 try:
508 508 repo.dirstate.rebuild(rev, files)
509 509 finally:
510 510 del wlock
511 511
512 512 def debugcheckstate(ui, repo):
513 513 """validate the correctness of the current dirstate"""
514 514 parent1, parent2 = repo.dirstate.parents()
515 515 m1 = repo.changectx(parent1).manifest()
516 516 m2 = repo.changectx(parent2).manifest()
517 517 errors = 0
518 518 for f in repo.dirstate:
519 519 state = repo.dirstate[f]
520 520 if state in "nr" and f not in m1:
521 521 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
522 522 errors += 1
523 523 if state in "a" and f in m1:
524 524 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
525 525 errors += 1
526 526 if state in "m" and f not in m1 and f not in m2:
527 527 ui.warn(_("%s in state %s, but not in either manifest\n") %
528 528 (f, state))
529 529 errors += 1
530 530 for f in m1:
531 531 state = repo.dirstate[f]
532 532 if state not in "nrm":
533 533 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
534 534 errors += 1
535 535 if errors:
536 536 error = _(".hg/dirstate inconsistent with current parent's manifest")
537 537 raise util.Abort(error)
538 538
539 539 def showconfig(ui, repo, *values, **opts):
540 540 """show combined config settings from all hgrc files
541 541
542 542 With no args, print names and values of all config items.
543 543
544 544 With one arg of the form section.name, print just the value of
545 545 that config item.
546 546
547 547 With multiple args, print names and values of all config items
548 548 with matching section names."""
549 549
550 550 untrusted = bool(opts.get('untrusted'))
551 551 if values:
552 552 if len([v for v in values if '.' in v]) > 1:
553 553 raise util.Abort(_('only one config item permitted'))
554 554 for section, name, value in ui.walkconfig(untrusted=untrusted):
555 555 sectname = section + '.' + name
556 556 if values:
557 557 for v in values:
558 558 if v == section:
559 559 ui.write('%s=%s\n' % (sectname, value))
560 560 elif v == sectname:
561 561 ui.write(value, '\n')
562 562 else:
563 563 ui.write('%s=%s\n' % (sectname, value))
564 564
565 565 def debugsetparents(ui, repo, rev1, rev2=None):
566 566 """manually set the parents of the current working directory
567 567
568 568 This is useful for writing repository conversion tools, but should
569 569 be used with care.
570 570 """
571 571
572 572 if not rev2:
573 573 rev2 = hex(nullid)
574 574
575 575 wlock = repo.wlock()
576 576 try:
577 577 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
578 578 finally:
579 579 del wlock
580 580
581 581 def debugstate(ui, repo):
582 582 """show the contents of the current dirstate"""
583 583 k = repo.dirstate._map.items()
584 584 k.sort()
585 585 for file_, ent in k:
586 586 if ent[3] == -1:
587 587 # Pad or slice to locale representation
588 588 locale_len = len(time.strftime("%x %X", time.localtime(0)))
589 589 timestr = 'unset'
590 590 timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
591 591 else:
592 592 timestr = time.strftime("%x %X", time.localtime(ent[3]))
593 593 if ent[1] & 020000:
594 594 mode = 'lnk'
595 595 else:
596 596 mode = '%3o' % (ent[1] & 0777)
597 597 ui.write("%c %s %10d %s %s\n" % (ent[0], mode, ent[2], timestr, file_))
598 598 for f in repo.dirstate.copies():
599 599 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
600 600
601 601 def debugdata(ui, file_, rev):
602 602 """dump the contents of a data file revision"""
603 603 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
604 604 try:
605 605 ui.write(r.revision(r.lookup(rev)))
606 606 except KeyError:
607 607 raise util.Abort(_('invalid revision identifier %s') % rev)
608 608
609 609 def debugdate(ui, date, range=None, **opts):
610 610 """parse and display a date"""
611 611 if opts["extended"]:
612 612 d = util.parsedate(date, util.extendeddateformats)
613 613 else:
614 614 d = util.parsedate(date)
615 615 ui.write("internal: %s %s\n" % d)
616 616 ui.write("standard: %s\n" % util.datestr(d))
617 617 if range:
618 618 m = util.matchdate(range)
619 619 ui.write("match: %s\n" % m(d[0]))
620 620
621 621 def debugindex(ui, file_):
622 622 """dump the contents of an index file"""
623 623 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
624 624 ui.write(" rev offset length base linkrev" +
625 625 " nodeid p1 p2\n")
626 626 for i in xrange(r.count()):
627 627 node = r.node(i)
628 628 try:
629 629 pp = r.parents(node)
630 630 except:
631 631 pp = [nullid, nullid]
632 632 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
633 633 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
634 634 short(node), short(pp[0]), short(pp[1])))
635 635
636 636 def debugindexdot(ui, file_):
637 637 """dump an index DAG as a .dot file"""
638 638 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
639 639 ui.write("digraph G {\n")
640 640 for i in xrange(r.count()):
641 641 node = r.node(i)
642 642 pp = r.parents(node)
643 643 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
644 644 if pp[1] != nullid:
645 645 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
646 646 ui.write("}\n")
647 647
648 648 def debuginstall(ui):
649 649 '''test Mercurial installation'''
650 650
651 651 def writetemp(contents):
652 652 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
653 653 f = os.fdopen(fd, "wb")
654 654 f.write(contents)
655 655 f.close()
656 656 return name
657 657
658 658 problems = 0
659 659
660 660 # encoding
661 661 ui.status(_("Checking encoding (%s)...\n") % util._encoding)
662 662 try:
663 663 util.fromlocal("test")
664 664 except util.Abort, inst:
665 665 ui.write(" %s\n" % inst)
666 666 ui.write(_(" (check that your locale is properly set)\n"))
667 667 problems += 1
668 668
669 669 # compiled modules
670 670 ui.status(_("Checking extensions...\n"))
671 671 try:
672 672 import bdiff, mpatch, base85
673 673 except Exception, inst:
674 674 ui.write(" %s\n" % inst)
675 675 ui.write(_(" One or more extensions could not be found"))
676 676 ui.write(_(" (check that you compiled the extensions)\n"))
677 677 problems += 1
678 678
679 679 # templates
680 680 ui.status(_("Checking templates...\n"))
681 681 try:
682 682 import templater
683 683 t = templater.templater(templater.templatepath("map-cmdline.default"))
684 684 except Exception, inst:
685 685 ui.write(" %s\n" % inst)
686 686 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
687 687 problems += 1
688 688
689 689 # patch
690 690 ui.status(_("Checking patch...\n"))
691 691 patchproblems = 0
692 692 a = "1\n2\n3\n4\n"
693 693 b = "1\n2\n3\ninsert\n4\n"
694 694 fa = writetemp(a)
695 695 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
696 696 os.path.basename(fa))
697 697 fd = writetemp(d)
698 698
699 699 files = {}
700 700 try:
701 701 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
702 702 except util.Abort, e:
703 703 ui.write(_(" patch call failed:\n"))
704 704 ui.write(" " + str(e) + "\n")
705 705 patchproblems += 1
706 706 else:
707 707 if list(files) != [os.path.basename(fa)]:
708 708 ui.write(_(" unexpected patch output!\n"))
709 709 patchproblems += 1
710 710 a = file(fa).read()
711 711 if a != b:
712 712 ui.write(_(" patch test failed!\n"))
713 713 patchproblems += 1
714 714
715 715 if patchproblems:
716 716 if ui.config('ui', 'patch'):
717 717 ui.write(_(" (Current patch tool may be incompatible with patch,"
718 718 " or misconfigured. Please check your .hgrc file)\n"))
719 719 else:
720 720 ui.write(_(" Internal patcher failure, please report this error"
721 721 " to http://www.selenic.com/mercurial/bts\n"))
722 722 problems += patchproblems
723 723
724 724 os.unlink(fa)
725 725 os.unlink(fd)
726 726
727 727 # merge helper
728 728 ui.status(_("Checking merge helper...\n"))
729 729 cmd = (os.environ.get("HGMERGE") or ui.config("ui", "merge")
730 730 or "hgmerge")
731 731 cmdpath = util.find_exe(cmd) or util.find_exe(cmd.split()[0])
732 732 if not cmdpath:
733 733 if cmd == 'hgmerge':
734 734 ui.write(_(" No merge helper set and can't find default"
735 735 " hgmerge script in PATH\n"))
736 736 ui.write(_(" (specify a merge helper in your .hgrc file)\n"))
737 737 else:
738 738 ui.write(_(" Can't find merge helper '%s' in PATH\n") % cmd)
739 739 ui.write(_(" (specify a merge helper in your .hgrc file)\n"))
740 740 problems += 1
741 741 else:
742 742 # actually attempt a patch here
743 743 fa = writetemp("1\n2\n3\n4\n")
744 744 fl = writetemp("1\n2\n3\ninsert\n4\n")
745 745 fr = writetemp("begin\n1\n2\n3\n4\n")
746 746 r = util.system('%s "%s" "%s" "%s"' % (cmd, fl, fa, fr))
747 747 if r:
748 748 ui.write(_(" Got unexpected merge error %d!\n") % r)
749 749 problems += 1
750 750 m = file(fl).read()
751 751 if m != "begin\n1\n2\n3\ninsert\n4\n":
752 752 ui.write(_(" Got unexpected merge results!\n"))
753 753 ui.write(_(" (your merge helper may have the"
754 754 " wrong argument order)\n"))
755 755 ui.write(_(" Result: %r\n") % m)
756 756 problems += 1
757 757 os.unlink(fa)
758 758 os.unlink(fl)
759 759 os.unlink(fr)
760 760
761 761 # editor
762 762 ui.status(_("Checking commit editor...\n"))
763 763 editor = ui.geteditor()
764 764 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
765 765 if not cmdpath:
766 766 if editor == 'vi':
767 767 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
768 768 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
769 769 else:
770 770 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
771 771 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
772 772 problems += 1
773 773
774 774 # check username
775 775 ui.status(_("Checking username...\n"))
776 776 user = os.environ.get("HGUSER")
777 777 if user is None:
778 778 user = ui.config("ui", "username")
779 779 if user is None:
780 780 user = os.environ.get("EMAIL")
781 781 if not user:
782 782 ui.warn(" ")
783 783 ui.username()
784 784 ui.write(_(" (specify a username in your .hgrc file)\n"))
785 785
786 786 if not problems:
787 787 ui.status(_("No problems detected\n"))
788 788 else:
789 789 ui.write(_("%s problems detected,"
790 790 " please check your install!\n") % problems)
791 791
792 792 return problems
793 793
794 794 def debugrename(ui, repo, file1, *pats, **opts):
795 795 """dump rename information"""
796 796
797 797 ctx = repo.changectx(opts.get('rev', 'tip'))
798 798 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
799 799 ctx.node()):
800 800 m = ctx.filectx(abs).renamed()
801 801 if m:
802 802 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1])))
803 803 else:
804 804 ui.write(_("%s not renamed\n") % rel)
805 805
806 806 def debugwalk(ui, repo, *pats, **opts):
807 807 """show how files match on given patterns"""
808 808 items = list(cmdutil.walk(repo, pats, opts))
809 809 if not items:
810 810 return
811 811 fmt = '%%s %%-%ds %%-%ds %%s' % (
812 812 max([len(abs) for (src, abs, rel, exact) in items]),
813 813 max([len(rel) for (src, abs, rel, exact) in items]))
814 814 for src, abs, rel, exact in items:
815 815 line = fmt % (src, abs, rel, exact and 'exact' or '')
816 816 ui.write("%s\n" % line.rstrip())
817 817
818 818 def diff(ui, repo, *pats, **opts):
819 819 """diff repository (or selected files)
820 820
821 821 Show differences between revisions for the specified files.
822 822
823 823 Differences between files are shown using the unified diff format.
824 824
825 825 NOTE: diff may generate unexpected results for merges, as it will
826 826 default to comparing against the working directory's first parent
827 827 changeset if no revisions are specified.
828 828
829 829 When two revision arguments are given, then changes are shown
830 830 between those revisions. If only one revision is specified then
831 831 that revision is compared to the working directory, and, when no
832 832 revisions are specified, the working directory files are compared
833 833 to its parent.
834 834
835 835 Without the -a option, diff will avoid generating diffs of files
836 836 it detects as binary. With -a, diff will generate a diff anyway,
837 837 probably with undesirable results.
838 838 """
839 839 node1, node2 = cmdutil.revpair(repo, opts['rev'])
840 840
841 841 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
842 842
843 843 patch.diff(repo, node1, node2, fns, match=matchfn,
844 844 opts=patch.diffopts(ui, opts))
845 845
846 846 def export(ui, repo, *changesets, **opts):
847 847 """dump the header and diffs for one or more changesets
848 848
849 849 Print the changeset header and diffs for one or more revisions.
850 850
851 851 The information shown in the changeset header is: author,
852 852 changeset hash, parent(s) and commit comment.
853 853
854 854 NOTE: export may generate unexpected diff output for merge changesets,
855 855 as it will compare the merge changeset against its first parent only.
856 856
857 857 Output may be to a file, in which case the name of the file is
858 858 given using a format string. The formatting rules are as follows:
859 859
860 860 %% literal "%" character
861 861 %H changeset hash (40 bytes of hexadecimal)
862 862 %N number of patches being generated
863 863 %R changeset revision number
864 864 %b basename of the exporting repository
865 865 %h short-form changeset hash (12 bytes of hexadecimal)
866 866 %n zero-padded sequence number, starting at 1
867 867 %r zero-padded changeset revision number
868 868
869 869 Without the -a option, export will avoid generating diffs of files
870 870 it detects as binary. With -a, export will generate a diff anyway,
871 871 probably with undesirable results.
872 872
873 873 With the --switch-parent option, the diff will be against the second
874 874 parent. It can be useful to review a merge.
875 875 """
876 876 if not changesets:
877 877 raise util.Abort(_("export requires at least one changeset"))
878 878 revs = cmdutil.revrange(repo, changesets)
879 879 if len(revs) > 1:
880 880 ui.note(_('exporting patches:\n'))
881 881 else:
882 882 ui.note(_('exporting patch:\n'))
883 883 patch.export(repo, revs, template=opts['output'],
884 884 switch_parent=opts['switch_parent'],
885 885 opts=patch.diffopts(ui, opts))
886 886
887 887 def grep(ui, repo, pattern, *pats, **opts):
888 888 """search for a pattern in specified files and revisions
889 889
890 890 Search revisions of files for a regular expression.
891 891
892 892 This command behaves differently than Unix grep. It only accepts
893 893 Python/Perl regexps. It searches repository history, not the
894 894 working directory. It always prints the revision number in which
895 895 a match appears.
896 896
897 897 By default, grep only prints output for the first revision of a
898 898 file in which it finds a match. To get it to print every revision
899 899 that contains a change in match status ("-" for a match that
900 900 becomes a non-match, or "+" for a non-match that becomes a match),
901 901 use the --all flag.
902 902 """
903 903 reflags = 0
904 904 if opts['ignore_case']:
905 905 reflags |= re.I
906 906 try:
907 907 regexp = re.compile(pattern, reflags)
908 908 except Exception, inst:
909 909 ui.warn(_("grep: invalid match pattern: %s!\n") % inst)
910 910 return None
911 911 sep, eol = ':', '\n'
912 912 if opts['print0']:
913 913 sep = eol = '\0'
914 914
915 915 fcache = {}
916 916 def getfile(fn):
917 917 if fn not in fcache:
918 918 fcache[fn] = repo.file(fn)
919 919 return fcache[fn]
920 920
921 921 def matchlines(body):
922 922 begin = 0
923 923 linenum = 0
924 924 while True:
925 925 match = regexp.search(body, begin)
926 926 if not match:
927 927 break
928 928 mstart, mend = match.span()
929 929 linenum += body.count('\n', begin, mstart) + 1
930 930 lstart = body.rfind('\n', begin, mstart) + 1 or begin
931 931 lend = body.find('\n', mend)
932 932 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
933 933 begin = lend + 1
934 934
935 935 class linestate(object):
936 936 def __init__(self, line, linenum, colstart, colend):
937 937 self.line = line
938 938 self.linenum = linenum
939 939 self.colstart = colstart
940 940 self.colend = colend
941 941
942 942 def __eq__(self, other):
943 943 return self.line == other.line
944 944
945 945 matches = {}
946 946 copies = {}
947 947 def grepbody(fn, rev, body):
948 948 matches[rev].setdefault(fn, [])
949 949 m = matches[rev][fn]
950 950 for lnum, cstart, cend, line in matchlines(body):
951 951 s = linestate(line, lnum, cstart, cend)
952 952 m.append(s)
953 953
954 954 def difflinestates(a, b):
955 955 sm = difflib.SequenceMatcher(None, a, b)
956 956 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
957 957 if tag == 'insert':
958 958 for i in xrange(blo, bhi):
959 959 yield ('+', b[i])
960 960 elif tag == 'delete':
961 961 for i in xrange(alo, ahi):
962 962 yield ('-', a[i])
963 963 elif tag == 'replace':
964 964 for i in xrange(alo, ahi):
965 965 yield ('-', a[i])
966 966 for i in xrange(blo, bhi):
967 967 yield ('+', b[i])
968 968
969 969 prev = {}
970 970 def display(fn, rev, states, prevstates):
971 971 found = False
972 972 filerevmatches = {}
973 973 r = prev.get(fn, -1)
974 974 if opts['all']:
975 975 iter = difflinestates(states, prevstates)
976 976 else:
977 977 iter = [('', l) for l in prevstates]
978 978 for change, l in iter:
979 979 cols = [fn, str(r)]
980 980 if opts['line_number']:
981 981 cols.append(str(l.linenum))
982 982 if opts['all']:
983 983 cols.append(change)
984 984 if opts['user']:
985 985 cols.append(ui.shortuser(get(r)[1]))
986 986 if opts['files_with_matches']:
987 987 c = (fn, r)
988 988 if c in filerevmatches:
989 989 continue
990 990 filerevmatches[c] = 1
991 991 else:
992 992 cols.append(l.line)
993 993 ui.write(sep.join(cols), eol)
994 994 found = True
995 995 return found
996 996
997 997 fstate = {}
998 998 skip = {}
999 999 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1000 1000 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1001 1001 found = False
1002 1002 follow = opts.get('follow')
1003 1003 for st, rev, fns in changeiter:
1004 1004 if st == 'window':
1005 1005 matches.clear()
1006 1006 elif st == 'add':
1007 1007 mf = repo.changectx(rev).manifest()
1008 1008 matches[rev] = {}
1009 1009 for fn in fns:
1010 1010 if fn in skip:
1011 1011 continue
1012 1012 try:
1013 1013 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1014 1014 fstate.setdefault(fn, [])
1015 1015 if follow:
1016 1016 copied = getfile(fn).renamed(mf[fn])
1017 1017 if copied:
1018 1018 copies.setdefault(rev, {})[fn] = copied[0]
1019 1019 except KeyError:
1020 1020 pass
1021 1021 elif st == 'iter':
1022 1022 states = matches[rev].items()
1023 1023 states.sort()
1024 1024 for fn, m in states:
1025 1025 copy = copies.get(rev, {}).get(fn)
1026 1026 if fn in skip:
1027 1027 if copy:
1028 1028 skip[copy] = True
1029 1029 continue
1030 1030 if fn in prev or fstate[fn]:
1031 1031 r = display(fn, rev, m, fstate[fn])
1032 1032 found = found or r
1033 1033 if r and not opts['all']:
1034 1034 skip[fn] = True
1035 1035 if copy:
1036 1036 skip[copy] = True
1037 1037 fstate[fn] = m
1038 1038 if copy:
1039 1039 fstate[copy] = m
1040 1040 prev[fn] = rev
1041 1041
1042 1042 fstate = fstate.items()
1043 1043 fstate.sort()
1044 1044 for fn, state in fstate:
1045 1045 if fn in skip:
1046 1046 continue
1047 1047 if fn not in copies.get(prev[fn], {}):
1048 1048 found = display(fn, rev, {}, state) or found
1049 1049 return (not found and 1) or 0
1050 1050
1051 1051 def heads(ui, repo, *branchrevs, **opts):
1052 1052 """show current repository heads or show branch heads
1053 1053
1054 1054 With no arguments, show all repository head changesets.
1055 1055
1056 1056 If branch or revisions names are given this will show the heads of
1057 1057 the specified branches or the branches those revisions are tagged
1058 1058 with.
1059 1059
1060 1060 Repository "heads" are changesets that don't have child
1061 1061 changesets. They are where development generally takes place and
1062 1062 are the usual targets for update and merge operations.
1063 1063
1064 1064 Branch heads are changesets that have a given branch tag, but have
1065 1065 no child changesets with that tag. They are usually where
1066 1066 development on the given branch takes place.
1067 1067 """
1068 1068 if opts['rev']:
1069 1069 start = repo.lookup(opts['rev'])
1070 1070 else:
1071 1071 start = None
1072 1072 if not branchrevs:
1073 1073 # Assume we're looking repo-wide heads if no revs were specified.
1074 1074 heads = repo.heads(start)
1075 1075 else:
1076 1076 heads = []
1077 1077 visitedset = util.set()
1078 1078 for branchrev in branchrevs:
1079 1079 branch = repo.changectx(branchrev).branch()
1080 1080 if branch in visitedset:
1081 1081 continue
1082 1082 visitedset.add(branch)
1083 1083 bheads = repo.branchheads(branch, start)
1084 1084 if not bheads:
1085 1085 if branch != branchrev:
1086 1086 ui.warn(_("no changes on branch %s containing %s are "
1087 1087 "reachable from %s\n")
1088 1088 % (branch, branchrev, opts['rev']))
1089 1089 else:
1090 1090 ui.warn(_("no changes on branch %s are reachable from %s\n")
1091 1091 % (branch, opts['rev']))
1092 1092 heads.extend(bheads)
1093 1093 if not heads:
1094 1094 return 1
1095 1095 displayer = cmdutil.show_changeset(ui, repo, opts)
1096 1096 for n in heads:
1097 1097 displayer.show(changenode=n)
1098 1098
1099 1099 def help_(ui, name=None, with_version=False):
1100 1100 """show help for a command, extension, or list of commands
1101 1101
1102 1102 With no arguments, print a list of commands and short help.
1103 1103
1104 1104 Given a command name, print help for that command.
1105 1105
1106 1106 Given an extension name, print help for that extension, and the
1107 1107 commands it provides."""
1108 1108 option_lists = []
1109 1109
1110 1110 def addglobalopts(aliases):
1111 1111 if ui.verbose:
1112 1112 option_lists.append((_("global options:"), globalopts))
1113 1113 if name == 'shortlist':
1114 1114 option_lists.append((_('use "hg help" for the full list '
1115 1115 'of commands'), ()))
1116 1116 else:
1117 1117 if name == 'shortlist':
1118 1118 msg = _('use "hg help" for the full list of commands '
1119 1119 'or "hg -v" for details')
1120 1120 elif aliases:
1121 1121 msg = _('use "hg -v help%s" to show aliases and '
1122 1122 'global options') % (name and " " + name or "")
1123 1123 else:
1124 1124 msg = _('use "hg -v help %s" to show global options') % name
1125 1125 option_lists.append((msg, ()))
1126 1126
1127 1127 def helpcmd(name):
1128 1128 if with_version:
1129 1129 version_(ui)
1130 1130 ui.write('\n')
1131 1131 aliases, i = cmdutil.findcmd(ui, name, table)
1132 1132 # synopsis
1133 1133 ui.write("%s\n\n" % i[2])
1134 1134
1135 1135 # description
1136 1136 doc = i[0].__doc__
1137 1137 if not doc:
1138 1138 doc = _("(No help text available)")
1139 1139 if ui.quiet:
1140 1140 doc = doc.splitlines(0)[0]
1141 1141 ui.write("%s\n" % doc.rstrip())
1142 1142
1143 1143 if not ui.quiet:
1144 1144 # aliases
1145 1145 if len(aliases) > 1:
1146 1146 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1147 1147
1148 1148 # options
1149 1149 if i[1]:
1150 1150 option_lists.append((_("options:\n"), i[1]))
1151 1151
1152 1152 addglobalopts(False)
1153 1153
1154 1154 def helplist(header, select=None):
1155 1155 h = {}
1156 1156 cmds = {}
1157 1157 for c, e in table.items():
1158 1158 f = c.split("|", 1)[0]
1159 1159 if select and not select(f):
1160 1160 continue
1161 1161 if name == "shortlist" and not f.startswith("^"):
1162 1162 continue
1163 1163 f = f.lstrip("^")
1164 1164 if not ui.debugflag and f.startswith("debug"):
1165 1165 continue
1166 1166 doc = e[0].__doc__
1167 1167 if not doc:
1168 1168 doc = _("(No help text available)")
1169 1169 h[f] = doc.splitlines(0)[0].rstrip()
1170 1170 cmds[f] = c.lstrip("^")
1171 1171
1172 1172 if not h:
1173 1173 ui.status(_('no commands defined\n'))
1174 1174 return
1175 1175
1176 1176 ui.status(header)
1177 1177 fns = h.keys()
1178 1178 fns.sort()
1179 1179 m = max(map(len, fns))
1180 1180 for f in fns:
1181 1181 if ui.verbose:
1182 1182 commands = cmds[f].replace("|",", ")
1183 1183 ui.write(" %s:\n %s\n"%(commands, h[f]))
1184 1184 else:
1185 1185 ui.write(' %-*s %s\n' % (m, f, h[f]))
1186 1186
1187 1187 if not ui.quiet:
1188 1188 addglobalopts(True)
1189 1189
1190 1190 def helptopic(name):
1191 1191 v = None
1192 1192 for i in help.helptable:
1193 1193 l = i.split('|')
1194 1194 if name in l:
1195 1195 v = i
1196 1196 header = l[-1]
1197 1197 if not v:
1198 1198 raise cmdutil.UnknownCommand(name)
1199 1199
1200 1200 # description
1201 1201 doc = help.helptable[v]
1202 1202 if not doc:
1203 1203 doc = _("(No help text available)")
1204 1204 if callable(doc):
1205 1205 doc = doc()
1206 1206
1207 1207 ui.write("%s\n" % header)
1208 1208 ui.write("%s\n" % doc.rstrip())
1209 1209
1210 1210 def helpext(name):
1211 1211 try:
1212 1212 mod = extensions.find(name)
1213 1213 except KeyError:
1214 1214 raise cmdutil.UnknownCommand(name)
1215 1215
1216 1216 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1217 1217 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1218 1218 for d in doc[1:]:
1219 1219 ui.write(d, '\n')
1220 1220
1221 1221 ui.status('\n')
1222 1222
1223 1223 try:
1224 1224 ct = mod.cmdtable
1225 1225 except AttributeError:
1226 1226 ct = {}
1227 1227
1228 1228 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct])
1229 1229 helplist(_('list of commands:\n\n'), modcmds.has_key)
1230 1230
1231 1231 if name and name != 'shortlist':
1232 1232 i = None
1233 1233 for f in (helpcmd, helptopic, helpext):
1234 1234 try:
1235 1235 f(name)
1236 1236 i = None
1237 1237 break
1238 1238 except cmdutil.UnknownCommand, inst:
1239 1239 i = inst
1240 1240 if i:
1241 1241 raise i
1242 1242
1243 1243 else:
1244 1244 # program name
1245 1245 if ui.verbose or with_version:
1246 1246 version_(ui)
1247 1247 else:
1248 1248 ui.status(_("Mercurial Distributed SCM\n"))
1249 1249 ui.status('\n')
1250 1250
1251 1251 # list of commands
1252 1252 if name == "shortlist":
1253 1253 header = _('basic commands:\n\n')
1254 1254 else:
1255 1255 header = _('list of commands:\n\n')
1256 1256
1257 1257 helplist(header)
1258 1258
1259 1259 # list all option lists
1260 1260 opt_output = []
1261 1261 for title, options in option_lists:
1262 1262 opt_output.append(("\n%s" % title, None))
1263 1263 for shortopt, longopt, default, desc in options:
1264 1264 if "DEPRECATED" in desc and not ui.verbose: continue
1265 1265 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1266 1266 longopt and " --%s" % longopt),
1267 1267 "%s%s" % (desc,
1268 1268 default
1269 1269 and _(" (default: %s)") % default
1270 1270 or "")))
1271 1271
1272 1272 if opt_output:
1273 1273 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1274 1274 for first, second in opt_output:
1275 1275 if second:
1276 1276 ui.write(" %-*s %s\n" % (opts_len, first, second))
1277 1277 else:
1278 1278 ui.write("%s\n" % first)
1279 1279
1280 1280 def identify(ui, repo, source=None,
1281 1281 rev=None, num=None, id=None, branch=None, tags=None):
1282 1282 """identify the working copy or specified revision
1283 1283
1284 1284 With no revision, print a summary of the current state of the repo.
1285 1285
1286 1286 With a path, do a lookup in another repository.
1287 1287
1288 1288 This summary identifies the repository state using one or two parent
1289 1289 hash identifiers, followed by a "+" if there are uncommitted changes
1290 1290 in the working directory, a list of tags for this revision and a branch
1291 1291 name for non-default branches.
1292 1292 """
1293 1293
1294 1294 if not repo and not source:
1295 1295 raise util.Abort(_("There is no Mercurial repository here "
1296 1296 "(.hg not found)"))
1297 1297
1298 1298 hexfunc = ui.debugflag and hex or short
1299 1299 default = not (num or id or branch or tags)
1300 1300 output = []
1301 1301
1302 1302 if source:
1303 1303 source, revs, checkout = hg.parseurl(ui.expandpath(source), [])
1304 1304 srepo = hg.repository(ui, source)
1305 1305 if not rev and revs:
1306 1306 rev = revs[0]
1307 1307 if not rev:
1308 1308 rev = "tip"
1309 1309 if num or branch or tags:
1310 1310 raise util.Abort(
1311 1311 "can't query remote revision number, branch, or tags")
1312 1312 output = [hexfunc(srepo.lookup(rev))]
1313 1313 elif not rev:
1314 1314 ctx = repo.workingctx()
1315 1315 parents = ctx.parents()
1316 1316 changed = False
1317 1317 if default or id or num:
1318 1318 changed = ctx.files() + ctx.deleted()
1319 1319 if default or id:
1320 1320 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
1321 1321 (changed) and "+" or "")]
1322 1322 if num:
1323 1323 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
1324 1324 (changed) and "+" or ""))
1325 1325 else:
1326 1326 ctx = repo.changectx(rev)
1327 1327 if default or id:
1328 1328 output = [hexfunc(ctx.node())]
1329 1329 if num:
1330 1330 output.append(str(ctx.rev()))
1331 1331
1332 1332 if not source and default and not ui.quiet:
1333 1333 b = util.tolocal(ctx.branch())
1334 1334 if b != 'default':
1335 1335 output.append("(%s)" % b)
1336 1336
1337 1337 # multiple tags for a single parent separated by '/'
1338 1338 t = "/".join(ctx.tags())
1339 1339 if t:
1340 1340 output.append(t)
1341 1341
1342 1342 if branch:
1343 1343 output.append(util.tolocal(ctx.branch()))
1344 1344
1345 1345 if tags:
1346 1346 output.extend(ctx.tags())
1347 1347
1348 1348 ui.write("%s\n" % ' '.join(output))
1349 1349
1350 1350 def import_(ui, repo, patch1, *patches, **opts):
1351 1351 """import an ordered set of patches
1352 1352
1353 1353 Import a list of patches and commit them individually.
1354 1354
1355 1355 If there are outstanding changes in the working directory, import
1356 1356 will abort unless given the -f flag.
1357 1357
1358 1358 You can import a patch straight from a mail message. Even patches
1359 1359 as attachments work (body part must be type text/plain or
1360 1360 text/x-patch to be used). From and Subject headers of email
1361 1361 message are used as default committer and commit message. All
1362 1362 text/plain body parts before first diff are added to commit
1363 1363 message.
1364 1364
1365 1365 If the imported patch was generated by hg export, user and description
1366 1366 from patch override values from message headers and body. Values
1367 1367 given on command line with -m and -u override these.
1368 1368
1369 1369 If --exact is specified, import will set the working directory
1370 1370 to the parent of each patch before applying it, and will abort
1371 1371 if the resulting changeset has a different ID than the one
1372 1372 recorded in the patch. This may happen due to character set
1373 1373 problems or other deficiencies in the text patch format.
1374 1374
1375 1375 To read a patch from standard input, use patch name "-".
1376 1376 """
1377 1377 patches = (patch1,) + patches
1378 1378
1379 1379 if opts.get('exact') or not opts['force']:
1380 1380 cmdutil.bail_if_changed(repo)
1381 1381
1382 1382 d = opts["base"]
1383 1383 strip = opts["strip"]
1384 1384 wlock = lock = None
1385 1385 try:
1386 1386 wlock = repo.wlock()
1387 1387 lock = repo.lock()
1388 1388 for p in patches:
1389 1389 pf = os.path.join(d, p)
1390 1390
1391 1391 if pf == '-':
1392 1392 ui.status(_("applying patch from stdin\n"))
1393 1393 data = patch.extract(ui, sys.stdin)
1394 1394 else:
1395 1395 ui.status(_("applying %s\n") % p)
1396 1396 if os.path.exists(pf):
1397 1397 data = patch.extract(ui, file(pf, 'rb'))
1398 1398 else:
1399 1399 data = patch.extract(ui, urllib.urlopen(pf))
1400 1400 tmpname, message, user, date, branch, nodeid, p1, p2 = data
1401 1401
1402 1402 if tmpname is None:
1403 1403 raise util.Abort(_('no diffs found'))
1404 1404
1405 1405 try:
1406 1406 cmdline_message = cmdutil.logmessage(opts)
1407 1407 if cmdline_message:
1408 1408 # pickup the cmdline msg
1409 1409 message = cmdline_message
1410 1410 elif message:
1411 1411 # pickup the patch msg
1412 1412 message = message.strip()
1413 1413 else:
1414 1414 # launch the editor
1415 1415 message = None
1416 1416 ui.debug(_('message:\n%s\n') % message)
1417 1417
1418 1418 wp = repo.workingctx().parents()
1419 1419 if opts.get('exact'):
1420 1420 if not nodeid or not p1:
1421 1421 raise util.Abort(_('not a mercurial patch'))
1422 1422 p1 = repo.lookup(p1)
1423 1423 p2 = repo.lookup(p2 or hex(nullid))
1424 1424
1425 1425 if p1 != wp[0].node():
1426 1426 hg.clean(repo, p1)
1427 1427 repo.dirstate.setparents(p1, p2)
1428 1428 elif p2:
1429 1429 try:
1430 1430 p1 = repo.lookup(p1)
1431 1431 p2 = repo.lookup(p2)
1432 1432 if p1 == wp[0].node():
1433 1433 repo.dirstate.setparents(p1, p2)
1434 1434 except hg.RepoError:
1435 1435 pass
1436 1436 if opts.get('exact') or opts.get('import_branch'):
1437 1437 repo.dirstate.setbranch(branch or 'default')
1438 1438
1439 1439 files = {}
1440 1440 try:
1441 1441 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1442 1442 files=files)
1443 1443 finally:
1444 1444 files = patch.updatedir(ui, repo, files)
1445 1445 n = repo.commit(files, message, user, date)
1446 1446 if opts.get('exact'):
1447 1447 if hex(n) != nodeid:
1448 1448 repo.rollback()
1449 1449 raise util.Abort(_('patch is damaged'
1450 1450 ' or loses information'))
1451 1451 finally:
1452 1452 os.unlink(tmpname)
1453 1453 finally:
1454 1454 del lock, wlock
1455 1455
1456 1456 def incoming(ui, repo, source="default", **opts):
1457 1457 """show new changesets found in source
1458 1458
1459 1459 Show new changesets found in the specified path/URL or the default
1460 1460 pull location. These are the changesets that would be pulled if a pull
1461 1461 was requested.
1462 1462
1463 1463 For remote repository, using --bundle avoids downloading the changesets
1464 1464 twice if the incoming is followed by a pull.
1465 1465
1466 1466 See pull for valid source format details.
1467 1467 """
1468 1468 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1469 1469 cmdutil.setremoteconfig(ui, opts)
1470 1470
1471 1471 other = hg.repository(ui, source)
1472 1472 ui.status(_('comparing with %s\n') % util.hidepassword(source))
1473 1473 if revs:
1474 1474 revs = [other.lookup(rev) for rev in revs]
1475 1475 incoming = repo.findincoming(other, heads=revs, force=opts["force"])
1476 1476 if not incoming:
1477 1477 try:
1478 1478 os.unlink(opts["bundle"])
1479 1479 except:
1480 1480 pass
1481 1481 ui.status(_("no changes found\n"))
1482 1482 return 1
1483 1483
1484 1484 cleanup = None
1485 1485 try:
1486 1486 fname = opts["bundle"]
1487 1487 if fname or not other.local():
1488 1488 # create a bundle (uncompressed if other repo is not local)
1489 1489 if revs is None:
1490 1490 cg = other.changegroup(incoming, "incoming")
1491 1491 else:
1492 1492 cg = other.changegroupsubset(incoming, revs, 'incoming')
1493 1493 bundletype = other.local() and "HG10BZ" or "HG10UN"
1494 1494 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1495 1495 # keep written bundle?
1496 1496 if opts["bundle"]:
1497 1497 cleanup = None
1498 1498 if not other.local():
1499 1499 # use the created uncompressed bundlerepo
1500 1500 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1501 1501
1502 1502 o = other.changelog.nodesbetween(incoming, revs)[0]
1503 1503 if opts['newest_first']:
1504 1504 o.reverse()
1505 1505 displayer = cmdutil.show_changeset(ui, other, opts)
1506 1506 for n in o:
1507 1507 parents = [p for p in other.changelog.parents(n) if p != nullid]
1508 1508 if opts['no_merges'] and len(parents) == 2:
1509 1509 continue
1510 1510 displayer.show(changenode=n)
1511 1511 finally:
1512 1512 if hasattr(other, 'close'):
1513 1513 other.close()
1514 1514 if cleanup:
1515 1515 os.unlink(cleanup)
1516 1516
1517 1517 def init(ui, dest=".", **opts):
1518 1518 """create a new repository in the given directory
1519 1519
1520 1520 Initialize a new repository in the given directory. If the given
1521 1521 directory does not exist, it is created.
1522 1522
1523 1523 If no directory is given, the current directory is used.
1524 1524
1525 1525 It is possible to specify an ssh:// URL as the destination.
1526 1526 Look at the help text for the pull command for important details
1527 1527 about ssh:// URLs.
1528 1528 """
1529 1529 cmdutil.setremoteconfig(ui, opts)
1530 1530 hg.repository(ui, dest, create=1)
1531 1531
1532 1532 def locate(ui, repo, *pats, **opts):
1533 1533 """locate files matching specific patterns
1534 1534
1535 1535 Print all files under Mercurial control whose names match the
1536 1536 given patterns.
1537 1537
1538 1538 This command searches the entire repository by default. To search
1539 1539 just the current directory and its subdirectories, use
1540 1540 "--include .".
1541 1541
1542 1542 If no patterns are given to match, this command prints all file
1543 1543 names.
1544 1544
1545 1545 If you want to feed the output of this command into the "xargs"
1546 1546 command, use the "-0" option to both this command and "xargs".
1547 1547 This will avoid the problem of "xargs" treating single filenames
1548 1548 that contain white space as multiple filenames.
1549 1549 """
1550 1550 end = opts['print0'] and '\0' or '\n'
1551 1551 rev = opts['rev']
1552 1552 if rev:
1553 1553 node = repo.lookup(rev)
1554 1554 else:
1555 1555 node = None
1556 1556
1557 1557 ret = 1
1558 1558 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1559 1559 badmatch=util.always,
1560 1560 default='relglob'):
1561 1561 if src == 'b':
1562 1562 continue
1563 1563 if not node and abs not in repo.dirstate:
1564 1564 continue
1565 1565 if opts['fullpath']:
1566 1566 ui.write(os.path.join(repo.root, abs), end)
1567 1567 else:
1568 1568 ui.write(((pats and rel) or abs), end)
1569 1569 ret = 0
1570 1570
1571 1571 return ret
1572 1572
1573 1573 def log(ui, repo, *pats, **opts):
1574 1574 """show revision history of entire repository or files
1575 1575
1576 1576 Print the revision history of the specified files or the entire
1577 1577 project.
1578 1578
1579 1579 File history is shown without following rename or copy history of
1580 1580 files. Use -f/--follow with a file name to follow history across
1581 1581 renames and copies. --follow without a file name will only show
1582 1582 ancestors or descendants of the starting revision. --follow-first
1583 1583 only follows the first parent of merge revisions.
1584 1584
1585 1585 If no revision range is specified, the default is tip:0 unless
1586 1586 --follow is set, in which case the working directory parent is
1587 1587 used as the starting revision.
1588 1588
1589 1589 By default this command outputs: changeset id and hash, tags,
1590 1590 non-trivial parents, user, date and time, and a summary for each
1591 1591 commit. When the -v/--verbose switch is used, the list of changed
1592 1592 files and full commit message is shown.
1593 1593
1594 1594 NOTE: log -p may generate unexpected diff output for merge
1595 1595 changesets, as it will compare the merge changeset against its
1596 1596 first parent only. Also, the files: list will only reflect files
1597 1597 that are different from BOTH parents.
1598 1598
1599 1599 """
1600 1600
1601 1601 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1602 1602 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1603 1603
1604 1604 if opts['limit']:
1605 1605 try:
1606 1606 limit = int(opts['limit'])
1607 1607 except ValueError:
1608 1608 raise util.Abort(_('limit must be a positive integer'))
1609 1609 if limit <= 0: raise util.Abort(_('limit must be positive'))
1610 1610 else:
1611 1611 limit = sys.maxint
1612 1612 count = 0
1613 1613
1614 1614 if opts['copies'] and opts['rev']:
1615 1615 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1616 1616 else:
1617 1617 endrev = repo.changelog.count()
1618 1618 rcache = {}
1619 1619 ncache = {}
1620 1620 dcache = []
1621 1621 def getrenamed(fn, rev, man):
1622 1622 '''looks up all renames for a file (up to endrev) the first
1623 1623 time the file is given. It indexes on the changerev and only
1624 1624 parses the manifest if linkrev != changerev.
1625 1625 Returns rename info for fn at changerev rev.'''
1626 1626 if fn not in rcache:
1627 1627 rcache[fn] = {}
1628 1628 ncache[fn] = {}
1629 1629 fl = repo.file(fn)
1630 1630 for i in xrange(fl.count()):
1631 1631 node = fl.node(i)
1632 1632 lr = fl.linkrev(node)
1633 1633 renamed = fl.renamed(node)
1634 1634 rcache[fn][lr] = renamed
1635 1635 if renamed:
1636 1636 ncache[fn][node] = renamed
1637 1637 if lr >= endrev:
1638 1638 break
1639 1639 if rev in rcache[fn]:
1640 1640 return rcache[fn][rev]
1641 1641 mr = repo.manifest.rev(man)
1642 1642 if repo.manifest.parentrevs(mr) != (mr - 1, nullrev):
1643 1643 return ncache[fn].get(repo.manifest.find(man, fn)[0])
1644 1644 if not dcache or dcache[0] != man:
1645 1645 dcache[:] = [man, repo.manifest.readdelta(man)]
1646 1646 if fn in dcache[1]:
1647 1647 return ncache[fn].get(dcache[1][fn])
1648 1648 return None
1649 1649
1650 1650 df = False
1651 1651 if opts["date"]:
1652 1652 df = util.matchdate(opts["date"])
1653 1653
1654 1654 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
1655 1655 for st, rev, fns in changeiter:
1656 1656 if st == 'add':
1657 1657 changenode = repo.changelog.node(rev)
1658 1658 parents = [p for p in repo.changelog.parentrevs(rev)
1659 1659 if p != nullrev]
1660 1660 if opts['no_merges'] and len(parents) == 2:
1661 1661 continue
1662 1662 if opts['only_merges'] and len(parents) != 2:
1663 1663 continue
1664 1664
1665 1665 if df:
1666 1666 changes = get(rev)
1667 1667 if not df(changes[2][0]):
1668 1668 continue
1669 1669
1670 1670 if opts['keyword']:
1671 1671 changes = get(rev)
1672 1672 miss = 0
1673 1673 for k in [kw.lower() for kw in opts['keyword']]:
1674 1674 if not (k in changes[1].lower() or
1675 1675 k in changes[4].lower() or
1676 1676 k in " ".join(changes[3]).lower()):
1677 1677 miss = 1
1678 1678 break
1679 1679 if miss:
1680 1680 continue
1681 1681
1682 1682 copies = []
1683 1683 if opts.get('copies') and rev:
1684 1684 mf = get(rev)[0]
1685 1685 for fn in get(rev)[3]:
1686 1686 rename = getrenamed(fn, rev, mf)
1687 1687 if rename:
1688 1688 copies.append((fn, rename[0]))
1689 1689 displayer.show(rev, changenode, copies=copies)
1690 1690 elif st == 'iter':
1691 1691 if count == limit: break
1692 1692 if displayer.flush(rev):
1693 1693 count += 1
1694 1694
1695 1695 def manifest(ui, repo, node=None, rev=None):
1696 1696 """output the current or given revision of the project manifest
1697 1697
1698 1698 Print a list of version controlled files for the given revision.
1699 1699 If no revision is given, the parent of the working directory is used,
1700 1700 or tip if no revision is checked out.
1701 1701
1702 1702 The manifest is the list of files being version controlled. If no revision
1703 1703 is given then the first parent of the working directory is used.
1704 1704
1705 1705 With -v flag, print file permissions, symlink and executable bits. With
1706 1706 --debug flag, print file revision hashes.
1707 1707 """
1708 1708
1709 1709 if rev and node:
1710 1710 raise util.Abort(_("please specify just one revision"))
1711 1711
1712 1712 if not node:
1713 1713 node = rev
1714 1714
1715 1715 m = repo.changectx(node).manifest()
1716 1716 files = m.keys()
1717 1717 files.sort()
1718 1718
1719 1719 for f in files:
1720 1720 if ui.debugflag:
1721 1721 ui.write("%40s " % hex(m[f]))
1722 1722 if ui.verbose:
1723 1723 type = m.execf(f) and "*" or m.linkf(f) and "@" or " "
1724 1724 perm = m.execf(f) and "755" or "644"
1725 1725 ui.write("%3s %1s " % (perm, type))
1726 1726 ui.write("%s\n" % f)
1727 1727
1728 1728 def merge(ui, repo, node=None, force=None, rev=None):
1729 1729 """merge working directory with another revision
1730 1730
1731 1731 Merge the contents of the current working directory and the
1732 1732 requested revision. Files that changed between either parent are
1733 1733 marked as changed for the next commit and a commit must be
1734 1734 performed before any further updates are allowed.
1735 1735
1736 1736 If no revision is specified, the working directory's parent is a
1737 1737 head revision, and the repository contains exactly one other head,
1738 1738 the other head is merged with by default. Otherwise, an explicit
1739 1739 revision to merge with must be provided.
1740 1740 """
1741 1741
1742 1742 if rev and node:
1743 1743 raise util.Abort(_("please specify just one revision"))
1744 1744 if not node:
1745 1745 node = rev
1746 1746
1747 1747 if not node:
1748 1748 heads = repo.heads()
1749 1749 if len(heads) > 2:
1750 1750 raise util.Abort(_('repo has %d heads - '
1751 1751 'please merge with an explicit rev') %
1752 1752 len(heads))
1753 1753 parent = repo.dirstate.parents()[0]
1754 1754 if len(heads) == 1:
1755 1755 msg = _('there is nothing to merge')
1756 1756 if parent != repo.lookup(repo.workingctx().branch()):
1757 1757 msg = _('%s - use "hg update" instead') % msg
1758 1758 raise util.Abort(msg)
1759 1759
1760 1760 if parent not in heads:
1761 1761 raise util.Abort(_('working dir not at a head rev - '
1762 1762 'use "hg update" or merge with an explicit rev'))
1763 1763 node = parent == heads[0] and heads[-1] or heads[0]
1764 1764 return hg.merge(repo, node, force=force)
1765 1765
1766 1766 def outgoing(ui, repo, dest=None, **opts):
1767 1767 """show changesets not found in destination
1768 1768
1769 1769 Show changesets not found in the specified destination repository or
1770 1770 the default push location. These are the changesets that would be pushed
1771 1771 if a push was requested.
1772 1772
1773 1773 See pull for valid destination format details.
1774 1774 """
1775 1775 dest, revs, checkout = hg.parseurl(
1776 1776 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1777 1777 cmdutil.setremoteconfig(ui, opts)
1778 1778 if revs:
1779 1779 revs = [repo.lookup(rev) for rev in revs]
1780 1780
1781 1781 other = hg.repository(ui, dest)
1782 1782 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1783 1783 o = repo.findoutgoing(other, force=opts['force'])
1784 1784 if not o:
1785 1785 ui.status(_("no changes found\n"))
1786 1786 return 1
1787 1787 o = repo.changelog.nodesbetween(o, revs)[0]
1788 1788 if opts['newest_first']:
1789 1789 o.reverse()
1790 1790 displayer = cmdutil.show_changeset(ui, repo, opts)
1791 1791 for n in o:
1792 1792 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1793 1793 if opts['no_merges'] and len(parents) == 2:
1794 1794 continue
1795 1795 displayer.show(changenode=n)
1796 1796
1797 1797 def parents(ui, repo, file_=None, **opts):
1798 1798 """show the parents of the working dir or revision
1799 1799
1800 1800 Print the working directory's parent revisions. If a
1801 1801 revision is given via --rev, the parent of that revision
1802 1802 will be printed. If a file argument is given, revision in
1803 1803 which the file was last changed (before the working directory
1804 1804 revision or the argument to --rev if given) is printed.
1805 1805 """
1806 1806 rev = opts.get('rev')
1807 1807 if rev:
1808 1808 ctx = repo.changectx(rev)
1809 1809 else:
1810 1810 ctx = repo.workingctx()
1811 1811
1812 1812 if file_:
1813 1813 files, match, anypats = cmdutil.matchpats(repo, (file_,), opts)
1814 1814 if anypats or len(files) != 1:
1815 1815 raise util.Abort(_('can only specify an explicit file name'))
1816 1816 file_ = files[0]
1817 1817 filenodes = []
1818 1818 for cp in ctx.parents():
1819 1819 if not cp:
1820 1820 continue
1821 1821 try:
1822 1822 filenodes.append(cp.filenode(file_))
1823 1823 except revlog.LookupError:
1824 1824 pass
1825 1825 if not filenodes:
1826 1826 raise util.Abort(_("'%s' not found in manifest!") % file_)
1827 1827 fl = repo.file(file_)
1828 1828 p = [repo.lookup(fl.linkrev(fn)) for fn in filenodes]
1829 1829 else:
1830 1830 p = [cp.node() for cp in ctx.parents()]
1831 1831
1832 1832 displayer = cmdutil.show_changeset(ui, repo, opts)
1833 1833 for n in p:
1834 1834 if n != nullid:
1835 1835 displayer.show(changenode=n)
1836 1836
1837 1837 def paths(ui, repo, search=None):
1838 1838 """show definition of symbolic path names
1839 1839
1840 1840 Show definition of symbolic path name NAME. If no name is given, show
1841 1841 definition of available names.
1842 1842
1843 1843 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1844 1844 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1845 1845 """
1846 1846 if search:
1847 1847 for name, path in ui.configitems("paths"):
1848 1848 if name == search:
1849 1849 ui.write("%s\n" % path)
1850 1850 return
1851 1851 ui.warn(_("not found!\n"))
1852 1852 return 1
1853 1853 else:
1854 1854 for name, path in ui.configitems("paths"):
1855 1855 ui.write("%s = %s\n" % (name, path))
1856 1856
1857 1857 def postincoming(ui, repo, modheads, optupdate, checkout):
1858 1858 if modheads == 0:
1859 1859 return
1860 1860 if optupdate:
1861 1861 if modheads <= 1 or checkout:
1862 1862 return hg.update(repo, checkout)
1863 1863 else:
1864 1864 ui.status(_("not updating, since new heads added\n"))
1865 1865 if modheads > 1:
1866 1866 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1867 1867 else:
1868 1868 ui.status(_("(run 'hg update' to get a working copy)\n"))
1869 1869
1870 1870 def pull(ui, repo, source="default", **opts):
1871 1871 """pull changes from the specified source
1872 1872
1873 1873 Pull changes from a remote repository to a local one.
1874 1874
1875 1875 This finds all changes from the repository at the specified path
1876 1876 or URL and adds them to the local repository. By default, this
1877 1877 does not update the copy of the project in the working directory.
1878 1878
1879 1879 Valid URLs are of the form:
1880 1880
1881 1881 local/filesystem/path (or file://local/filesystem/path)
1882 1882 http://[user@]host[:port]/[path]
1883 1883 https://[user@]host[:port]/[path]
1884 1884 ssh://[user@]host[:port]/[path]
1885 1885 static-http://host[:port]/[path]
1886 1886
1887 1887 Paths in the local filesystem can either point to Mercurial
1888 1888 repositories or to bundle files (as created by 'hg bundle' or
1889 1889 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1890 1890 allows access to a Mercurial repository where you simply use a web
1891 1891 server to publish the .hg directory as static content.
1892 1892
1893 1893 An optional identifier after # indicates a particular branch, tag,
1894 1894 or changeset to pull.
1895 1895
1896 1896 Some notes about using SSH with Mercurial:
1897 1897 - SSH requires an accessible shell account on the destination machine
1898 1898 and a copy of hg in the remote path or specified with as remotecmd.
1899 1899 - path is relative to the remote user's home directory by default.
1900 1900 Use an extra slash at the start of a path to specify an absolute path:
1901 1901 ssh://example.com//tmp/repository
1902 1902 - Mercurial doesn't use its own compression via SSH; the right thing
1903 1903 to do is to configure it in your ~/.ssh/config, e.g.:
1904 1904 Host *.mylocalnetwork.example.com
1905 1905 Compression no
1906 1906 Host *
1907 1907 Compression yes
1908 1908 Alternatively specify "ssh -C" as your ssh command in your hgrc or
1909 1909 with the --ssh command line option.
1910 1910 """
1911 1911 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1912 1912 cmdutil.setremoteconfig(ui, opts)
1913 1913
1914 1914 other = hg.repository(ui, source)
1915 1915 ui.status(_('pulling from %s\n') % util.hidepassword(source))
1916 1916 if revs:
1917 1917 try:
1918 1918 revs = [other.lookup(rev) for rev in revs]
1919 1919 except repo.NoCapability:
1920 1920 error = _("Other repository doesn't support revision lookup, "
1921 1921 "so a rev cannot be specified.")
1922 1922 raise util.Abort(error)
1923 1923
1924 1924 modheads = repo.pull(other, heads=revs, force=opts['force'])
1925 1925 return postincoming(ui, repo, modheads, opts['update'], checkout)
1926 1926
1927 1927 def push(ui, repo, dest=None, **opts):
1928 1928 """push changes to the specified destination
1929 1929
1930 1930 Push changes from the local repository to the given destination.
1931 1931
1932 1932 This is the symmetrical operation for pull. It helps to move
1933 1933 changes from the current repository to a different one. If the
1934 1934 destination is local this is identical to a pull in that directory
1935 1935 from the current one.
1936 1936
1937 1937 By default, push will refuse to run if it detects the result would
1938 1938 increase the number of remote heads. This generally indicates the
1939 1939 the client has forgotten to sync and merge before pushing.
1940 1940
1941 1941 Valid URLs are of the form:
1942 1942
1943 1943 local/filesystem/path (or file://local/filesystem/path)
1944 1944 ssh://[user@]host[:port]/[path]
1945 1945 http://[user@]host[:port]/[path]
1946 1946 https://[user@]host[:port]/[path]
1947 1947
1948 1948 An optional identifier after # indicates a particular branch, tag,
1949 1949 or changeset to push.
1950 1950
1951 1951 Look at the help text for the pull command for important details
1952 1952 about ssh:// URLs.
1953 1953
1954 1954 Pushing to http:// and https:// URLs is only possible, if this
1955 1955 feature is explicitly enabled on the remote Mercurial server.
1956 1956 """
1957 1957 dest, revs, checkout = hg.parseurl(
1958 1958 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1959 1959 cmdutil.setremoteconfig(ui, opts)
1960 1960
1961 1961 other = hg.repository(ui, dest)
1962 1962 ui.status('pushing to %s\n' % util.hidepassword(dest))
1963 1963 if revs:
1964 1964 revs = [repo.lookup(rev) for rev in revs]
1965 1965 r = repo.push(other, opts['force'], revs=revs)
1966 1966 return r == 0
1967 1967
1968 1968 def rawcommit(ui, repo, *pats, **opts):
1969 1969 """raw commit interface (DEPRECATED)
1970 1970
1971 1971 (DEPRECATED)
1972 1972 Lowlevel commit, for use in helper scripts.
1973 1973
1974 1974 This command is not intended to be used by normal users, as it is
1975 1975 primarily useful for importing from other SCMs.
1976 1976
1977 1977 This command is now deprecated and will be removed in a future
1978 1978 release, please use debugsetparents and commit instead.
1979 1979 """
1980 1980
1981 1981 ui.warn(_("(the rawcommit command is deprecated)\n"))
1982 1982
1983 1983 message = cmdutil.logmessage(opts)
1984 1984
1985 1985 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
1986 1986 if opts['files']:
1987 1987 files += open(opts['files']).read().splitlines()
1988 1988
1989 1989 parents = [repo.lookup(p) for p in opts['parent']]
1990 1990
1991 1991 try:
1992 1992 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
1993 1993 except ValueError, inst:
1994 1994 raise util.Abort(str(inst))
1995 1995
1996 1996 def recover(ui, repo):
1997 1997 """roll back an interrupted transaction
1998 1998
1999 1999 Recover from an interrupted commit or pull.
2000 2000
2001 2001 This command tries to fix the repository status after an interrupted
2002 2002 operation. It should only be necessary when Mercurial suggests it.
2003 2003 """
2004 2004 if repo.recover():
2005 2005 return hg.verify(repo)
2006 2006 return 1
2007 2007
2008 2008 def remove(ui, repo, *pats, **opts):
2009 2009 """remove the specified files on the next commit
2010 2010
2011 2011 Schedule the indicated files for removal from the repository.
2012 2012
2013 2013 This only removes files from the current branch, not from the
2014 2014 entire project history. If the files still exist in the working
2015 2015 directory, they will be deleted from it. If invoked with --after,
2016 2016 files are marked as removed, but not actually unlinked unless --force
2017 2017 is also given. Without exact file names, --after will only mark
2018 2018 files as removed if they are no longer in the working directory.
2019 2019
2020 2020 This command schedules the files to be removed at the next commit.
2021 2021 To undo a remove before that, see hg revert.
2022 2022
2023 2023 Modified files and added files are not removed by default. To
2024 2024 remove them, use the -f/--force option.
2025 2025 """
2026 2026 if not opts['after'] and not pats:
2027 2027 raise util.Abort(_('no files specified'))
2028 2028 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2029 2029 exact = dict.fromkeys(files)
2030 2030 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
2031 2031 modified, added, removed, deleted, unknown = mardu
2032 2032 remove, forget = [], []
2033 2033 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
2034 2034 reason = None
2035 2035 if abs in modified and not opts['force']:
2036 2036 reason = _('is modified (use -f to force removal)')
2037 2037 elif abs in added:
2038 2038 if opts['force']:
2039 2039 forget.append(abs)
2040 2040 continue
2041 2041 reason = _('has been marked for add (use -f to force removal)')
2042 2042 exact = 1 # force the message
2043 2043 elif abs not in repo.dirstate:
2044 2044 reason = _('is not managed')
2045 2045 elif opts['after'] and not exact and abs not in deleted:
2046 2046 continue
2047 2047 elif abs in removed:
2048 2048 continue
2049 2049 if reason:
2050 2050 if exact:
2051 2051 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2052 2052 else:
2053 2053 if ui.verbose or not exact:
2054 2054 ui.status(_('removing %s\n') % rel)
2055 2055 remove.append(abs)
2056 2056 repo.forget(forget)
2057 2057 repo.remove(remove, unlink=opts['force'] or not opts['after'])
2058 2058
2059 2059 def rename(ui, repo, *pats, **opts):
2060 2060 """rename files; equivalent of copy + remove
2061 2061
2062 2062 Mark dest as copies of sources; mark sources for deletion. If
2063 2063 dest is a directory, copies are put in that directory. If dest is
2064 2064 a file, there can only be one source.
2065 2065
2066 2066 By default, this command copies the contents of files as they
2067 2067 stand in the working directory. If invoked with --after, the
2068 2068 operation is recorded, but no copying is performed.
2069 2069
2070 2070 This command takes effect in the next commit. To undo a rename
2071 2071 before that, see hg revert.
2072 2072 """
2073 2073 wlock = repo.wlock(False)
2074 2074 try:
2075 2075 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2076 2076 finally:
2077 2077 del wlock
2078 2078
2079 2079 def revert(ui, repo, *pats, **opts):
2080 2080 """restore individual files or dirs to an earlier state
2081 2081
2082 2082 (use update -r to check out earlier revisions, revert does not
2083 2083 change the working dir parents)
2084 2084
2085 2085 With no revision specified, revert the named files or directories
2086 2086 to the contents they had in the parent of the working directory.
2087 2087 This restores the contents of the affected files to an unmodified
2088 2088 state and unschedules adds, removes, copies, and renames. If the
2089 2089 working directory has two parents, you must explicitly specify the
2090 2090 revision to revert to.
2091 2091
2092 2092 Using the -r option, revert the given files or directories to their
2093 2093 contents as of a specific revision. This can be helpful to "roll
2094 2094 back" some or all of an earlier change.
2095 2095
2096 2096 Revert modifies the working directory. It does not commit any
2097 2097 changes, or change the parent of the working directory. If you
2098 2098 revert to a revision other than the parent of the working
2099 2099 directory, the reverted files will thus appear modified
2100 2100 afterwards.
2101 2101
2102 2102 If a file has been deleted, it is restored. If the executable
2103 2103 mode of a file was changed, it is reset.
2104 2104
2105 2105 If names are given, all files matching the names are reverted.
2106 2106
2107 2107 If no arguments are given, no files are reverted.
2108 2108
2109 2109 Modified files are saved with a .orig suffix before reverting.
2110 2110 To disable these backups, use --no-backup.
2111 2111 """
2112 2112
2113 2113 if opts["date"]:
2114 2114 if opts["rev"]:
2115 2115 raise util.Abort(_("you can't specify a revision and a date"))
2116 2116 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2117 2117
2118 2118 if not pats and not opts['all']:
2119 2119 raise util.Abort(_('no files or directories specified; '
2120 2120 'use --all to revert the whole repo'))
2121 2121
2122 2122 parent, p2 = repo.dirstate.parents()
2123 2123 if not opts['rev'] and p2 != nullid:
2124 2124 raise util.Abort(_('uncommitted merge - please provide a '
2125 2125 'specific revision'))
2126 2126 ctx = repo.changectx(opts['rev'])
2127 2127 node = ctx.node()
2128 2128 mf = ctx.manifest()
2129 2129 if node == parent:
2130 2130 pmf = mf
2131 2131 else:
2132 2132 pmf = None
2133 2133
2134 2134 # need all matching names in dirstate and manifest of target rev,
2135 2135 # so have to walk both. do not print errors if files exist in one
2136 2136 # but not other.
2137 2137
2138 2138 names = {}
2139 2139 target_only = {}
2140 2140
2141 2141 wlock = repo.wlock()
2142 2142 try:
2143 2143 # walk dirstate.
2144 2144 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2145 2145 badmatch=mf.has_key):
2146 2146 names[abs] = (rel, exact)
2147 2147 if src == 'b':
2148 2148 target_only[abs] = True
2149 2149
2150 2150 # walk target manifest.
2151 2151
2152 2152 def badmatch(path):
2153 2153 if path in names:
2154 2154 return True
2155 2155 path_ = path + '/'
2156 2156 for f in names:
2157 2157 if f.startswith(path_):
2158 2158 return True
2159 2159 return False
2160 2160
2161 2161 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2162 2162 badmatch=badmatch):
2163 2163 if abs in names or src == 'b':
2164 2164 continue
2165 2165 names[abs] = (rel, exact)
2166 2166 target_only[abs] = True
2167 2167
2168 2168 changes = repo.status(match=names.has_key)[:5]
2169 2169 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2170 2170
2171 2171 # if f is a rename, also revert the source
2172 2172 cwd = repo.getcwd()
2173 2173 for f in added:
2174 2174 src = repo.dirstate.copied(f)
2175 2175 if src and src not in names and repo.dirstate[src] == 'r':
2176 2176 removed[src] = None
2177 2177 names[src] = (repo.pathto(src, cwd), True)
2178 2178
2179 2179 revert = ([], _('reverting %s\n'))
2180 2180 add = ([], _('adding %s\n'))
2181 2181 remove = ([], _('removing %s\n'))
2182 2182 forget = ([], _('forgetting %s\n'))
2183 2183 undelete = ([], _('undeleting %s\n'))
2184 2184 update = {}
2185 2185
2186 2186 disptable = (
2187 2187 # dispatch table:
2188 2188 # file state
2189 2189 # action if in target manifest
2190 2190 # action if not in target manifest
2191 2191 # make backup if in target manifest
2192 2192 # make backup if not in target manifest
2193 2193 (modified, revert, remove, True, True),
2194 2194 (added, revert, forget, True, False),
2195 2195 (removed, undelete, None, False, False),
2196 2196 (deleted, revert, remove, False, False),
2197 2197 (unknown, add, None, True, False),
2198 2198 (target_only, add, None, False, False),
2199 2199 )
2200 2200
2201 2201 entries = names.items()
2202 2202 entries.sort()
2203 2203
2204 2204 for abs, (rel, exact) in entries:
2205 2205 mfentry = mf.get(abs)
2206 2206 target = repo.wjoin(abs)
2207 2207 def handle(xlist, dobackup):
2208 2208 xlist[0].append(abs)
2209 2209 update[abs] = 1
2210 2210 if dobackup and not opts['no_backup'] and util.lexists(target):
2211 2211 bakname = "%s.orig" % rel
2212 2212 ui.note(_('saving current version of %s as %s\n') %
2213 2213 (rel, bakname))
2214 2214 if not opts.get('dry_run'):
2215 2215 util.copyfile(target, bakname)
2216 2216 if ui.verbose or not exact:
2217 2217 ui.status(xlist[1] % rel)
2218 2218 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2219 2219 if abs not in table: continue
2220 2220 # file has changed in dirstate
2221 2221 if mfentry:
2222 2222 handle(hitlist, backuphit)
2223 2223 elif misslist is not None:
2224 2224 handle(misslist, backupmiss)
2225 2225 else:
2226 2226 if exact: ui.warn(_('file not managed: %s\n') % rel)
2227 2227 break
2228 2228 else:
2229 2229 # file has not changed in dirstate
2230 2230 if node == parent:
2231 2231 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2232 2232 continue
2233 2233 if pmf is None:
2234 2234 # only need parent manifest in this unlikely case,
2235 2235 # so do not read by default
2236 2236 pmf = repo.changectx(parent).manifest()
2237 2237 if abs in pmf:
2238 2238 if mfentry:
2239 2239 # if version of file is same in parent and target
2240 2240 # manifests, do nothing
2241 2241 if pmf[abs] != mfentry:
2242 2242 handle(revert, False)
2243 2243 else:
2244 2244 handle(remove, False)
2245 2245
2246 2246 if not opts.get('dry_run'):
2247 2247 for f in forget[0]:
2248 2248 repo.dirstate.forget(f)
2249 2249 r = hg.revert(repo, node, update.has_key)
2250 2250 for f in add[0]:
2251 2251 repo.dirstate.add(f)
2252 2252 for f in undelete[0]:
2253 2253 repo.dirstate.normal(f)
2254 2254 for f in remove[0]:
2255 2255 repo.dirstate.remove(f)
2256 2256 return r
2257 2257 finally:
2258 2258 del wlock
2259 2259
2260 2260 def rollback(ui, repo):
2261 2261 """roll back the last transaction
2262 2262
2263 2263 This command should be used with care. There is only one level of
2264 2264 rollback, and there is no way to undo a rollback. It will also
2265 2265 restore the dirstate at the time of the last transaction, losing
2266 2266 any dirstate changes since that time.
2267 2267
2268 2268 Transactions are used to encapsulate the effects of all commands
2269 2269 that create new changesets or propagate existing changesets into a
2270 2270 repository. For example, the following commands are transactional,
2271 2271 and their effects can be rolled back:
2272 2272
2273 2273 commit
2274 2274 import
2275 2275 pull
2276 2276 push (with this repository as destination)
2277 2277 unbundle
2278 2278
2279 2279 This command is not intended for use on public repositories. Once
2280 2280 changes are visible for pull by other users, rolling a transaction
2281 2281 back locally is ineffective (someone else may already have pulled
2282 2282 the changes). Furthermore, a race is possible with readers of the
2283 2283 repository; for example an in-progress pull from the repository
2284 2284 may fail if a rollback is performed.
2285 2285 """
2286 2286 repo.rollback()
2287 2287
2288 2288 def root(ui, repo):
2289 2289 """print the root (top) of the current working dir
2290 2290
2291 2291 Print the root directory of the current repository.
2292 2292 """
2293 2293 ui.write(repo.root + "\n")
2294 2294
2295 2295 def serve(ui, repo, **opts):
2296 2296 """export the repository via HTTP
2297 2297
2298 2298 Start a local HTTP repository browser and pull server.
2299 2299
2300 2300 By default, the server logs accesses to stdout and errors to
2301 2301 stderr. Use the "-A" and "-E" options to log to files.
2302 2302 """
2303 2303
2304 2304 if opts["stdio"]:
2305 2305 if repo is None:
2306 2306 raise hg.RepoError(_("There is no Mercurial repository here"
2307 2307 " (.hg not found)"))
2308 2308 s = sshserver.sshserver(ui, repo)
2309 2309 s.serve_forever()
2310 2310
2311 2311 parentui = ui.parentui or ui
2312 2312 optlist = ("name templates style address port ipv6"
2313 2313 " accesslog errorlog webdir_conf certificate")
2314 2314 for o in optlist.split():
2315 2315 if opts[o]:
2316 2316 parentui.setconfig("web", o, str(opts[o]))
2317 2317 if (repo is not None) and (repo.ui != parentui):
2318 2318 repo.ui.setconfig("web", o, str(opts[o]))
2319 2319
2320 2320 if repo is None and not ui.config("web", "webdir_conf"):
2321 2321 raise hg.RepoError(_("There is no Mercurial repository here"
2322 2322 " (.hg not found)"))
2323 2323
2324 2324 class service:
2325 2325 def init(self):
2326 2326 util.set_signal_handler()
2327 2327 try:
2328 2328 self.httpd = hgweb.server.create_server(parentui, repo)
2329 2329 except socket.error, inst:
2330 2330 raise util.Abort(_('cannot start server: ') + inst.args[1])
2331 2331
2332 2332 if not ui.verbose: return
2333 2333
2334 2334 if self.httpd.port != 80:
2335 2335 ui.status(_('listening at http://%s:%d/\n') %
2336 2336 (self.httpd.addr, self.httpd.port))
2337 2337 else:
2338 2338 ui.status(_('listening at http://%s/\n') % self.httpd.addr)
2339 2339
2340 2340 def run(self):
2341 2341 self.httpd.serve_forever()
2342 2342
2343 2343 service = service()
2344 2344
2345 2345 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2346 2346
2347 2347 def status(ui, repo, *pats, **opts):
2348 2348 """show changed files in the working directory
2349 2349
2350 2350 Show status of files in the repository. If names are given, only
2351 2351 files that match are shown. Files that are clean or ignored, are
2352 2352 not listed unless -c (clean), -i (ignored) or -A is given.
2353 2353
2354 2354 NOTE: status may appear to disagree with diff if permissions have
2355 2355 changed or a merge has occurred. The standard diff format does not
2356 2356 report permission changes and diff only reports changes relative
2357 2357 to one merge parent.
2358 2358
2359 2359 If one revision is given, it is used as the base revision.
2360 2360 If two revisions are given, the difference between them is shown.
2361 2361
2362 2362 The codes used to show the status of files are:
2363 2363 M = modified
2364 2364 A = added
2365 2365 R = removed
2366 C = clean
2366 = = clean
2367 2367 ! = deleted, but still tracked
2368 2368 ? = not tracked
2369 2369 I = ignored (not shown by default)
2370 2370 = the previous added file was copied from here
2371 2371 """
2372 2372
2373 2373 all = opts['all']
2374 2374 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2375 2375
2376 2376 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2377 2377 cwd = (pats and repo.getcwd()) or ''
2378 2378 modified, added, removed, deleted, unknown, ignored, clean = [
2379 2379 n for n in repo.status(node1=node1, node2=node2, files=files,
2380 2380 match=matchfn,
2381 2381 list_ignored=all or opts['ignored'],
2382 2382 list_clean=all or opts['clean'])]
2383 2383
2384 2384 changetypes = (('modified', 'M', modified),
2385 2385 ('added', 'A', added),
2386 2386 ('removed', 'R', removed),
2387 2387 ('deleted', '!', deleted),
2388 2388 ('unknown', '?', unknown),
2389 2389 ('ignored', 'I', ignored))
2390 2390
2391 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2391 explicit_changetypes = changetypes + (('clean', '=', clean),)
2392 2392
2393 2393 end = opts['print0'] and '\0' or '\n'
2394 2394
2395 2395 for opt, char, changes in ([ct for ct in explicit_changetypes
2396 2396 if all or opts[ct[0]]]
2397 2397 or changetypes):
2398 2398 if opts['no_status']:
2399 2399 format = "%%s%s" % end
2400 2400 else:
2401 2401 format = "%s %%s%s" % (char, end)
2402 2402
2403 2403 for f in changes:
2404 2404 ui.write(format % repo.pathto(f, cwd))
2405 2405 if ((all or opts.get('copies')) and not opts.get('no_status')):
2406 2406 copied = repo.dirstate.copied(f)
2407 2407 if copied:
2408 2408 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2409 2409
2410 2410 def tag(ui, repo, name, rev_=None, **opts):
2411 2411 """add a tag for the current or given revision
2412 2412
2413 2413 Name a particular revision using <name>.
2414 2414
2415 2415 Tags are used to name particular revisions of the repository and are
2416 2416 very useful to compare different revision, to go back to significant
2417 2417 earlier versions or to mark branch points as releases, etc.
2418 2418
2419 2419 If no revision is given, the parent of the working directory is used,
2420 2420 or tip if no revision is checked out.
2421 2421
2422 2422 To facilitate version control, distribution, and merging of tags,
2423 2423 they are stored as a file named ".hgtags" which is managed
2424 2424 similarly to other project files and can be hand-edited if
2425 2425 necessary. The file '.hg/localtags' is used for local tags (not
2426 2426 shared among repositories).
2427 2427 """
2428 2428 if name in ['tip', '.', 'null']:
2429 2429 raise util.Abort(_("the name '%s' is reserved") % name)
2430 2430 if rev_ is not None:
2431 2431 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2432 2432 "please use 'hg tag [-r REV] NAME' instead\n"))
2433 2433 if opts['rev']:
2434 2434 raise util.Abort(_("use only one form to specify the revision"))
2435 2435 if opts['rev'] and opts['remove']:
2436 2436 raise util.Abort(_("--rev and --remove are incompatible"))
2437 2437 if opts['rev']:
2438 2438 rev_ = opts['rev']
2439 2439 message = opts['message']
2440 2440 if opts['remove']:
2441 2441 tagtype = repo.tagtype(name)
2442 2442
2443 2443 if not tagtype:
2444 2444 raise util.Abort(_('tag %s does not exist') % name)
2445 2445 if opts['local'] and tagtype == 'global':
2446 2446 raise util.Abort(_('%s tag is global') % name)
2447 2447 if not opts['local'] and tagtype == 'local':
2448 2448 raise util.Abort(_('%s tag is local') % name)
2449 2449
2450 2450 rev_ = nullid
2451 2451 if not message:
2452 2452 message = _('Removed tag %s') % name
2453 2453 elif name in repo.tags() and not opts['force']:
2454 2454 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2455 2455 % name)
2456 2456 if not rev_ and repo.dirstate.parents()[1] != nullid:
2457 2457 raise util.Abort(_('uncommitted merge - please provide a '
2458 2458 'specific revision'))
2459 2459 r = repo.changectx(rev_).node()
2460 2460
2461 2461 if not message:
2462 2462 message = _('Added tag %s for changeset %s') % (name, short(r))
2463 2463
2464 2464 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2465 2465
2466 2466 def tags(ui, repo):
2467 2467 """list repository tags
2468 2468
2469 2469 List the repository tags.
2470 2470
2471 2471 This lists both regular and local tags. When the -v/--verbose switch
2472 2472 is used, a third column "local" is printed for local tags.
2473 2473 """
2474 2474
2475 2475 l = repo.tagslist()
2476 2476 l.reverse()
2477 2477 hexfunc = ui.debugflag and hex or short
2478 2478 tagtype = ""
2479 2479
2480 2480 for t, n in l:
2481 2481 if ui.quiet:
2482 2482 ui.write("%s\n" % t)
2483 2483 continue
2484 2484
2485 2485 try:
2486 2486 hn = hexfunc(n)
2487 2487 r = "%5d:%s" % (repo.changelog.rev(n), hn)
2488 2488 except revlog.LookupError:
2489 2489 r = " ?:%s" % hn
2490 2490 else:
2491 2491 spaces = " " * (30 - util.locallen(t))
2492 2492 if ui.verbose:
2493 2493 if repo.tagtype(t) == 'local':
2494 2494 tagtype = " local"
2495 2495 else:
2496 2496 tagtype = ""
2497 2497 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
2498 2498
2499 2499 def tip(ui, repo, **opts):
2500 2500 """show the tip revision
2501 2501
2502 2502 Show the tip revision.
2503 2503 """
2504 2504 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2505 2505
2506 2506 def unbundle(ui, repo, fname1, *fnames, **opts):
2507 2507 """apply one or more changegroup files
2508 2508
2509 2509 Apply one or more compressed changegroup files generated by the
2510 2510 bundle command.
2511 2511 """
2512 2512 fnames = (fname1,) + fnames
2513 2513 for fname in fnames:
2514 2514 if os.path.exists(fname):
2515 2515 f = open(fname, "rb")
2516 2516 else:
2517 2517 f = urllib.urlopen(fname)
2518 2518 gen = changegroup.readbundle(f, fname)
2519 2519 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2520 2520
2521 2521 return postincoming(ui, repo, modheads, opts['update'], None)
2522 2522
2523 2523 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2524 2524 """update working directory
2525 2525
2526 2526 Update the working directory to the specified revision, or the
2527 2527 tip of the current branch if none is specified.
2528 2528
2529 2529 If there are no outstanding changes in the working directory and
2530 2530 there is a linear relationship between the current version and the
2531 2531 requested version, the result is the requested version.
2532 2532
2533 2533 To merge the working directory with another revision, use the
2534 2534 merge command.
2535 2535
2536 2536 By default, update will refuse to run if doing so would require
2537 2537 discarding local changes.
2538 2538 """
2539 2539 if rev and node:
2540 2540 raise util.Abort(_("please specify just one revision"))
2541 2541
2542 2542 if not rev:
2543 2543 rev = node
2544 2544
2545 2545 if date:
2546 2546 if rev:
2547 2547 raise util.Abort(_("you can't specify a revision and a date"))
2548 2548 rev = cmdutil.finddate(ui, repo, date)
2549 2549
2550 2550 if clean:
2551 2551 return hg.clean(repo, rev)
2552 2552 else:
2553 2553 return hg.update(repo, rev)
2554 2554
2555 2555 def verify(ui, repo):
2556 2556 """verify the integrity of the repository
2557 2557
2558 2558 Verify the integrity of the current repository.
2559 2559
2560 2560 This will perform an extensive check of the repository's
2561 2561 integrity, validating the hashes and checksums of each entry in
2562 2562 the changelog, manifest, and tracked files, as well as the
2563 2563 integrity of their crosslinks and indices.
2564 2564 """
2565 2565 return hg.verify(repo)
2566 2566
2567 2567 def version_(ui):
2568 2568 """output version and copyright information"""
2569 2569 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2570 2570 % version.get_version())
2571 2571 ui.status(_(
2572 2572 "\nCopyright (C) 2005-2007 Matt Mackall <mpm@selenic.com> and others\n"
2573 2573 "This is free software; see the source for copying conditions. "
2574 2574 "There is NO\nwarranty; "
2575 2575 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2576 2576 ))
2577 2577
2578 2578 # Command options and aliases are listed here, alphabetically
2579 2579
2580 2580 globalopts = [
2581 2581 ('R', 'repository', '',
2582 2582 _('repository root directory or symbolic path name')),
2583 2583 ('', 'cwd', '', _('change working directory')),
2584 2584 ('y', 'noninteractive', None,
2585 2585 _('do not prompt, assume \'yes\' for any required answers')),
2586 2586 ('q', 'quiet', None, _('suppress output')),
2587 2587 ('v', 'verbose', None, _('enable additional output')),
2588 2588 ('', 'config', [], _('set/override config option')),
2589 2589 ('', 'debug', None, _('enable debugging output')),
2590 2590 ('', 'debugger', None, _('start debugger')),
2591 2591 ('', 'encoding', util._encoding, _('set the charset encoding')),
2592 2592 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2593 2593 ('', 'lsprof', None, _('print improved command execution profile')),
2594 2594 ('', 'traceback', None, _('print traceback on exception')),
2595 2595 ('', 'time', None, _('time how long the command takes')),
2596 2596 ('', 'profile', None, _('print command execution profile')),
2597 2597 ('', 'version', None, _('output version information and exit')),
2598 2598 ('h', 'help', None, _('display help and exit')),
2599 2599 ]
2600 2600
2601 2601 dryrunopts = [('n', 'dry-run', None,
2602 2602 _('do not perform actions, just print output'))]
2603 2603
2604 2604 remoteopts = [
2605 2605 ('e', 'ssh', '', _('specify ssh command to use')),
2606 2606 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2607 2607 ]
2608 2608
2609 2609 walkopts = [
2610 2610 ('I', 'include', [], _('include names matching the given patterns')),
2611 2611 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2612 2612 ]
2613 2613
2614 2614 commitopts = [
2615 2615 ('m', 'message', '', _('use <text> as commit message')),
2616 2616 ('l', 'logfile', '', _('read commit message from <file>')),
2617 2617 ]
2618 2618
2619 2619 commitopts2 = [
2620 2620 ('d', 'date', '', _('record datecode as commit date')),
2621 2621 ('u', 'user', '', _('record user as committer')),
2622 2622 ]
2623 2623
2624 2624 table = {
2625 2625 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2626 2626 "addremove":
2627 2627 (addremove,
2628 2628 [('s', 'similarity', '',
2629 2629 _('guess renamed files by similarity (0<=s<=100)')),
2630 2630 ] + walkopts + dryrunopts,
2631 2631 _('hg addremove [OPTION]... [FILE]...')),
2632 2632 "^annotate":
2633 2633 (annotate,
2634 2634 [('r', 'rev', '', _('annotate the specified revision')),
2635 2635 ('f', 'follow', None, _('follow file copies and renames')),
2636 2636 ('a', 'text', None, _('treat all files as text')),
2637 2637 ('u', 'user', None, _('list the author')),
2638 2638 ('d', 'date', None, _('list the date')),
2639 2639 ('n', 'number', None, _('list the revision number (default)')),
2640 2640 ('c', 'changeset', None, _('list the changeset')),
2641 2641 ('l', 'line-number', None,
2642 2642 _('show line number at the first appearance'))
2643 2643 ] + walkopts,
2644 2644 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
2645 2645 "archive":
2646 2646 (archive,
2647 2647 [('', 'no-decode', None, _('do not pass files through decoders')),
2648 2648 ('p', 'prefix', '', _('directory prefix for files in archive')),
2649 2649 ('r', 'rev', '', _('revision to distribute')),
2650 2650 ('t', 'type', '', _('type of distribution to create')),
2651 2651 ] + walkopts,
2652 2652 _('hg archive [OPTION]... DEST')),
2653 2653 "backout":
2654 2654 (backout,
2655 2655 [('', 'merge', None,
2656 2656 _('merge with old dirstate parent after backout')),
2657 2657 ('', 'parent', '', _('parent to choose when backing out merge')),
2658 2658 ('r', 'rev', '', _('revision to backout')),
2659 2659 ] + walkopts + commitopts + commitopts2,
2660 2660 _('hg backout [OPTION]... [-r] REV')),
2661 2661 "branch":
2662 2662 (branch,
2663 2663 [('f', 'force', None,
2664 2664 _('set branch name even if it shadows an existing branch'))],
2665 2665 _('hg branch [NAME]')),
2666 2666 "branches":
2667 2667 (branches,
2668 2668 [('a', 'active', False,
2669 2669 _('show only branches that have unmerged heads'))],
2670 2670 _('hg branches [-a]')),
2671 2671 "bundle":
2672 2672 (bundle,
2673 2673 [('f', 'force', None,
2674 2674 _('run even when remote repository is unrelated')),
2675 2675 ('r', 'rev', [],
2676 2676 _('a changeset you would like to bundle')),
2677 2677 ('', 'base', [],
2678 2678 _('a base changeset to specify instead of a destination')),
2679 2679 ] + remoteopts,
2680 2680 _('hg bundle [-f] [-r REV]... [--base REV]... FILE [DEST]')),
2681 2681 "cat":
2682 2682 (cat,
2683 2683 [('o', 'output', '', _('print output to file with formatted name')),
2684 2684 ('r', 'rev', '', _('print the given revision')),
2685 2685 ] + walkopts,
2686 2686 _('hg cat [OPTION]... FILE...')),
2687 2687 "^clone":
2688 2688 (clone,
2689 2689 [('U', 'noupdate', None, _('do not update the new working directory')),
2690 2690 ('r', 'rev', [],
2691 2691 _('a changeset you would like to have after cloning')),
2692 2692 ('', 'pull', None, _('use pull protocol to copy metadata')),
2693 2693 ('', 'uncompressed', None,
2694 2694 _('use uncompressed transfer (fast over LAN)')),
2695 2695 ] + remoteopts,
2696 2696 _('hg clone [OPTION]... SOURCE [DEST]')),
2697 2697 "^commit|ci":
2698 2698 (commit,
2699 2699 [('A', 'addremove', None,
2700 2700 _('mark new/missing files as added/removed before committing')),
2701 2701 ] + walkopts + commitopts + commitopts2,
2702 2702 _('hg commit [OPTION]... [FILE]...')),
2703 2703 "copy|cp":
2704 2704 (copy,
2705 2705 [('A', 'after', None, _('record a copy that has already occurred')),
2706 2706 ('f', 'force', None,
2707 2707 _('forcibly copy over an existing managed file')),
2708 2708 ] + walkopts + dryrunopts,
2709 2709 _('hg copy [OPTION]... [SOURCE]... DEST')),
2710 2710 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2711 2711 "debugcomplete":
2712 2712 (debugcomplete,
2713 2713 [('o', 'options', None, _('show the command options'))],
2714 2714 _('debugcomplete [-o] CMD')),
2715 2715 "debuginstall": (debuginstall, [], _('debuginstall')),
2716 2716 "debugrebuildstate":
2717 2717 (debugrebuildstate,
2718 2718 [('r', 'rev', '', _('revision to rebuild to'))],
2719 2719 _('debugrebuildstate [-r REV] [REV]')),
2720 2720 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2721 2721 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
2722 2722 "debugstate": (debugstate, [], _('debugstate')),
2723 2723 "debugdate":
2724 2724 (debugdate,
2725 2725 [('e', 'extended', None, _('try extended date formats'))],
2726 2726 _('debugdate [-e] DATE [RANGE]')),
2727 2727 "debugdata": (debugdata, [], _('debugdata FILE REV')),
2728 2728 "debugfsinfo": (debugfsinfo, [], _('debugfsinfo [PATH]')),
2729 2729 "debugindex": (debugindex, [], _('debugindex FILE')),
2730 2730 "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
2731 2731 "debugrename":
2732 2732 (debugrename,
2733 2733 [('r', 'rev', '', _('revision to debug'))],
2734 2734 _('debugrename [-r REV] FILE')),
2735 2735 "debugwalk": (debugwalk, walkopts, _('debugwalk [OPTION]... [FILE]...')),
2736 2736 "^diff":
2737 2737 (diff,
2738 2738 [('r', 'rev', [], _('revision')),
2739 2739 ('a', 'text', None, _('treat all files as text')),
2740 2740 ('p', 'show-function', None,
2741 2741 _('show which function each change is in')),
2742 2742 ('g', 'git', None, _('use git extended diff format')),
2743 2743 ('', 'nodates', None, _("don't include dates in diff headers")),
2744 2744 ('w', 'ignore-all-space', None,
2745 2745 _('ignore white space when comparing lines')),
2746 2746 ('b', 'ignore-space-change', None,
2747 2747 _('ignore changes in the amount of white space')),
2748 2748 ('B', 'ignore-blank-lines', None,
2749 2749 _('ignore changes whose lines are all blank')),
2750 2750 ] + walkopts,
2751 2751 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2752 2752 "^export":
2753 2753 (export,
2754 2754 [('o', 'output', '', _('print output to file with formatted name')),
2755 2755 ('a', 'text', None, _('treat all files as text')),
2756 2756 ('g', 'git', None, _('use git extended diff format')),
2757 2757 ('', 'nodates', None, _("don't include dates in diff headers")),
2758 2758 ('', 'switch-parent', None, _('diff against the second parent'))],
2759 2759 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2760 2760 "grep":
2761 2761 (grep,
2762 2762 [('0', 'print0', None, _('end fields with NUL')),
2763 2763 ('', 'all', None, _('print all revisions that match')),
2764 2764 ('f', 'follow', None,
2765 2765 _('follow changeset history, or file history across copies and renames')),
2766 2766 ('i', 'ignore-case', None, _('ignore case when matching')),
2767 2767 ('l', 'files-with-matches', None,
2768 2768 _('print only filenames and revs that match')),
2769 2769 ('n', 'line-number', None, _('print matching line numbers')),
2770 2770 ('r', 'rev', [], _('search in given revision range')),
2771 2771 ('u', 'user', None, _('print user who committed change')),
2772 2772 ] + walkopts,
2773 2773 _('hg grep [OPTION]... PATTERN [FILE]...')),
2774 2774 "heads":
2775 2775 (heads,
2776 2776 [('', 'style', '', _('display using template map file')),
2777 2777 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2778 2778 ('', 'template', '', _('display with template'))],
2779 2779 _('hg heads [-r REV] [REV]...')),
2780 2780 "help": (help_, [], _('hg help [COMMAND]')),
2781 2781 "identify|id":
2782 2782 (identify,
2783 2783 [('r', 'rev', '', _('identify the specified rev')),
2784 2784 ('n', 'num', None, _('show local revision number')),
2785 2785 ('i', 'id', None, _('show global revision id')),
2786 2786 ('b', 'branch', None, _('show branch')),
2787 2787 ('t', 'tags', None, _('show tags'))],
2788 2788 _('hg identify [-nibt] [-r REV] [SOURCE]')),
2789 2789 "import|patch":
2790 2790 (import_,
2791 2791 [('p', 'strip', 1,
2792 2792 _('directory strip option for patch. This has the same\n'
2793 2793 'meaning as the corresponding patch option')),
2794 2794 ('b', 'base', '', _('base path')),
2795 2795 ('f', 'force', None,
2796 2796 _('skip check for outstanding uncommitted changes')),
2797 2797 ('', 'exact', None,
2798 2798 _('apply patch to the nodes from which it was generated')),
2799 2799 ('', 'import-branch', None,
2800 2800 _('Use any branch information in patch (implied by --exact)'))] + commitopts,
2801 2801 _('hg import [-p NUM] [-m MESSAGE] [-f] PATCH...')),
2802 2802 "incoming|in": (incoming,
2803 2803 [('M', 'no-merges', None, _('do not show merges')),
2804 2804 ('f', 'force', None,
2805 2805 _('run even when remote repository is unrelated')),
2806 2806 ('', 'style', '', _('display using template map file')),
2807 2807 ('n', 'newest-first', None, _('show newest record first')),
2808 2808 ('', 'bundle', '', _('file to store the bundles into')),
2809 2809 ('p', 'patch', None, _('show patch')),
2810 2810 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2811 2811 ('', 'template', '', _('display with template')),
2812 2812 ] + remoteopts,
2813 2813 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2814 2814 ' [--bundle FILENAME] [SOURCE]')),
2815 2815 "^init":
2816 2816 (init,
2817 2817 remoteopts,
2818 2818 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2819 2819 "locate":
2820 2820 (locate,
2821 2821 [('r', 'rev', '', _('search the repository as it stood at rev')),
2822 2822 ('0', 'print0', None,
2823 2823 _('end filenames with NUL, for use with xargs')),
2824 2824 ('f', 'fullpath', None,
2825 2825 _('print complete paths from the filesystem root')),
2826 2826 ] + walkopts,
2827 2827 _('hg locate [OPTION]... [PATTERN]...')),
2828 2828 "^log|history":
2829 2829 (log,
2830 2830 [('f', 'follow', None,
2831 2831 _('follow changeset history, or file history across copies and renames')),
2832 2832 ('', 'follow-first', None,
2833 2833 _('only follow the first parent of merge changesets')),
2834 2834 ('d', 'date', '', _('show revs matching date spec')),
2835 2835 ('C', 'copies', None, _('show copied files')),
2836 2836 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
2837 2837 ('l', 'limit', '', _('limit number of changes displayed')),
2838 2838 ('r', 'rev', [], _('show the specified revision or range')),
2839 2839 ('', 'removed', None, _('include revs where files were removed')),
2840 2840 ('M', 'no-merges', None, _('do not show merges')),
2841 2841 ('', 'style', '', _('display using template map file')),
2842 2842 ('m', 'only-merges', None, _('show only merges')),
2843 2843 ('p', 'patch', None, _('show patch')),
2844 2844 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2845 2845 ('', 'template', '', _('display with template')),
2846 2846 ] + walkopts,
2847 2847 _('hg log [OPTION]... [FILE]')),
2848 2848 "manifest": (manifest, [('r', 'rev', '', _('revision to display'))],
2849 2849 _('hg manifest [-r REV]')),
2850 2850 "^merge":
2851 2851 (merge,
2852 2852 [('f', 'force', None, _('force a merge with outstanding changes')),
2853 2853 ('r', 'rev', '', _('revision to merge')),
2854 2854 ],
2855 2855 _('hg merge [-f] [[-r] REV]')),
2856 2856 "outgoing|out": (outgoing,
2857 2857 [('M', 'no-merges', None, _('do not show merges')),
2858 2858 ('f', 'force', None,
2859 2859 _('run even when remote repository is unrelated')),
2860 2860 ('p', 'patch', None, _('show patch')),
2861 2861 ('', 'style', '', _('display using template map file')),
2862 2862 ('r', 'rev', [], _('a specific revision you would like to push')),
2863 2863 ('n', 'newest-first', None, _('show newest record first')),
2864 2864 ('', 'template', '', _('display with template')),
2865 2865 ] + remoteopts,
2866 2866 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
2867 2867 "^parents":
2868 2868 (parents,
2869 2869 [('r', 'rev', '', _('show parents from the specified rev')),
2870 2870 ('', 'style', '', _('display using template map file')),
2871 2871 ('', 'template', '', _('display with template'))],
2872 2872 _('hg parents [-r REV] [FILE]')),
2873 2873 "paths": (paths, [], _('hg paths [NAME]')),
2874 2874 "^pull":
2875 2875 (pull,
2876 2876 [('u', 'update', None,
2877 2877 _('update to new tip if changesets were pulled')),
2878 2878 ('f', 'force', None,
2879 2879 _('run even when remote repository is unrelated')),
2880 2880 ('r', 'rev', [],
2881 2881 _('a specific revision up to which you would like to pull')),
2882 2882 ] + remoteopts,
2883 2883 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
2884 2884 "^push":
2885 2885 (push,
2886 2886 [('f', 'force', None, _('force push')),
2887 2887 ('r', 'rev', [], _('a specific revision you would like to push')),
2888 2888 ] + remoteopts,
2889 2889 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
2890 2890 "debugrawcommit|rawcommit":
2891 2891 (rawcommit,
2892 2892 [('p', 'parent', [], _('parent')),
2893 2893 ('F', 'files', '', _('file list'))
2894 2894 ] + commitopts + commitopts2,
2895 2895 _('hg debugrawcommit [OPTION]... [FILE]...')),
2896 2896 "recover": (recover, [], _('hg recover')),
2897 2897 "^remove|rm":
2898 2898 (remove,
2899 2899 [('A', 'after', None, _('record remove without deleting')),
2900 2900 ('f', 'force', None, _('remove file even if modified')),
2901 2901 ] + walkopts,
2902 2902 _('hg remove [OPTION]... FILE...')),
2903 2903 "rename|mv":
2904 2904 (rename,
2905 2905 [('A', 'after', None, _('record a rename that has already occurred')),
2906 2906 ('f', 'force', None,
2907 2907 _('forcibly copy over an existing managed file')),
2908 2908 ] + walkopts + dryrunopts,
2909 2909 _('hg rename [OPTION]... SOURCE... DEST')),
2910 2910 "revert":
2911 2911 (revert,
2912 2912 [('a', 'all', None, _('revert all changes when no arguments given')),
2913 2913 ('d', 'date', '', _('tipmost revision matching date')),
2914 2914 ('r', 'rev', '', _('revision to revert to')),
2915 2915 ('', 'no-backup', None, _('do not save backup copies of files')),
2916 2916 ] + walkopts + dryrunopts,
2917 2917 _('hg revert [OPTION]... [-r REV] [NAME]...')),
2918 2918 "rollback": (rollback, [], _('hg rollback')),
2919 2919 "root": (root, [], _('hg root')),
2920 2920 "showconfig|debugconfig":
2921 2921 (showconfig,
2922 2922 [('u', 'untrusted', None, _('show untrusted configuration options'))],
2923 2923 _('showconfig [-u] [NAME]...')),
2924 2924 "^serve":
2925 2925 (serve,
2926 2926 [('A', 'accesslog', '', _('name of access log file to write to')),
2927 2927 ('d', 'daemon', None, _('run server in background')),
2928 2928 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
2929 2929 ('E', 'errorlog', '', _('name of error log file to write to')),
2930 2930 ('p', 'port', 0, _('port to use (default: 8000)')),
2931 2931 ('a', 'address', '', _('address to use')),
2932 2932 ('n', 'name', '',
2933 2933 _('name to show in web pages (default: working dir)')),
2934 2934 ('', 'webdir-conf', '', _('name of the webdir config file'
2935 2935 ' (serve more than one repo)')),
2936 2936 ('', 'pid-file', '', _('name of file to write process ID to')),
2937 2937 ('', 'stdio', None, _('for remote clients')),
2938 2938 ('t', 'templates', '', _('web templates to use')),
2939 2939 ('', 'style', '', _('template style to use')),
2940 2940 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
2941 2941 ('', 'certificate', '', _('SSL certificate file'))],
2942 2942 _('hg serve [OPTION]...')),
2943 2943 "^status|st":
2944 2944 (status,
2945 2945 [('A', 'all', None, _('show status of all files')),
2946 2946 ('m', 'modified', None, _('show only modified files')),
2947 2947 ('a', 'added', None, _('show only added files')),
2948 2948 ('r', 'removed', None, _('show only removed files')),
2949 2949 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
2950 2950 ('c', 'clean', None, _('show only files without changes')),
2951 2951 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
2952 2952 ('i', 'ignored', None, _('show only ignored files')),
2953 2953 ('n', 'no-status', None, _('hide status prefix')),
2954 2954 ('C', 'copies', None, _('show source of copied files')),
2955 2955 ('0', 'print0', None,
2956 2956 _('end filenames with NUL, for use with xargs')),
2957 2957 ('', 'rev', [], _('show difference from revision')),
2958 2958 ] + walkopts,
2959 2959 _('hg status [OPTION]... [FILE]...')),
2960 2960 "tag":
2961 2961 (tag,
2962 2962 [('f', 'force', None, _('replace existing tag')),
2963 2963 ('l', 'local', None, _('make the tag local')),
2964 2964 ('r', 'rev', '', _('revision to tag')),
2965 2965 ('', 'remove', None, _('remove a tag')),
2966 2966 # -l/--local is already there, commitopts cannot be used
2967 2967 ('m', 'message', '', _('use <text> as commit message')),
2968 2968 ] + commitopts2,
2969 2969 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
2970 2970 "tags": (tags, [], _('hg tags')),
2971 2971 "tip":
2972 2972 (tip,
2973 2973 [('', 'style', '', _('display using template map file')),
2974 2974 ('p', 'patch', None, _('show patch')),
2975 2975 ('', 'template', '', _('display with template'))],
2976 2976 _('hg tip [-p]')),
2977 2977 "unbundle":
2978 2978 (unbundle,
2979 2979 [('u', 'update', None,
2980 2980 _('update to new tip if changesets were unbundled'))],
2981 2981 _('hg unbundle [-u] FILE...')),
2982 2982 "^update|up|checkout|co":
2983 2983 (update,
2984 2984 [('C', 'clean', None, _('overwrite locally modified files')),
2985 2985 ('d', 'date', '', _('tipmost revision matching date')),
2986 2986 ('r', 'rev', '', _('revision'))],
2987 2987 _('hg update [-C] [-d DATE] [[-r] REV]')),
2988 2988 "verify": (verify, [], _('hg verify')),
2989 2989 "version": (version_, [], _('hg version')),
2990 2990 }
2991 2991
2992 2992 norepo = ("clone init version help debugancestor debugcomplete debugdata"
2993 2993 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
2994 2994 optionalrepo = ("identify paths serve showconfig")
@@ -1,13 +1,13 b''
1 1 adding a
2 2 adding b
3 3 pulling from ../a
4 4 searching for changes
5 5 warning: repository is unrelated
6 6 adding changesets
7 7 adding manifests
8 8 adding file changes
9 9 added 1 changesets with 1 changes to 1 files (+1 heads)
10 10 (run 'hg heads' to see heads, 'hg merge' to merge)
11 11 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 12 (branch merge, don't forget to commit)
13 C b
13 = b
@@ -1,10 +1,10 b''
1 1 % basic
2 2 % unknown
3 3 *** [alias] unknown: command bargle is unknown
4 4 % ambiguous
5 5 *** [alias] ambiguous: command s is ambiguous
6 6 % recursive
7 7 *** [alias] recursive: circular dependency on recursive
8 8 adding foo
9 9 % with opts
10 C foo
10 = foo
@@ -1,47 +1,47 b''
1 1 # should fail - foo is not managed
2 2 foo: not copying - file is not managed
3 3 abort: no files to copy
4 4 ? foo
5 5 # dry-run; print a warning that this is not a real copy; foo is added
6 6 foo has not been committed yet, so no copy data will be stored for bar.
7 7 A foo
8 8 # should print a warning that this is not a real copy; bar is added
9 9 foo has not been committed yet, so no copy data will be stored for bar.
10 10 A bar
11 11 # should print a warning that this is not a real copy; foo is added
12 12 bar has not been committed yet, so no copy data will be stored for foo.
13 13 A foo
14 14 # dry-run; should show that foo is clean
15 C foo
15 = foo
16 16 # should show copy
17 17 A bar
18 18 foo
19 19 # shouldn't show copy
20 20 # should match
21 21 rev offset length base linkrev nodeid p1 p2
22 22 0 0 5 0 0 2ed2a3912a0b 000000000000 000000000000
23 23 bar renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
24 24 # should not be renamed
25 25 bar not renamed
26 26 # should show copy
27 27 M bar
28 28 foo
29 29 # should show no parents for tip
30 30 rev offset length base linkrev nodeid p1 p2
31 31 0 0 69 0 1 6ca237634e1f 000000000000 000000000000
32 32 1 69 6 1 2 7a1ff8e75f5b 6ca237634e1f 000000000000
33 33 2 75 82 1 3 243dfe60f3d9 000000000000 000000000000
34 34 # should match
35 35 rev offset length base linkrev nodeid p1 p2
36 36 0 0 5 0 0 2ed2a3912a0b 000000000000 000000000000
37 37 1 5 7 1 2 dd12c926cf16 2ed2a3912a0b 000000000000
38 38 bar renamed from foo:dd12c926cf165e3eb4cf87b084955cb617221c17
39 39 # should show no copies
40 40 # copy --after on an added file
41 41 A baz
42 42 bar
43 43 # foo was clean:
44 C foo
44 = foo
45 45 # but it's considered modified after a copy --after --force
46 46 M foo
47 47 bar
@@ -1,304 +1,304 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 per file line
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 11 init create a new repository in the given directory
12 12 log show revision history of entire repository or files
13 13 merge merge working directory with another revision
14 14 parents show the parents of the working dir or revision
15 15 pull pull changes from the specified source
16 16 push push changes to the specified destination
17 17 remove remove the specified files on the next commit
18 18 serve export the repository via HTTP
19 19 status show changed files in the working directory
20 20 update update working directory
21 21
22 22 use "hg help" for the full list of commands or "hg -v" for details
23 23 add add the specified files on the next commit
24 24 annotate show changeset information per file line
25 25 clone make a copy of an existing repository
26 26 commit commit the specified files or all outstanding changes
27 27 diff diff repository (or selected files)
28 28 export dump the header and diffs for one or more changesets
29 29 init create a new repository in the given directory
30 30 log show revision history of entire repository or files
31 31 merge merge working directory with another revision
32 32 parents show the parents of the working dir or revision
33 33 pull pull changes from the specified source
34 34 push push changes to the specified destination
35 35 remove remove the specified files on the next commit
36 36 serve export the repository via HTTP
37 37 status show changed files in the working directory
38 38 update update working directory
39 39 Mercurial Distributed SCM
40 40
41 41 list of commands:
42 42
43 43 add add the specified files on the next commit
44 44 addremove add all new files, delete all missing files
45 45 annotate show changeset information per file line
46 46 archive create unversioned archive of a repository revision
47 47 backout reverse effect of earlier changeset
48 48 branch set or show the current branch name
49 49 branches list repository named branches
50 50 bundle create a changegroup file
51 51 cat output the current or given revision of files
52 52 clone make a copy of an existing repository
53 53 commit commit the specified files or all outstanding changes
54 54 copy mark files as copied for the next commit
55 55 diff diff repository (or selected files)
56 56 export dump the header and diffs for one or more changesets
57 57 grep search for a pattern in specified files and revisions
58 58 heads show current repository heads or show branch heads
59 59 help show help for a command, extension, or list of commands
60 60 identify identify the working copy or specified revision
61 61 import import an ordered set of patches
62 62 incoming show new changesets found in source
63 63 init create a new repository in the given directory
64 64 locate locate files matching specific patterns
65 65 log show revision history of entire repository or files
66 66 manifest output the current or given revision of the project manifest
67 67 merge merge working directory with another revision
68 68 outgoing show changesets not found in destination
69 69 parents show the parents of the working dir or revision
70 70 paths show definition of symbolic path names
71 71 pull pull changes from the specified source
72 72 push push changes to the specified destination
73 73 recover roll back an interrupted transaction
74 74 remove remove the specified files on the next commit
75 75 rename rename files; equivalent of copy + remove
76 76 revert restore individual files or dirs to an earlier state
77 77 rollback roll back the last transaction
78 78 root print the root (top) of the current working dir
79 79 serve export the repository via HTTP
80 80 showconfig show combined config settings from all hgrc files
81 81 status show changed files in the working directory
82 82 tag add a tag for the current or given revision
83 83 tags list repository tags
84 84 tip show the tip revision
85 85 unbundle apply one or more changegroup files
86 86 update update working directory
87 87 verify verify the integrity of the repository
88 88 version output version and copyright information
89 89
90 90 use "hg -v help" to show aliases and global options
91 91 add add the specified files on the next commit
92 92 addremove add all new files, delete all missing files
93 93 annotate show changeset information per file line
94 94 archive create unversioned archive of a repository revision
95 95 backout reverse effect of earlier changeset
96 96 branch set or show the current branch name
97 97 branches list repository named branches
98 98 bundle create a changegroup file
99 99 cat output the current or given revision of files
100 100 clone make a copy of an existing repository
101 101 commit commit the specified files or all outstanding changes
102 102 copy mark files as copied for the next commit
103 103 diff diff repository (or selected files)
104 104 export dump the header and diffs for one or more changesets
105 105 grep search for a pattern in specified files and revisions
106 106 heads show current repository heads or show branch heads
107 107 help show help for a command, extension, or list of commands
108 108 identify identify the working copy or specified revision
109 109 import import an ordered set of patches
110 110 incoming show new changesets found in source
111 111 init create a new repository in the given directory
112 112 locate locate files matching specific patterns
113 113 log show revision history of entire repository or files
114 114 manifest output the current or given revision of the project manifest
115 115 merge merge working directory with another revision
116 116 outgoing show changesets not found in destination
117 117 parents show the parents of the working dir or revision
118 118 paths show definition of symbolic path names
119 119 pull pull changes from the specified source
120 120 push push changes to the specified destination
121 121 recover roll back an interrupted transaction
122 122 remove remove the specified files on the next commit
123 123 rename rename files; equivalent of copy + remove
124 124 revert restore individual files or dirs to an earlier state
125 125 rollback roll back the last transaction
126 126 root print the root (top) of the current working dir
127 127 serve export the repository via HTTP
128 128 showconfig show combined config settings from all hgrc files
129 129 status show changed files in the working directory
130 130 tag add a tag for the current or given revision
131 131 tags list repository tags
132 132 tip show the tip revision
133 133 unbundle apply one or more changegroup files
134 134 update update working directory
135 135 verify verify the integrity of the repository
136 136 version output version and copyright information
137 137 hg add [OPTION]... [FILE]...
138 138
139 139 add the specified files on the next commit
140 140
141 141 Schedule files to be version controlled and added to the repository.
142 142
143 143 The files will be added to the repository at the next commit. To
144 144 undo an add before that, see hg revert.
145 145
146 146 If no names are given, add all files in the repository.
147 147
148 148 options:
149 149
150 150 -I --include include names matching the given patterns
151 151 -X --exclude exclude names matching the given patterns
152 152 -n --dry-run do not perform actions, just print output
153 153
154 154 use "hg -v help add" to show global options
155 155 hg add: option --skjdfks not recognized
156 156 hg add [OPTION]... [FILE]...
157 157
158 158 add the specified files on the next commit
159 159
160 160 Schedule files to be version controlled and added to the repository.
161 161
162 162 The files will be added to the repository at the next commit. To
163 163 undo an add before that, see hg revert.
164 164
165 165 If no names are given, add all files in the repository.
166 166
167 167 options:
168 168
169 169 -I --include include names matching the given patterns
170 170 -X --exclude exclude names matching the given patterns
171 171 -n --dry-run do not perform actions, just print output
172 172
173 173 use "hg -v help add" to show global options
174 174 hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...
175 175
176 176 diff repository (or selected files)
177 177
178 178 Show differences between revisions for the specified files.
179 179
180 180 Differences between files are shown using the unified diff format.
181 181
182 182 NOTE: diff may generate unexpected results for merges, as it will
183 183 default to comparing against the working directory's first parent
184 184 changeset if no revisions are specified.
185 185
186 186 When two revision arguments are given, then changes are shown
187 187 between those revisions. If only one revision is specified then
188 188 that revision is compared to the working directory, and, when no
189 189 revisions are specified, the working directory files are compared
190 190 to its parent.
191 191
192 192 Without the -a option, diff will avoid generating diffs of files
193 193 it detects as binary. With -a, diff will generate a diff anyway,
194 194 probably with undesirable results.
195 195
196 196 options:
197 197
198 198 -r --rev revision
199 199 -a --text treat all files as text
200 200 -p --show-function show which function each change is in
201 201 -g --git use git extended diff format
202 202 --nodates don't include dates in diff headers
203 203 -w --ignore-all-space ignore white space when comparing lines
204 204 -b --ignore-space-change ignore changes in the amount of white space
205 205 -B --ignore-blank-lines ignore changes whose lines are all blank
206 206 -I --include include names matching the given patterns
207 207 -X --exclude exclude names matching the given patterns
208 208
209 209 use "hg -v help diff" to show global options
210 210 hg status [OPTION]... [FILE]...
211 211
212 212 show changed files in the working directory
213 213
214 214 Show status of files in the repository. If names are given, only
215 215 files that match are shown. Files that are clean or ignored, are
216 216 not listed unless -c (clean), -i (ignored) or -A is given.
217 217
218 218 NOTE: status may appear to disagree with diff if permissions have
219 219 changed or a merge has occurred. The standard diff format does not
220 220 report permission changes and diff only reports changes relative
221 221 to one merge parent.
222 222
223 223 If one revision is given, it is used as the base revision.
224 224 If two revisions are given, the difference between them is shown.
225 225
226 226 The codes used to show the status of files are:
227 227 M = modified
228 228 A = added
229 229 R = removed
230 C = clean
230 = = clean
231 231 ! = deleted, but still tracked
232 232 ? = not tracked
233 233 I = ignored (not shown by default)
234 234 = the previous added file was copied from here
235 235
236 236 aliases: st
237 237
238 238 options:
239 239
240 240 -A --all show status of all files
241 241 -m --modified show only modified files
242 242 -a --added show only added files
243 243 -r --removed show only removed files
244 244 -d --deleted show only deleted (but tracked) files
245 245 -c --clean show only files without changes
246 246 -u --unknown show only unknown (not tracked) files
247 247 -i --ignored show only ignored files
248 248 -n --no-status hide status prefix
249 249 -C --copies show source of copied files
250 250 -0 --print0 end filenames with NUL, for use with xargs
251 251 --rev show difference from revision
252 252 -I --include include names matching the given patterns
253 253 -X --exclude exclude names matching the given patterns
254 254
255 255 use "hg -v help status" to show global options
256 256 hg status [OPTION]... [FILE]...
257 257
258 258 show changed files in the working directory
259 259 hg: unknown command 'foo'
260 260 Mercurial Distributed SCM
261 261
262 262 basic commands:
263 263
264 264 add add the specified files on the next commit
265 265 annotate show changeset information per file line
266 266 clone make a copy of an existing repository
267 267 commit commit the specified files or all outstanding changes
268 268 diff diff repository (or selected files)
269 269 export dump the header and diffs for one or more changesets
270 270 init create a new repository in the given directory
271 271 log show revision history of entire repository or files
272 272 merge merge working directory with another revision
273 273 parents show the parents of the working dir or revision
274 274 pull pull changes from the specified source
275 275 push push changes to the specified destination
276 276 remove remove the specified files on the next commit
277 277 serve export the repository via HTTP
278 278 status show changed files in the working directory
279 279 update update working directory
280 280
281 281 use "hg help" for the full list of commands or "hg -v" for details
282 282 hg: unknown command 'skjdfks'
283 283 Mercurial Distributed SCM
284 284
285 285 basic commands:
286 286
287 287 add add the specified files on the next commit
288 288 annotate show changeset information per file line
289 289 clone make a copy of an existing repository
290 290 commit commit the specified files or all outstanding changes
291 291 diff diff repository (or selected files)
292 292 export dump the header and diffs for one or more changesets
293 293 init create a new repository in the given directory
294 294 log show revision history of entire repository or files
295 295 merge merge working directory with another revision
296 296 parents show the parents of the working dir or revision
297 297 pull pull changes from the specified source
298 298 push push changes to the specified destination
299 299 remove remove the specified files on the next commit
300 300 serve export the repository via HTTP
301 301 status show changed files in the working directory
302 302 update update working directory
303 303
304 304 use "hg help" for the full list of commands or "hg -v" for details
@@ -1,49 +1,49 b''
1 1 adding a
2 2 adding b/b
3 3 % file replaced with directory
4 4 % should fail - would corrupt dirstate
5 5 abort: file 'a' in dirstate clashes with 'a/a'
6 6 % removing shadow
7 7 % should succeed - shadow removed
8 8 % directory replaced with file
9 9 % should fail - would corrupt dirstate
10 10 abort: directory 'b' already in dirstate
11 11 % removing shadow
12 12 % should succeed - shadow removed
13 13 % look what we got
14 14 A a/a
15 15 A b
16 16 R a
17 17 R b/b
18 18 % revert reintroducing shadow - should fail
19 19 abort: file 'b' in dirstate clashes with 'b/b'
20 20 % revert all - should succeed
21 21 undeleting a
22 22 forgetting a/a
23 23 forgetting b
24 24 undeleting b/b
25 25 % addremove
26 26 removing a
27 27 adding a/a
28 28 adding b
29 29 removing b/b
30 30 A a/a
31 31 A b
32 32 R a
33 33 R b/b
34 34 % commit
35 C a/a
36 C b
35 = a/a
36 = b
37 37 % long directory replaced with file
38 38 adding d/d/d
39 39 % should fail - would corrupt dirstate
40 40 abort: directory 'd' already in dirstate
41 41 % removing shadow
42 42 % should succeed - shadow removed
43 43 % update should work at least with clean workdir
44 44 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
45 C a
46 C b/b
45 = a
46 = b/b
47 47 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
48 C a/a
49 C b
48 = a/a
49 = b
@@ -1,64 +1,64 b''
1 1 adding file1
2 2 adding file2
3 3 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 4
5 5 # non-interactive merge
6 6 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
7 7 (branch merge, don't forget to commit)
8 8 status:
9 9 M file2
10 C file1
10 = file1
11 11 file1:
12 12 1
13 13 changed
14 14 file2:
15 15 2
16 16 changed
17 17
18 18 # interactive merge
19 19 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
20 20 local changed file1 which remote deleted
21 21 use (c)hanged version or (d)elete? remote changed file2 which local deleted
22 22 use (c)hanged version or leave (d)eleted? 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 23 (branch merge, don't forget to commit)
24 24 status:
25 25 file2: No such file or directory
26 C file1
26 = file1
27 27 file1:
28 28 1
29 29 changed
30 30 file2 does not exist
31 31
32 32 # interactive merge with bad input
33 33 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 34 local changed file1 which remote deleted
35 35 use (c)hanged version or (d)elete? unrecognized response
36 36 local changed file1 which remote deleted
37 37 use (c)hanged version or (d)elete? unrecognized response
38 38 local changed file1 which remote deleted
39 39 use (c)hanged version or (d)elete? remote changed file2 which local deleted
40 40 use (c)hanged version or leave (d)eleted? unrecognized response
41 41 remote changed file2 which local deleted
42 42 use (c)hanged version or leave (d)eleted? 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
43 43 (branch merge, don't forget to commit)
44 44 status:
45 45 M file2
46 46 R file1
47 47 file1 does not exist
48 48 file2:
49 49 2
50 50 changed
51 51
52 52 # interactive merge with not enough input
53 53 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
54 54 local changed file1 which remote deleted
55 55 use (c)hanged version or (d)elete? remote changed file2 which local deleted
56 56 use (c)hanged version or leave (d)eleted? abort: response expected
57 57 failed
58 58 status:
59 59 file2: No such file or directory
60 C file1
60 = file1
61 61 file1:
62 62 1
63 63 changed
64 64 file2 does not exist
@@ -1,19 +1,19 b''
1 1 adding foo
2 2 Patch queue now empty
3 3 applying patch1
4 4 applying patch2
5 5 applying bad-patch
6 6 transaction abort!
7 7 rollback completed
8 8 cleaning up working directory...done
9 9 abort: decoding near 'οΏ½': 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)!
10 10 changeset: 0:bbd179dfa0a7
11 11 tag: tip
12 12 user: test
13 13 date: Thu Jan 01 00:00:00 1970 +0000
14 14 summary: add foo
15 15
16 16 % bar should be gone; other unknown/ignored files should still be around
17 17 ? untracked-file
18 18 I .hgignore
19 C foo
19 = foo
@@ -1,458 +1,458 b''
1 1 % help
2 2 mq extension - patch management and development
3 3
4 4 This extension lets you work with a stack of patches in a Mercurial
5 5 repository. It manages two stacks of patches - all known patches, and
6 6 applied patches (subset of known patches).
7 7
8 8 Known patches are represented as patch files in the .hg/patches
9 9 directory. Applied patches are both patch files and changesets.
10 10
11 11 Common tasks (use "hg help command" for more details):
12 12
13 13 prepare repository to work with patches qinit
14 14 create new patch qnew
15 15 import existing patch qimport
16 16
17 17 print patch series qseries
18 18 print applied patches qapplied
19 19 print name of top applied patch qtop
20 20
21 21 add known patch to applied stack qpush
22 22 remove patch from applied stack qpop
23 23 refresh contents of top applied patch qrefresh
24 24
25 25 list of commands:
26 26
27 27 qapplied print the patches already applied
28 28 qclone clone main and patch repository at same time
29 29 qcommit commit changes in the queue repository
30 30 qdelete remove patches from queue
31 31 qdiff diff of the current patch
32 32 qfold fold the named patches into the current patch
33 33 qgoto push or pop patches until named patch is at top of stack
34 34 qguard set or print guards for a patch
35 35 qheader Print the header of the topmost or specified patch
36 36 qimport import a patch
37 37 qinit init a new queue repository
38 38 qnew create a new patch
39 39 qnext print the name of the next patch
40 40 qpop pop the current patch off the stack
41 41 qprev print the name of the previous patch
42 42 qpush push the next patch onto the stack
43 43 qrefresh update the current patch
44 44 qrename rename a patch
45 45 qrestore restore the queue state saved by a rev
46 46 qsave save current queue state
47 47 qselect set or print guarded patches to push
48 48 qseries print the entire series file
49 49 qtop print the name of the current patch
50 50 qunapplied print the patches not yet applied
51 51 strip strip a revision and all later revs on the same branch
52 52
53 53 use "hg -v help mq" to show aliases and global options
54 54 adding a
55 55 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
56 56 adding b/z
57 57 % qinit
58 58 % -R qinit
59 59 % qinit -c
60 60 A .hgignore
61 61 A series
62 62 % qnew implies add
63 63 A .hgignore
64 64 A series
65 65 A test.patch
66 66 % qinit; qinit -c
67 67 .hgignore:
68 68 syntax: glob
69 69 status
70 70 guards
71 71 series:
72 72 abort: repository already exists!
73 73 % qinit; <stuff>; qinit -c
74 74 adding .hg/patches/A
75 75 adding .hg/patches/B
76 76 A .hgignore
77 77 A A
78 78 A B
79 79 A series
80 80 .hgignore:
81 81 status
82 82 bleh
83 83 series:
84 84 A
85 85 B
86 86 % qnew with uncommitted changes
87 87 abort: local changes found, refresh first
88 88 A somefile
89 89 % qnew with uncommitted changes and missing file (issue 803)
90 90 someotherfile: No such file or directory
91 91 A somefile
92 92 issue803.patch
93 93 Patch queue now empty
94 94 % qnew -m
95 95 foo bar
96 96 % qrefresh
97 97 foo bar
98 98
99 99 diff -r xa
100 100 --- a/a
101 101 +++ b/a
102 102 @@ -1,1 +1,2 @@ a
103 103 a
104 104 +a
105 105 % empty qrefresh
106 106 revision:
107 107 patch:
108 108 foo bar
109 109
110 110 working dir diff:
111 111 --- a/a
112 112 +++ b/a
113 113 @@ -1,1 +1,2 @@ a
114 114 a
115 115 +a
116 116 % qpop
117 117 Patch queue now empty
118 118 % qpush
119 119 applying test.patch
120 120 Now at: test.patch
121 121 % pop/push outside repo
122 122 Patch queue now empty
123 123 applying test.patch
124 124 Now at: test.patch
125 125 % qrefresh in subdir
126 126 % pop/push -a in subdir
127 127 Patch queue now empty
128 128 applying test.patch
129 129 applying test2.patch
130 130 Now at: test2.patch
131 131 % qseries
132 132 test.patch
133 133 test2.patch
134 134 Now at: test.patch
135 135 0 A test.patch: foo bar
136 136 1 U test2.patch:
137 137 applying test2.patch
138 138 Now at: test2.patch
139 139 % qapplied
140 140 test.patch
141 141 test2.patch
142 142 % qtop
143 143 test2.patch
144 144 % qprev
145 145 test.patch
146 146 % qnext
147 147 All patches applied
148 148 % pop, qnext, qprev, qapplied
149 149 Now at: test.patch
150 150 test2.patch
151 151 Only one patch applied
152 152 test.patch
153 153 % commit should fail
154 154 abort: cannot commit over an applied mq patch
155 155 % push should fail
156 156 pushing to ../../k
157 157 abort: source has mq patches applied
158 158 % qunapplied
159 159 test2.patch
160 160 % qpush/qpop with index
161 161 applying test2.patch
162 162 Now at: test2.patch
163 163 Now at: test.patch
164 164 applying test1b.patch
165 165 Now at: test1b.patch
166 166 applying test2.patch
167 167 Now at: test2.patch
168 168 Now at: test1b.patch
169 169 Now at: test.patch
170 170 applying test1b.patch
171 171 applying test2.patch
172 172 Now at: test2.patch
173 173 % push should succeed
174 174 Patch queue now empty
175 175 pushing to ../../k
176 176 searching for changes
177 177 adding changesets
178 178 adding manifests
179 179 adding file changes
180 180 added 1 changesets with 1 changes to 1 files
181 181 % qpush/qpop error codes
182 182 applying test.patch
183 183 applying test1b.patch
184 184 applying test2.patch
185 185 Now at: test2.patch
186 186 % pops all patches and succeeds
187 187 Patch queue now empty
188 188 qpop -a succeeds
189 189 % does nothing and succeeds
190 190 no patches applied
191 191 qpop -a succeeds
192 192 % fails - nothing else to pop
193 193 no patches applied
194 194 qpop fails
195 195 % pushes a patch and succeeds
196 196 applying test.patch
197 197 Now at: test.patch
198 198 qpush succeeds
199 199 % pops a patch and succeeds
200 200 Patch queue now empty
201 201 qpop succeeds
202 202 % pushes up to test1b.patch and succeeds
203 203 applying test.patch
204 204 applying test1b.patch
205 205 Now at: test1b.patch
206 206 qpush test1b.patch succeeds
207 207 % does nothing and succeeds
208 208 qpush: test1b.patch is already at the top
209 209 qpush test1b.patch succeeds
210 210 % does nothing and succeeds
211 211 qpop: test1b.patch is already at the top
212 212 qpop test1b.patch succeeds
213 213 % fails - can't push to this patch
214 214 abort: cannot push to a previous patch: test.patch
215 215 qpush test.patch fails
216 216 % fails - can't pop to this patch
217 217 abort: patch test2.patch is not applied
218 218 qpop test2.patch fails
219 219 % pops up to test.patch and succeeds
220 220 Now at: test.patch
221 221 qpop test.patch succeeds
222 222 % pushes all patches and succeeds
223 223 applying test1b.patch
224 224 applying test2.patch
225 225 Now at: test2.patch
226 226 qpush -a succeeds
227 227 % does nothing and succeeds
228 228 all patches are currently applied
229 229 qpush -a succeeds
230 230 % fails - nothing else to push
231 231 patch series already fully applied
232 232 qpush fails
233 233 % does nothing and succeeds
234 234 all patches are currently applied
235 235 qpush test2.patch succeeds
236 236 % strip
237 237 adding x
238 238 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
239 239 saving bundle to
240 240 adding changesets
241 241 adding manifests
242 242 adding file changes
243 243 added 1 changesets with 1 changes to 1 files
244 244 (run 'hg update' to get a working copy)
245 245 % cd b; hg qrefresh
246 246 adding a
247 247 foo
248 248
249 249 diff -r cb9a9f314b8b a
250 250 --- a/a
251 251 +++ b/a
252 252 @@ -1,1 +1,2 @@ a
253 253 a
254 254 +a
255 255 diff -r cb9a9f314b8b b/f
256 256 --- /dev/null
257 257 +++ b/b/f
258 258 @@ -0,0 +1,1 @@
259 259 +f
260 260 % hg qrefresh .
261 261 foo
262 262
263 263 diff -r cb9a9f314b8b b/f
264 264 --- /dev/null
265 265 +++ b/b/f
266 266 @@ -0,0 +1,1 @@
267 267 +f
268 268 M a
269 269 % qpush failure
270 270 Patch queue now empty
271 271 applying foo
272 272 applying bar
273 273 file foo already exists
274 274 1 out of 1 hunk FAILED -- saving rejects to file foo.rej
275 275 patch failed, unable to continue (try -v)
276 276 patch failed, rejects left in working dir
277 277 Errors during apply, please fix and refresh bar
278 278 ? foo
279 279 ? foo.rej
280 280 % mq tags
281 281 0 qparent
282 282 1 qbase foo
283 283 2 qtip bar tip
284 284 new file
285 285
286 286 diff --git a/new b/new
287 287 new file mode 100755
288 288 --- /dev/null
289 289 +++ b/new
290 290 @@ -0,0 +1,1 @@
291 291 +foo
292 292 copy file
293 293
294 294 diff --git a/new b/copy
295 295 copy from new
296 296 copy to copy
297 297 Now at: new
298 298 applying copy
299 299 Now at: copy
300 300 diff --git a/new b/copy
301 301 copy from new
302 302 copy to copy
303 303 diff --git a/new b/copy
304 304 copy from new
305 305 copy to copy
306 306 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
307 307 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
308 308 adding branch
309 309 adding changesets
310 310 adding manifests
311 311 adding file changes
312 312 added 1 changesets with 1 changes to 1 files
313 313 (run 'hg update' to get a working copy)
314 314 Patch queue now empty
315 315 applying bar
316 316 Now at: bar
317 317 diff --git a/bar b/bar
318 318 new file mode 100644
319 319 --- /dev/null
320 320 +++ b/bar
321 321 @@ -0,0 +1,1 @@
322 322 +bar
323 323 diff --git a/foo b/baz
324 324 rename from foo
325 325 rename to baz
326 326 2 baz (foo)
327 327 diff --git a/bar b/bar
328 328 new file mode 100644
329 329 --- /dev/null
330 330 +++ b/bar
331 331 @@ -0,0 +1,1 @@
332 332 +bar
333 333 diff --git a/foo b/baz
334 334 rename from foo
335 335 rename to baz
336 336 2 baz (foo)
337 337 diff --git a/bar b/bar
338 338 diff --git a/foo b/baz
339 339
340 340 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
341 341 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
342 342 adding branch
343 343 adding changesets
344 344 adding manifests
345 345 adding file changes
346 346 added 1 changesets with 1 changes to 1 files
347 347 (run 'hg update' to get a working copy)
348 348 Patch queue now empty
349 349 applying bar
350 350 Now at: bar
351 351 diff --git a/foo b/bleh
352 352 rename from foo
353 353 rename to bleh
354 354 diff --git a/quux b/quux
355 355 new file mode 100644
356 356 --- /dev/null
357 357 +++ b/quux
358 358 @@ -0,0 +1,1 @@
359 359 +bar
360 360 3 bleh (foo)
361 361 diff --git a/foo b/barney
362 362 rename from foo
363 363 rename to barney
364 364 diff --git a/fred b/fred
365 365 new file mode 100644
366 366 --- /dev/null
367 367 +++ b/fred
368 368 @@ -0,0 +1,1 @@
369 369 +bar
370 370 3 barney (foo)
371 371 % refresh omitting an added file
372 C newfile
372 = newfile
373 373 A newfile
374 374 Now at: bar
375 375 % create a git patch
376 376 diff --git a/alexander b/alexander
377 377 % create a git binary patch
378 378 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
379 379 diff --git a/bucephalus b/bucephalus
380 380 % check binary patches can be popped and pushed
381 381 Now at: addalexander
382 382 applying addbucephalus
383 383 Now at: addbucephalus
384 384 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
385 385 % strip again
386 386 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
387 387 merging foo
388 388 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
389 389 (branch merge, don't forget to commit)
390 390 changeset: 3:99615015637b
391 391 tag: tip
392 392 parent: 2:20cbbe65cff7
393 393 parent: 1:d2871fc282d4
394 394 user: test
395 395 date: Thu Jan 01 00:00:00 1970 +0000
396 396 summary: merge
397 397
398 398 changeset: 2:20cbbe65cff7
399 399 parent: 0:53245c60e682
400 400 user: test
401 401 date: Thu Jan 01 00:00:00 1970 +0000
402 402 summary: change foo 2
403 403
404 404 changeset: 1:d2871fc282d4
405 405 user: test
406 406 date: Thu Jan 01 00:00:00 1970 +0000
407 407 summary: change foo 1
408 408
409 409 changeset: 0:53245c60e682
410 410 user: test
411 411 date: Thu Jan 01 00:00:00 1970 +0000
412 412 summary: add foo
413 413
414 414 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
415 415 saving bundle to
416 416 saving bundle to
417 417 adding branch
418 418 adding changesets
419 419 adding manifests
420 420 adding file changes
421 421 added 1 changesets with 1 changes to 1 files
422 422 (run 'hg update' to get a working copy)
423 423 changeset: 1:20cbbe65cff7
424 424 tag: tip
425 425 user: test
426 426 date: Thu Jan 01 00:00:00 1970 +0000
427 427 summary: change foo 2
428 428
429 429 changeset: 0:53245c60e682
430 430 user: test
431 431 date: Thu Jan 01 00:00:00 1970 +0000
432 432 summary: add foo
433 433
434 434 % qclone
435 435 abort: versioned patch repository not found (see qinit -c)
436 436 adding .hg/patches/patch1
437 437 main repo:
438 438 rev 1: change foo
439 439 rev 0: add foo
440 440 patch repo:
441 441 rev 0: checkpoint
442 442 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
443 443 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
444 444 main repo:
445 445 rev 0: add foo
446 446 patch repo:
447 447 rev 0: checkpoint
448 448 Patch queue now empty
449 449 main repo:
450 450 rev 0: add foo
451 451 patch repo:
452 452 rev 0: checkpoint
453 453 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
454 454 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
455 455 main repo:
456 456 rev 0: add foo
457 457 patch repo:
458 458 rev 0: checkpoint
@@ -1,17 +1,17 b''
1 1 adding bar
2 2 adding foo
3 3 % state dump
4 4 a 0 -1 baz
5 5 n 644 0 foo
6 6 r 0 0 bar
7 7 % status
8 8 A baz
9 9 R bar
10 C foo
10 = foo
11 11 % state dump
12 12 n 666 -1 bar
13 13 n 666 -1 foo
14 14 % status
15 15 ! bar
16 16 ? baz
17 C foo
17 = foo
@@ -1,40 +1,40 b''
1 1 checkout
2 2 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
3 3 merge
4 4 resolving manifests
5 5 overwrite None partial False
6 6 ancestor af1939970a1c local f26ec4fc3fa3+ remote 8e765a822af2
7 7 searching for copies back to rev 1
8 8 unmatched files in local:
9 9 c2
10 10 unmatched files in other:
11 11 b
12 12 b2
13 13 all copies found (* = to merge, ! = divergent):
14 14 c2 -> a2
15 15 b -> a *
16 16 b2 -> a2
17 17 checking for directory renames
18 18 a2: divergent renames -> dr
19 19 a: remote moved to b -> m
20 20 b2: remote created -> g
21 21 copying a to b
22 22 merging a and b
23 23 my a@f26ec4fc3fa3+ other b@8e765a822af2 ancestor a@af1939970a1c
24 24 removing a
25 25 warning: detected divergent renames of a2 to:
26 26 c2
27 27 b2
28 28 getting b2
29 29 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
30 30 (branch merge, don't forget to commit)
31 31 M b
32 32 a
33 33 M b2
34 34 R a
35 C c2
35 = c2
36 36 blahblah
37 37 rev offset length base linkrev nodeid p1 p2
38 38 0 0 67 0 1 dc51707dfc98 000000000000 000000000000
39 39 1 67 72 1 3 b2494a44f0a9 000000000000 dc51707dfc98
40 40 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
@@ -1,499 +1,499 b''
1 1 --------------
2 2 test L:up a R:nc a b W: - 1 get local a to b
3 3 --------------
4 4 resolving manifests
5 5 overwrite None partial False
6 6 ancestor 924404dff337 local e300d1c794ec+ remote 735846fee2d7
7 7 searching for copies back to rev 1
8 8 unmatched files in other:
9 9 b
10 10 all copies found (* = to merge, ! = divergent):
11 11 b -> a *
12 12 checking for directory renames
13 13 rev: versions differ -> m
14 14 a: remote copied to b -> m
15 15 copying a to b
16 16 merging a and b
17 17 my a@e300d1c794ec+ other b@735846fee2d7 ancestor a@924404dff337
18 18 merging rev
19 19 my rev@e300d1c794ec+ other rev@735846fee2d7 ancestor rev@924404dff337
20 20 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
21 21 (branch merge, don't forget to commit)
22 22 --------------
23 23 M b
24 24 a
25 C a
25 = a
26 26 --------------
27 27
28 28 --------------
29 29 test L:nc a b R:up a W: - 2 get rem change to a and b
30 30 --------------
31 31 resolving manifests
32 32 overwrite None partial False
33 33 ancestor 924404dff337 local ac809aeed39a+ remote f4db7e329e71
34 34 searching for copies back to rev 1
35 35 unmatched files in local:
36 36 b
37 37 all copies found (* = to merge, ! = divergent):
38 38 b -> a *
39 39 checking for directory renames
40 40 a: remote is newer -> g
41 41 b: local copied to a -> m
42 42 rev: versions differ -> m
43 43 getting a
44 44 merging b and a
45 45 my b@ac809aeed39a+ other a@f4db7e329e71 ancestor a@924404dff337
46 46 merging rev
47 47 my rev@ac809aeed39a+ other rev@f4db7e329e71 ancestor rev@924404dff337
48 48 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
49 49 (branch merge, don't forget to commit)
50 50 --------------
51 51 M a
52 52 M b
53 53 a
54 54 --------------
55 55
56 56 --------------
57 57 test L:up a R:nm a b W: - 3 get local a change to b, remove a
58 58 --------------
59 59 resolving manifests
60 60 overwrite None partial False
61 61 ancestor 924404dff337 local e300d1c794ec+ remote e03727d2d66b
62 62 searching for copies back to rev 1
63 63 unmatched files in other:
64 64 b
65 65 all copies found (* = to merge, ! = divergent):
66 66 b -> a *
67 67 checking for directory renames
68 68 rev: versions differ -> m
69 69 a: remote moved to b -> m
70 70 copying a to b
71 71 merging a and b
72 72 my a@e300d1c794ec+ other b@e03727d2d66b ancestor a@924404dff337
73 73 removing a
74 74 merging rev
75 75 my rev@e300d1c794ec+ other rev@e03727d2d66b ancestor rev@924404dff337
76 76 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
77 77 (branch merge, don't forget to commit)
78 78 --------------
79 79 M b
80 80 a
81 81 --------------
82 82
83 83 --------------
84 84 test L:nm a b R:up a W: - 4 get remote change to b
85 85 --------------
86 86 resolving manifests
87 87 overwrite None partial False
88 88 ancestor 924404dff337 local ecf3cb2a4219+ remote f4db7e329e71
89 89 searching for copies back to rev 1
90 90 unmatched files in local:
91 91 b
92 92 all copies found (* = to merge, ! = divergent):
93 93 b -> a *
94 94 checking for directory renames
95 95 b: local moved to a -> m
96 96 rev: versions differ -> m
97 97 merging b and a
98 98 my b@ecf3cb2a4219+ other a@f4db7e329e71 ancestor a@924404dff337
99 99 merging rev
100 100 my rev@ecf3cb2a4219+ other rev@f4db7e329e71 ancestor rev@924404dff337
101 101 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
102 102 (branch merge, don't forget to commit)
103 103 --------------
104 104 M b
105 105 a
106 106 --------------
107 107
108 108 --------------
109 109 test L: R:nc a b W: - 5 get b
110 110 --------------
111 111 resolving manifests
112 112 overwrite None partial False
113 113 ancestor 924404dff337 local 94b33a1b7f2d+ remote 735846fee2d7
114 114 searching for copies back to rev 1
115 115 unmatched files in other:
116 116 b
117 117 all copies found (* = to merge, ! = divergent):
118 118 b -> a
119 119 checking for directory renames
120 120 rev: versions differ -> m
121 121 b: remote created -> g
122 122 getting b
123 123 merging rev
124 124 my rev@94b33a1b7f2d+ other rev@735846fee2d7 ancestor rev@924404dff337
125 125 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
126 126 (branch merge, don't forget to commit)
127 127 --------------
128 128 M b
129 C a
129 = a
130 130 --------------
131 131
132 132 --------------
133 133 test L:nc a b R: W: - 6 nothing
134 134 --------------
135 135 resolving manifests
136 136 overwrite None partial False
137 137 ancestor 924404dff337 local ac809aeed39a+ remote 97c705ade336
138 138 searching for copies back to rev 1
139 139 unmatched files in local:
140 140 b
141 141 all copies found (* = to merge, ! = divergent):
142 142 b -> a
143 143 checking for directory renames
144 144 rev: versions differ -> m
145 145 merging rev
146 146 my rev@ac809aeed39a+ other rev@97c705ade336 ancestor rev@924404dff337
147 147 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
148 148 (branch merge, don't forget to commit)
149 149 --------------
150 C a
151 C b
150 = a
151 = b
152 152 --------------
153 153
154 154 --------------
155 155 test L: R:nm a b W: - 7 get b
156 156 --------------
157 157 resolving manifests
158 158 overwrite None partial False
159 159 ancestor 924404dff337 local 94b33a1b7f2d+ remote e03727d2d66b
160 160 searching for copies back to rev 1
161 161 unmatched files in other:
162 162 b
163 163 all copies found (* = to merge, ! = divergent):
164 164 b -> a
165 165 checking for directory renames
166 166 a: other deleted -> r
167 167 rev: versions differ -> m
168 168 b: remote created -> g
169 169 removing a
170 170 getting b
171 171 merging rev
172 172 my rev@94b33a1b7f2d+ other rev@e03727d2d66b ancestor rev@924404dff337
173 173 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
174 174 (branch merge, don't forget to commit)
175 175 --------------
176 176 M b
177 177 --------------
178 178
179 179 --------------
180 180 test L:nm a b R: W: - 8 nothing
181 181 --------------
182 182 resolving manifests
183 183 overwrite None partial False
184 184 ancestor 924404dff337 local ecf3cb2a4219+ remote 97c705ade336
185 185 searching for copies back to rev 1
186 186 unmatched files in local:
187 187 b
188 188 all copies found (* = to merge, ! = divergent):
189 189 b -> a
190 190 checking for directory renames
191 191 rev: versions differ -> m
192 192 merging rev
193 193 my rev@ecf3cb2a4219+ other rev@97c705ade336 ancestor rev@924404dff337
194 194 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
195 195 (branch merge, don't forget to commit)
196 196 --------------
197 C b
197 = b
198 198 --------------
199 199
200 200 --------------
201 201 test L:um a b R:um a b W: - 9 do merge with ancestor in a
202 202 --------------
203 203 resolving manifests
204 204 overwrite None partial False
205 205 ancestor 924404dff337 local ec03c2ca8642+ remote 79cc6877a3b7
206 206 searching for copies back to rev 1
207 207 b: versions differ -> m
208 208 rev: versions differ -> m
209 209 merging b
210 210 my b@ec03c2ca8642+ other b@79cc6877a3b7 ancestor a@924404dff337
211 211 merging rev
212 212 my rev@ec03c2ca8642+ other rev@79cc6877a3b7 ancestor rev@924404dff337
213 213 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
214 214 (branch merge, don't forget to commit)
215 215 --------------
216 216 M b
217 217 --------------
218 218
219 219 --------------
220 220 test L:nm a b R:nm a c W: - 11 get c, keep b
221 221 --------------
222 222 resolving manifests
223 223 overwrite None partial False
224 224 ancestor 924404dff337 local ecf3cb2a4219+ remote e6abcc1a30c2
225 225 searching for copies back to rev 1
226 226 unmatched files in local:
227 227 b
228 228 unmatched files in other:
229 229 c
230 230 all copies found (* = to merge, ! = divergent):
231 231 c -> a
232 232 b -> a
233 233 checking for directory renames
234 234 a: divergent renames -> dr
235 235 rev: versions differ -> m
236 236 c: remote created -> g
237 237 warning: detected divergent renames of a to:
238 238 b
239 239 c
240 240 getting c
241 241 merging rev
242 242 my rev@ecf3cb2a4219+ other rev@e6abcc1a30c2 ancestor rev@924404dff337
243 243 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
244 244 (branch merge, don't forget to commit)
245 245 --------------
246 246 M c
247 C b
247 = b
248 248 --------------
249 249
250 250 --------------
251 251 test L:nc a b R:up b W: - 12 merge b no ancestor
252 252 --------------
253 253 resolving manifests
254 254 overwrite None partial False
255 255 ancestor 924404dff337 local ac809aeed39a+ remote af30c7647fc7
256 256 searching for copies back to rev 1
257 257 b: versions differ -> m
258 258 rev: versions differ -> m
259 259 merging b
260 260 my b@ac809aeed39a+ other b@af30c7647fc7 ancestor b@000000000000
261 261 merging rev
262 262 my rev@ac809aeed39a+ other rev@af30c7647fc7 ancestor rev@924404dff337
263 263 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
264 264 (branch merge, don't forget to commit)
265 265 --------------
266 266 M b
267 C a
267 = a
268 268 --------------
269 269
270 270 --------------
271 271 test L:up b R:nm a b W: - 13 merge b no ancestor
272 272 --------------
273 273 resolving manifests
274 274 overwrite None partial False
275 275 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
276 276 searching for copies back to rev 1
277 277 a: other deleted -> r
278 278 b: versions differ -> m
279 279 rev: versions differ -> m
280 280 removing a
281 281 merging b
282 282 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
283 283 merging rev
284 284 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
285 285 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
286 286 (branch merge, don't forget to commit)
287 287 --------------
288 288 M b
289 289 --------------
290 290
291 291 --------------
292 292 test L:nc a b R:up a b W: - 14 merge b no ancestor
293 293 --------------
294 294 resolving manifests
295 295 overwrite None partial False
296 296 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
297 297 searching for copies back to rev 1
298 298 a: remote is newer -> g
299 299 b: versions differ -> m
300 300 rev: versions differ -> m
301 301 getting a
302 302 merging b
303 303 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
304 304 merging rev
305 305 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
306 306 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
307 307 (branch merge, don't forget to commit)
308 308 --------------
309 309 M a
310 310 M b
311 311 --------------
312 312
313 313 --------------
314 314 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
315 315 --------------
316 316 resolving manifests
317 317 overwrite None partial False
318 318 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
319 319 searching for copies back to rev 1
320 320 a: other deleted -> r
321 321 b: versions differ -> m
322 322 rev: versions differ -> m
323 323 removing a
324 324 merging b
325 325 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
326 326 merging rev
327 327 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
328 328 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
329 329 (branch merge, don't forget to commit)
330 330 --------------
331 331 M b
332 332 --------------
333 333
334 334 --------------
335 335 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
336 336 --------------
337 337 resolving manifests
338 338 overwrite None partial False
339 339 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
340 340 searching for copies back to rev 1
341 341 a: remote is newer -> g
342 342 b: versions differ -> m
343 343 rev: versions differ -> m
344 344 getting a
345 345 merging b
346 346 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
347 347 merging rev
348 348 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
349 349 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
350 350 (branch merge, don't forget to commit)
351 351 --------------
352 352 M a
353 353 M b
354 354 --------------
355 355
356 356 --------------
357 357 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
358 358 --------------
359 359 resolving manifests
360 360 overwrite None partial False
361 361 ancestor 924404dff337 local 0b76e65c8289+ remote 735846fee2d7
362 362 searching for copies back to rev 1
363 363 b: versions differ -> m
364 364 rev: versions differ -> m
365 365 merging b
366 366 my b@0b76e65c8289+ other b@735846fee2d7 ancestor b@000000000000
367 367 merging rev
368 368 my rev@0b76e65c8289+ other rev@735846fee2d7 ancestor rev@924404dff337
369 369 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
370 370 (branch merge, don't forget to commit)
371 371 --------------
372 372 M b
373 C a
373 = a
374 374 --------------
375 375
376 376 --------------
377 377 test L:nm a b R:up a b W: - 18 merge b no ancestor
378 378 --------------
379 379 resolving manifests
380 380 overwrite None partial False
381 381 ancestor 924404dff337 local ecf3cb2a4219+ remote 8dbce441892a
382 382 searching for copies back to rev 1
383 383 b: versions differ -> m
384 384 rev: versions differ -> m
385 385 a: prompt recreating -> g
386 386 getting a
387 387 merging b
388 388 my b@ecf3cb2a4219+ other b@8dbce441892a ancestor b@000000000000
389 389 merging rev
390 390 my rev@ecf3cb2a4219+ other rev@8dbce441892a ancestor rev@924404dff337
391 391 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
392 392 (branch merge, don't forget to commit)
393 393 --------------
394 394 M a
395 395 M b
396 396 --------------
397 397
398 398 --------------
399 399 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
400 400 --------------
401 401 resolving manifests
402 402 overwrite None partial False
403 403 ancestor 924404dff337 local 0b76e65c8289+ remote e03727d2d66b
404 404 searching for copies back to rev 1
405 405 b: versions differ -> m
406 406 rev: versions differ -> m
407 407 merging b
408 408 my b@0b76e65c8289+ other b@e03727d2d66b ancestor b@000000000000
409 409 merging rev
410 410 my rev@0b76e65c8289+ other rev@e03727d2d66b ancestor rev@924404dff337
411 411 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
412 412 (branch merge, don't forget to commit)
413 413 --------------
414 414 M b
415 C a
415 = a
416 416 --------------
417 417
418 418 --------------
419 419 test L:up a R:um a b W: - 20 merge a and b to b, remove a
420 420 --------------
421 421 resolving manifests
422 422 overwrite None partial False
423 423 ancestor 924404dff337 local e300d1c794ec+ remote 79cc6877a3b7
424 424 searching for copies back to rev 1
425 425 unmatched files in other:
426 426 b
427 427 all copies found (* = to merge, ! = divergent):
428 428 b -> a *
429 429 checking for directory renames
430 430 rev: versions differ -> m
431 431 a: remote moved to b -> m
432 432 copying a to b
433 433 merging a and b
434 434 my a@e300d1c794ec+ other b@79cc6877a3b7 ancestor a@924404dff337
435 435 removing a
436 436 merging rev
437 437 my rev@e300d1c794ec+ other rev@79cc6877a3b7 ancestor rev@924404dff337
438 438 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
439 439 (branch merge, don't forget to commit)
440 440 --------------
441 441 M b
442 442 a
443 443 --------------
444 444
445 445 --------------
446 446 test L:um a b R:up a W: - 21 merge a and b to b
447 447 --------------
448 448 resolving manifests
449 449 overwrite None partial False
450 450 ancestor 924404dff337 local ec03c2ca8642+ remote f4db7e329e71
451 451 searching for copies back to rev 1
452 452 unmatched files in local:
453 453 b
454 454 all copies found (* = to merge, ! = divergent):
455 455 b -> a *
456 456 checking for directory renames
457 457 b: local moved to a -> m
458 458 rev: versions differ -> m
459 459 merging b and a
460 460 my b@ec03c2ca8642+ other a@f4db7e329e71 ancestor a@924404dff337
461 461 merging rev
462 462 my rev@ec03c2ca8642+ other rev@f4db7e329e71 ancestor rev@924404dff337
463 463 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
464 464 (branch merge, don't forget to commit)
465 465 --------------
466 466 M b
467 467 a
468 468 --------------
469 469
470 470 --------------
471 471 test L:nm a b R:up a c W: - 23 get c, keep b
472 472 --------------
473 473 resolving manifests
474 474 overwrite None partial False
475 475 ancestor 924404dff337 local ecf3cb2a4219+ remote 2b958612230f
476 476 searching for copies back to rev 1
477 477 unmatched files in local:
478 478 b
479 479 unmatched files in other:
480 480 c
481 481 all copies found (* = to merge, ! = divergent):
482 482 b -> a *
483 483 checking for directory renames
484 484 b: local moved to a -> m
485 485 rev: versions differ -> m
486 486 c: remote created -> g
487 487 merging b and a
488 488 my b@ecf3cb2a4219+ other a@2b958612230f ancestor a@924404dff337
489 489 getting c
490 490 merging rev
491 491 my rev@ecf3cb2a4219+ other rev@2b958612230f ancestor rev@924404dff337
492 492 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
493 493 (branch merge, don't forget to commit)
494 494 --------------
495 495 M b
496 496 a
497 497 M c
498 498 --------------
499 499
@@ -1,120 +1,120 b''
1 1 hg status in repo root:
2 2 ? a/1/in_a_1
3 3 ? a/in_a
4 4 ? b/1/in_b_1
5 5 ? b/2/in_b_2
6 6 ? b/in_b
7 7 ? in_root
8 8 hg status . in repo root:
9 9 ? a/1/in_a_1
10 10 ? a/in_a
11 11 ? b/1/in_b_1
12 12 ? b/2/in_b_2
13 13 ? b/in_b
14 14 ? in_root
15 15 hg status in a:
16 16 ? a/1/in_a_1
17 17 ? a/in_a
18 18 ? b/1/in_b_1
19 19 ? b/2/in_b_2
20 20 ? b/in_b
21 21 ? in_root
22 22 hg status . in a:
23 23 ? 1/in_a_1
24 24 ? in_a
25 25 hg status .. in a:
26 26 ? 1/in_a_1
27 27 ? in_a
28 28 ? ../b/1/in_b_1
29 29 ? ../b/2/in_b_2
30 30 ? ../b/in_b
31 31 ? ../in_root
32 32 hg status in b:
33 33 ? a/1/in_a_1
34 34 ? a/in_a
35 35 ? b/1/in_b_1
36 36 ? b/2/in_b_2
37 37 ? b/in_b
38 38 ? in_root
39 39 hg status . in b:
40 40 ? 1/in_b_1
41 41 ? 2/in_b_2
42 42 ? in_b
43 43 hg status .. in b:
44 44 ? ../a/1/in_a_1
45 45 ? ../a/in_a
46 46 ? 1/in_b_1
47 47 ? 2/in_b_2
48 48 ? in_b
49 49 ? ../in_root
50 50 hg status in a/1:
51 51 ? a/1/in_a_1
52 52 ? a/in_a
53 53 ? b/1/in_b_1
54 54 ? b/2/in_b_2
55 55 ? b/in_b
56 56 ? in_root
57 57 hg status . in a/1:
58 58 ? in_a_1
59 59 hg status .. in a/1:
60 60 ? in_a_1
61 61 ? ../in_a
62 62 hg status in b/1:
63 63 ? a/1/in_a_1
64 64 ? a/in_a
65 65 ? b/1/in_b_1
66 66 ? b/2/in_b_2
67 67 ? b/in_b
68 68 ? in_root
69 69 hg status . in b/1:
70 70 ? in_b_1
71 71 hg status .. in b/1:
72 72 ? in_b_1
73 73 ? ../2/in_b_2
74 74 ? ../in_b
75 75 hg status in b/2:
76 76 ? a/1/in_a_1
77 77 ? a/in_a
78 78 ? b/1/in_b_1
79 79 ? b/2/in_b_2
80 80 ? b/in_b
81 81 ? in_root
82 82 hg status . in b/2:
83 83 ? in_b_2
84 84 hg status .. in b/2:
85 85 ? ../1/in_b_1
86 86 ? in_b_2
87 87 ? ../in_b
88 88 adding .hgignore
89 89 adding deleted
90 90 adding modified
91 91 adding removed
92 92 hg status:
93 93 A added
94 94 R removed
95 95 ! deleted
96 96 ? unknown
97 97 hg status modified added removed deleted unknown never-existed ignored:
98 98 never-existed: No such file or directory
99 99 A added
100 100 R removed
101 101 ! deleted
102 102 ? ignored
103 103 ? unknown
104 104 hg status -C:
105 105 A added
106 106 A copied
107 107 modified
108 108 R removed
109 109 ! deleted
110 110 ? unknown
111 111 hg status -A:
112 112 A added
113 113 A copied
114 114 modified
115 115 R removed
116 116 ! deleted
117 117 ? unknown
118 118 I ignored
119 C .hgignore
120 C modified
119 = .hgignore
120 = modified
General Comments 0
You need to be logged in to leave comments. Login now