comparison mercurial/revset.py @ 41359:431cf2c8c839

revset: support ranges in #generations relation
author Anton Shestakov <av6@dwimlabs.net>
date Tue, 15 Jan 2019 22:57:09 +0800
parents b1ea90613af3
children ee7791f2515b
comparison
equal deleted inserted replaced
41358:0a0927f7549d 41359:431cf2c8c839
223 return subset - getset(repo, subset, x, anyorder) 223 return subset - getset(repo, subset, x, anyorder)
224 224
225 def relationset(repo, subset, x, y, order): 225 def relationset(repo, subset, x, y, order):
226 raise error.ParseError(_("can't use a relation in this context")) 226 raise error.ParseError(_("can't use a relation in this context"))
227 227
228 def generationsrel(repo, subset, x, rel, n, order): 228 def _splitrange(a, b):
229 # TODO: support range, rewrite tests, and drop startdepth argument 229 """Split range with bounds a and b into two ranges at 0 and return two
230 # from ancestors() and descendants() predicates 230 tuples of numbers for use as startdepth and stopdepth arguments of
231 if n <= 0: 231 revancestors and revdescendants.
232 n = -n 232
233 return _ancestors(repo, subset, x, startdepth=n, stopdepth=n + 1) 233 >>> _splitrange(-10, -5) # [-10:-5]
234 else: 234 ((5, 11), (None, None))
235 return _descendants(repo, subset, x, startdepth=n, stopdepth=n + 1) 235 >>> _splitrange(5, 10) # [5:10]
236 ((None, None), (5, 11))
237 >>> _splitrange(-10, 10) # [-10:10]
238 ((0, 11), (0, 11))
239 >>> _splitrange(-10, 0) # [-10:0]
240 ((0, 11), (None, None))
241 >>> _splitrange(0, 10) # [0:10]
242 ((None, None), (0, 11))
243 >>> _splitrange(0, 0) # [0:0]
244 ((0, 1), (None, None))
245 >>> _splitrange(1, -1) # [1:-1]
246 ((None, None), (None, None))
247 """
248 ancdepths = (None, None)
249 descdepths = (None, None)
250 if a == b == 0:
251 ancdepths = (0, 1)
252 if a < 0:
253 ancdepths = (-min(b, 0), -a + 1)
254 if b > 0:
255 descdepths = (max(a, 0), b + 1)
256 return ancdepths, descdepths
257
258 def generationsrel(repo, subset, x, rel, a, b, order):
259 # TODO: rewrite tests, and drop startdepth argument from ancestors() and
260 # descendants() predicates
261 (ancstart, ancstop), (descstart, descstop) = _splitrange(a, b)
262
263 if ancstart is None and descstart is None:
264 return baseset()
265
266 revs = getset(repo, fullreposet(repo), x)
267 if not revs:
268 return baseset()
269
270 if ancstart is not None and descstart is not None:
271 s = dagop.revancestors(repo, revs, False, ancstart, ancstop)
272 s += dagop.revdescendants(repo, revs, False, descstart, descstop)
273 elif ancstart is not None:
274 s = dagop.revancestors(repo, revs, False, ancstart, ancstop)
275 elif descstart is not None:
276 s = dagop.revdescendants(repo, revs, False, descstart, descstop)
277
278 return subset & s
236 279
237 def relsubscriptset(repo, subset, x, y, z, order): 280 def relsubscriptset(repo, subset, x, y, z, order):
238 # this is pretty basic implementation of 'x#y[z]' operator, still 281 # this is pretty basic implementation of 'x#y[z]' operator, still
239 # experimental so undocumented. see the wiki for further ideas. 282 # experimental so undocumented. see the wiki for further ideas.
240 # https://www.mercurial-scm.org/wiki/RevsetOperatorPlan 283 # https://www.mercurial-scm.org/wiki/RevsetOperatorPlan
241 rel = getsymbol(y) 284 rel = getsymbol(y)
242 n = getinteger(z, _("relation subscript must be an integer")) 285 try:
286 a, b = getrange(z, '')
287 except error.ParseError:
288 a = getinteger(z, _("relation subscript must be an integer"))
289 b = a
290 else:
291 def getbound(i):
292 if i is None:
293 return None
294 msg = _("relation subscript bounds must be integers")
295 return getinteger(i, msg)
296 a, b = [getbound(i) for i in (a, b)]
297 if a is None:
298 a = -(dagop.maxlogdepth - 1)
299 if b is None:
300 b = +(dagop.maxlogdepth - 1)
243 301
244 if rel in subscriptrelations: 302 if rel in subscriptrelations:
245 return subscriptrelations[rel](repo, subset, x, rel, n, order) 303 return subscriptrelations[rel](repo, subset, x, rel, a, b, order)
246 304
247 relnames = [r for r in subscriptrelations.keys() if len(r) > 1] 305 relnames = [r for r in subscriptrelations.keys() if len(r) > 1]
248 raise error.UnknownIdentifier(rel, relnames) 306 raise error.UnknownIdentifier(rel, relnames)
249 307
250 def subscriptset(repo, subset, x, y, order): 308 def subscriptset(repo, subset, x, y, order):