Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/commands.py @ 580:353a2ce50423
[PATCH] New export patch
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
[PATCH] New export patch
From: Bryan O'Sullivan <bos@serpentine.com>
Modify export command to accept rev ranges and output file spec.
It can now export a range of revisions, and print exported patches
to files whose names are generated using format strings.
manifest hash: e0085c205cdc31a168bcd25c85772ef00d53031d
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCx02iywK+sNU5EO8RAtCKAJ0V2K9+i1OGa27KyC5/nq3m+OdvtgCgpnav
3vfEODMzJVOZoJt9wzI1UCg=
=YAdI
-----END PGP SIGNATURE-----
author | mpm@selenic.com |
---|---|
date | Sat, 02 Jul 2005 18:29:54 -0800 |
parents | 5291a16324c0 |
children | df8a5a0098d4 |
comparison
equal
deleted
inserted
replaced
579:ffeb2c3a1966 | 580:353a2ce50423 |
---|---|
31 p = os.getcwd()[len(repo.root) + 1: ] | 31 p = os.getcwd()[len(repo.root) + 1: ] |
32 return [ util.pconvert(os.path.normpath(os.path.join(p, x))) | 32 return [ util.pconvert(os.path.normpath(os.path.join(p, x))) |
33 for x in args ] | 33 for x in args ] |
34 return args | 34 return args |
35 | 35 |
36 def dodiff(ui, repo, files = None, node1 = None, node2 = None): | 36 revrangesep = ':' |
37 | |
38 def revrange(ui, repo, revs = [], revlog = None): | |
39 if revlog is None: | |
40 revlog = repo.changelog | |
41 revcount = revlog.count() | |
42 def fix(val, defval): | |
43 if not val: return defval | |
44 try: | |
45 num = int(val) | |
46 if str(num) != val: raise ValueError | |
47 if num < 0: num += revcount | |
48 if not (0 <= num < revcount): | |
49 raise ValueError | |
50 except ValueError: | |
51 try: | |
52 num = repo.changelog.rev(repo.lookup(val)) | |
53 except KeyError: | |
54 try: | |
55 num = revlog.rev(revlog.lookup(val)) | |
56 except KeyError: | |
57 ui.warn('abort: invalid revision identifier %s\n' % val) | |
58 sys.exit(1) | |
59 return num | |
60 for spec in revs: | |
61 if spec.find(revrangesep) >= 0: | |
62 start, end = spec.split(revrangesep, 1) | |
63 start = fix(start, 0) | |
64 end = fix(end, revcount - 1) | |
65 if end > start: | |
66 end += 1 | |
67 step = 1 | |
68 else: | |
69 end -= 1 | |
70 step = -1 | |
71 for rev in xrange(start, end, step): | |
72 yield str(rev) | |
73 else: | |
74 yield spec | |
75 | |
76 def dodiff(fp, ui, repo, files = None, node1 = None, node2 = None): | |
37 def date(c): | 77 def date(c): |
38 return time.asctime(time.gmtime(float(c[2].split(' ')[0]))) | 78 return time.asctime(time.gmtime(float(c[2].split(' ')[0]))) |
39 | 79 |
40 (c, a, d, u) = repo.changes(node1, node2, files) | 80 (c, a, d, u) = repo.changes(node1, node2, files) |
41 if files: | 81 if files: |
68 for f in c: | 108 for f in c: |
69 to = None | 109 to = None |
70 if f in mmap: | 110 if f in mmap: |
71 to = repo.file(f).read(mmap[f]) | 111 to = repo.file(f).read(mmap[f]) |
72 tn = read(f) | 112 tn = read(f) |
73 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r)) | 113 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r)) |
74 for f in a: | 114 for f in a: |
75 to = None | 115 to = None |
76 tn = read(f) | 116 tn = read(f) |
77 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r)) | 117 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r)) |
78 for f in d: | 118 for f in d: |
79 to = repo.file(f).read(mmap[f]) | 119 to = repo.file(f).read(mmap[f]) |
80 tn = None | 120 tn = None |
81 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r)) | 121 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r)) |
82 | 122 |
83 def show_changeset(ui, repo, rev=0, changenode=None, filelog=None): | 123 def show_changeset(ui, repo, rev=0, changenode=None, filelog=None): |
84 """show a single changeset or file revision""" | 124 """show a single changeset or file revision""" |
85 changelog = repo.changelog | 125 changelog = repo.changelog |
86 if filelog: | 126 if filelog: |
419 if files: | 459 if files: |
420 files = relpath(repo, files) | 460 files = relpath(repo, files) |
421 else: | 461 else: |
422 files = relpath(repo, [""]) | 462 files = relpath(repo, [""]) |
423 | 463 |
424 dodiff(ui, repo, files, *revs) | 464 dodiff(sys.stdout, ui, repo, files, *revs) |
425 | 465 |
426 def export(ui, repo, changeset): | 466 def doexport(ui, repo, changeset, seqno, total, revwidth, opts): |
427 """dump the changeset header and diffs for a revision""" | |
428 node = repo.lookup(changeset) | 467 node = repo.lookup(changeset) |
429 prev, other = repo.changelog.parents(node) | 468 prev, other = repo.changelog.parents(node) |
430 change = repo.changelog.read(node) | 469 change = repo.changelog.read(node) |
431 print "# HG changeset patch" | 470 |
432 print "# User %s" % change[1] | 471 def expand(name): |
433 print "# Node ID %s" % hg.hex(node) | 472 expansions = { |
434 print "# Parent %s" % hg.hex(prev) | 473 '%': lambda: '%', |
435 print | 474 'H': lambda: hg.hex(node), |
475 'N': lambda: str(total), | |
476 'R': lambda: str(repo.changelog.rev(node)), | |
477 'b': lambda: os.path.basename(repo.root), | |
478 'h': lambda: hg.short(node), | |
479 'n': lambda: str(seqno).zfill(len(str(total))), | |
480 'r': lambda: str(repo.changelog.rev(node)).zfill(revwidth), | |
481 } | |
482 newname = [] | |
483 namelen = len(name) | |
484 i = 0 | |
485 while i < namelen: | |
486 c = name[i] | |
487 if c == '%': | |
488 i += 1 | |
489 c = name[i] | |
490 c = expansions[c]() | |
491 newname.append(c) | |
492 i += 1 | |
493 return ''.join(newname) | |
494 | |
495 if opts['output'] and opts['output'] != '-': | |
496 try: | |
497 fp = open(expand(opts['output']), 'w') | |
498 except KeyError, inst: | |
499 ui.warn("error: invalid format spec '%%%s' in output file name\n" % | |
500 inst.args[0]) | |
501 sys.exit(1) | |
502 else: | |
503 fp = sys.stdout | |
504 | |
505 print >> fp, "# HG changeset patch" | |
506 print >> fp, "# User %s" % change[1] | |
507 print >> fp, "# Node ID %s" % hg.hex(node) | |
508 print >> fp, "# Parent %s" % hg.hex(prev) | |
509 print >> fp | |
436 if other != hg.nullid: | 510 if other != hg.nullid: |
437 print "# Parent %s" % hg.hex(other) | 511 print >> fp, "# Parent %s" % hg.hex(other) |
438 print change[4].rstrip() | 512 print >> fp, change[4].rstrip() |
439 print | 513 print >> fp |
440 | 514 |
441 dodiff(ui, repo, None, prev, node) | 515 dodiff(fp, ui, repo, None, prev, node) |
516 | |
517 def export(ui, repo, *changesets, **opts): | |
518 """dump the header and diffs for one or more changesets""" | |
519 seqno = 0 | |
520 revs = list(revrange(ui, repo, changesets)) | |
521 total = len(revs) | |
522 revwidth = max(len(revs[0]), len(revs[-1])) | |
523 for cset in revs: | |
524 seqno += 1 | |
525 doexport(ui, repo, cset, seqno, total, revwidth, opts) | |
442 | 526 |
443 def forget(ui, repo, file, *files): | 527 def forget(ui, repo, file, *files): |
444 """don't add the specified files on the next commit""" | 528 """don't add the specified files on the next commit""" |
445 repo.forget(relpath(repo, (file,) + files)) | 529 repo.forget(relpath(repo, (file,) + files)) |
446 | 530 |
583 cg = other.changegroup(fetch) | 667 cg = other.changegroup(fetch) |
584 r = repo.addchangegroup(cg) | 668 r = repo.addchangegroup(cg) |
585 if cg and not r: | 669 if cg and not r: |
586 if opts['update']: | 670 if opts['update']: |
587 return update(ui, repo) | 671 return update(ui, repo) |
588 else: | 672 else: |
589 ui.status("(run 'hg update' to get a working copy)\n") | 673 ui.status("(run 'hg update' to get a working copy)\n") |
590 | 674 |
591 return r | 675 return r |
592 | 676 |
593 def push(ui, repo, dest="default-push"): | 677 def push(ui, repo, dest="default-push"): |
677 | 761 |
678 def tag(ui, repo, name, rev = None, **opts): | 762 def tag(ui, repo, name, rev = None, **opts): |
679 """add a tag for the current tip or a given revision""" | 763 """add a tag for the current tip or a given revision""" |
680 | 764 |
681 if name == "tip": | 765 if name == "tip": |
682 ui.warn("abort: 'tip' is a reserved name!\n") | 766 ui.warn("abort: 'tip' is a reserved name!\n") |
683 return -1 | 767 return -1 |
768 if name.find(revrangesep) >= 0: | |
769 ui.warn("abort: '%s' cannot be used in a tag name\n" % revrangesep) | |
770 return -1 | |
684 | 771 |
685 (c, a, d, u) = repo.changes(None, None) | 772 (c, a, d, u) = repo.changes(None, None) |
686 for x in (c, a, d, u): | 773 for x in (c, a, d, u): |
687 if ".hgtags" in x: | 774 if ".hgtags" in x: |
688 ui.warn("abort: working copy of .hgtags is changed!\n") | 775 ui.warn("abort: working copy of .hgtags is changed!\n") |
689 ui.status("(please commit .hgtags manually)\n") | 776 ui.status("(please commit .hgtags manually)\n") |
690 return -1 | 777 return -1 |
691 | 778 |
692 if rev: | 779 if rev: |
693 r = hg.hex(repo.lookup(rev)) | 780 r = hg.hex(repo.lookup(rev)) |
694 else: | 781 else: |
695 r = hg.hex(repo.changelog.tip()) | 782 r = hg.hex(repo.changelog.tip()) |
771 "debugdumpdirstate": (debugdumpdirstate, [], 'debugdumpdirstate'), | 858 "debugdumpdirstate": (debugdumpdirstate, [], 'debugdumpdirstate'), |
772 "debugindex": (debugindex, [], 'debugindex <file>'), | 859 "debugindex": (debugindex, [], 'debugindex <file>'), |
773 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'), | 860 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'), |
774 "diff": (diff, [('r', 'rev', [], 'revision')], | 861 "diff": (diff, [('r', 'rev', [], 'revision')], |
775 'hg diff [-r A] [-r B] [files]'), | 862 'hg diff [-r A] [-r B] [files]'), |
776 "export": (export, [], "hg export <changeset>"), | 863 "export": (export, [('o', 'output', "", 'output to file')], |
864 "hg export [-o file] <changeset> ..."), | |
777 "forget": (forget, [], "hg forget [files]"), | 865 "forget": (forget, [], "hg forget [files]"), |
778 "heads": (heads, [], 'hg heads'), | 866 "heads": (heads, [], 'hg heads'), |
779 "help": (help, [], 'hg help [command]'), | 867 "help": (help, [], 'hg help [command]'), |
780 "identify|id": (identify, [], 'hg identify'), | 868 "identify|id": (identify, [], 'hg identify'), |
781 "import|patch": (import_, | 869 "import|patch": (import_, |
788 'hg log [-r A] [-r B] [file]'), | 876 'hg log [-r A] [-r B] [file]'), |
789 "manifest": (manifest, [], 'hg manifest [rev]'), | 877 "manifest": (manifest, [], 'hg manifest [rev]'), |
790 "parents": (parents, [], 'hg parents [node]'), | 878 "parents": (parents, [], 'hg parents [node]'), |
791 "pull": (pull, | 879 "pull": (pull, |
792 [('u', 'update', None, 'update working directory')], | 880 [('u', 'update', None, 'update working directory')], |
793 'hg pull [options] [source]'), | 881 'hg pull [options] [source]'), |
794 "push": (push, [], 'hg push <destination>'), | 882 "push": (push, [], 'hg push <destination>'), |
795 "rawcommit": (rawcommit, | 883 "rawcommit": (rawcommit, |
796 [('p', 'parent', [], 'parent'), | 884 [('p', 'parent', [], 'parent'), |
797 ('d', 'date', "", 'data'), | 885 ('d', 'date', "", 'data'), |
798 ('u', 'user', "", 'user'), | 886 ('u', 'user', "", 'user'), |
941 u.debug(inst, "\n") | 1029 u.debug(inst, "\n") |
942 u.warn("%s: invalid arguments\n" % i[0].__name__) | 1030 u.warn("%s: invalid arguments\n" % i[0].__name__) |
943 help(u, cmd) | 1031 help(u, cmd) |
944 | 1032 |
945 sys.exit(-1) | 1033 sys.exit(-1) |
946 |