8 from node import hex, nullid, nullrev, short |
8 from node import hex, nullid, nullrev, short |
9 from i18n import _ |
9 from i18n import _ |
10 import os, sys, errno, re, tempfile |
10 import os, sys, errno, re, tempfile |
11 import util, scmutil, templater, patch, error, templatekw, wdutil |
11 import util, scmutil, templater, patch, error, templatekw, wdutil |
12 import match as matchmod |
12 import match as matchmod |
13 import revset, subrepo |
13 import subrepo |
14 |
14 |
15 expandpats = wdutil.expandpats |
15 expandpats = wdutil.expandpats |
16 match = wdutil.match |
16 match = wdutil.match |
17 matchall = wdutil.matchall |
17 matchall = wdutil.matchall |
18 matchfiles = wdutil.matchfiles |
18 matchfiles = wdutil.matchfiles |
19 addremove = wdutil.addremove |
19 addremove = wdutil.addremove |
20 dirstatecopy = wdutil.dirstatecopy |
20 dirstatecopy = wdutil.dirstatecopy |
21 |
|
22 revrangesep = ':' |
|
23 |
21 |
24 def parsealiases(cmd): |
22 def parsealiases(cmd): |
25 return cmd.lstrip("^").split("|") |
23 return cmd.lstrip("^").split("|") |
26 |
24 |
27 def findpossible(cmd, table, strict=False): |
25 def findpossible(cmd, table, strict=False): |
115 if limit <= 0: |
113 if limit <= 0: |
116 raise util.Abort(_('limit must be positive')) |
114 raise util.Abort(_('limit must be positive')) |
117 else: |
115 else: |
118 limit = None |
116 limit = None |
119 return limit |
117 return limit |
120 |
|
121 def revsingle(repo, revspec, default='.'): |
|
122 if not revspec: |
|
123 return repo[default] |
|
124 |
|
125 l = revrange(repo, [revspec]) |
|
126 if len(l) < 1: |
|
127 raise util.Abort(_('empty revision set')) |
|
128 return repo[l[-1]] |
|
129 |
|
130 def revpair(repo, revs): |
|
131 if not revs: |
|
132 return repo.dirstate.p1(), None |
|
133 |
|
134 l = revrange(repo, revs) |
|
135 |
|
136 if len(l) == 0: |
|
137 return repo.dirstate.p1(), None |
|
138 |
|
139 if len(l) == 1: |
|
140 return repo.lookup(l[0]), None |
|
141 |
|
142 return repo.lookup(l[0]), repo.lookup(l[-1]) |
|
143 |
|
144 def revrange(repo, revs): |
|
145 """Yield revision as strings from a list of revision specifications.""" |
|
146 |
|
147 def revfix(repo, val, defval): |
|
148 if not val and val != 0 and defval is not None: |
|
149 return defval |
|
150 return repo.changelog.rev(repo.lookup(val)) |
|
151 |
|
152 seen, l = set(), [] |
|
153 for spec in revs: |
|
154 # attempt to parse old-style ranges first to deal with |
|
155 # things like old-tag which contain query metacharacters |
|
156 try: |
|
157 if isinstance(spec, int): |
|
158 seen.add(spec) |
|
159 l.append(spec) |
|
160 continue |
|
161 |
|
162 if revrangesep in spec: |
|
163 start, end = spec.split(revrangesep, 1) |
|
164 start = revfix(repo, start, 0) |
|
165 end = revfix(repo, end, len(repo) - 1) |
|
166 step = start > end and -1 or 1 |
|
167 for rev in xrange(start, end + step, step): |
|
168 if rev in seen: |
|
169 continue |
|
170 seen.add(rev) |
|
171 l.append(rev) |
|
172 continue |
|
173 elif spec and spec in repo: # single unquoted rev |
|
174 rev = revfix(repo, spec, None) |
|
175 if rev in seen: |
|
176 continue |
|
177 seen.add(rev) |
|
178 l.append(rev) |
|
179 continue |
|
180 except error.RepoLookupError: |
|
181 pass |
|
182 |
|
183 # fall through to new-style queries if old-style fails |
|
184 m = revset.match(repo.ui, spec) |
|
185 for r in m(repo, range(len(repo))): |
|
186 if r not in seen: |
|
187 l.append(r) |
|
188 seen.update(l) |
|
189 |
|
190 return l |
|
191 |
118 |
192 def makefilename(repo, pat, node, |
119 def makefilename(repo, pat, node, |
193 total=None, seqno=None, revwidth=None, pathname=None): |
120 total=None, seqno=None, revwidth=None, pathname=None): |
194 node_expander = { |
121 node_expander = { |
195 'H': lambda: hex(node), |
122 'H': lambda: hex(node), |