8 from demandload import demandload |
8 from demandload import demandload |
9 from node import * |
9 from node import * |
10 from i18n import gettext as _ |
10 from i18n import gettext as _ |
11 demandload(globals(), 'mdiff util') |
11 demandload(globals(), 'mdiff util') |
12 demandload(globals(), 'os sys') |
12 demandload(globals(), 'os sys') |
|
13 |
|
14 revrangesep = ':' |
|
15 |
|
16 def revfix(repo, val, defval): |
|
17 '''turn user-level id of changeset into rev number. |
|
18 user-level id can be tag, changeset, rev number, or negative rev |
|
19 number relative to number of revs (-1 is tip, etc).''' |
|
20 if not val: |
|
21 return defval |
|
22 try: |
|
23 num = int(val) |
|
24 if str(num) != val: |
|
25 raise ValueError |
|
26 if num < 0: |
|
27 num += repo.changelog.count() |
|
28 if num < 0: |
|
29 num = 0 |
|
30 elif num >= repo.changelog.count(): |
|
31 raise ValueError |
|
32 except ValueError: |
|
33 try: |
|
34 num = repo.changelog.rev(repo.lookup(val)) |
|
35 except KeyError: |
|
36 raise util.Abort(_('invalid revision identifier %s') % val) |
|
37 return num |
|
38 |
|
39 def revpair(ui, repo, revs): |
|
40 '''return pair of nodes, given list of revisions. second item can |
|
41 be None, meaning use working dir.''' |
|
42 if not revs: |
|
43 return repo.dirstate.parents()[0], None |
|
44 end = None |
|
45 if len(revs) == 1: |
|
46 start = revs[0] |
|
47 if revrangesep in start: |
|
48 start, end = start.split(revrangesep, 1) |
|
49 start = revfix(repo, start, 0) |
|
50 end = revfix(repo, end, repo.changelog.count() - 1) |
|
51 else: |
|
52 start = revfix(repo, start, None) |
|
53 elif len(revs) == 2: |
|
54 if revrangesep in revs[0] or revrangesep in revs[1]: |
|
55 raise util.Abort(_('too many revisions specified')) |
|
56 start = revfix(repo, revs[0], None) |
|
57 end = revfix(repo, revs[1], None) |
|
58 else: |
|
59 raise util.Abort(_('too many revisions specified')) |
|
60 if end is not None: end = repo.lookup(str(end)) |
|
61 return repo.lookup(str(start)), end |
|
62 |
|
63 def revrange(ui, repo, revs): |
|
64 """Yield revision as strings from a list of revision specifications.""" |
|
65 seen = {} |
|
66 for spec in revs: |
|
67 if revrangesep in spec: |
|
68 start, end = spec.split(revrangesep, 1) |
|
69 start = revfix(repo, start, 0) |
|
70 end = revfix(repo, end, repo.changelog.count() - 1) |
|
71 step = start > end and -1 or 1 |
|
72 for rev in xrange(start, end+step, step): |
|
73 if rev in seen: |
|
74 continue |
|
75 seen[rev] = 1 |
|
76 yield str(rev) |
|
77 else: |
|
78 rev = revfix(repo, spec, None) |
|
79 if rev in seen: |
|
80 continue |
|
81 seen[rev] = 1 |
|
82 yield str(rev) |
13 |
83 |
14 def make_filename(repo, pat, node, |
84 def make_filename(repo, pat, node, |
15 total=None, seqno=None, revwidth=None, pathname=None): |
85 total=None, seqno=None, revwidth=None, pathname=None): |
16 node_expander = { |
86 node_expander = { |
17 'H': lambda: hex(node), |
87 'H': lambda: hex(node), |