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