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