##// END OF EJS Templates
revset: support ranges in #generations relation
av6 -
r41395:431cf2c8 default
parent child Browse files
Show More
@@ -28,7 +28,7 b' baseset = smartset.baseset'
28 generatorset = smartset.generatorset
28 generatorset = smartset.generatorset
29
29
30 # possible maximum depth between null and wdir()
30 # possible maximum depth between null and wdir()
31 _maxlogdepth = 0x80000000
31 maxlogdepth = 0x80000000
32
32
33 def _walkrevtree(pfunc, revs, startdepth, stopdepth, reverse):
33 def _walkrevtree(pfunc, revs, startdepth, stopdepth, reverse):
34 """Walk DAG using 'pfunc' from the given 'revs' nodes
34 """Walk DAG using 'pfunc' from the given 'revs' nodes
@@ -42,7 +42,7 b' def _walkrevtree(pfunc, revs, startdepth'
42 if startdepth is None:
42 if startdepth is None:
43 startdepth = 0
43 startdepth = 0
44 if stopdepth is None:
44 if stopdepth is None:
45 stopdepth = _maxlogdepth
45 stopdepth = maxlogdepth
46 if stopdepth == 0:
46 if stopdepth == 0:
47 return
47 return
48 if stopdepth < 0:
48 if stopdepth < 0:
@@ -221,7 +221,7 b' def revdescendants(repo, revs, followfir'
221 Scan ends at the stopdepth (exlusive) if specified. Revisions found
221 Scan ends at the stopdepth (exlusive) if specified. Revisions found
222 earlier than the startdepth are omitted.
222 earlier than the startdepth are omitted.
223 """
223 """
224 if startdepth is None and stopdepth is None:
224 if startdepth is None and (stopdepth is None or stopdepth == maxlogdepth):
225 gen = _genrevdescendants(repo, revs, followfirst)
225 gen = _genrevdescendants(repo, revs, followfirst)
226 else:
226 else:
227 gen = _genrevdescendantsofdepth(repo, revs, followfirst,
227 gen = _genrevdescendantsofdepth(repo, revs, followfirst,
@@ -225,24 +225,82 b' def notset(repo, subset, x, order):'
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)
@@ -62,6 +62,7 b" testmod('mercurial.parser')"
62 testmod('mercurial.pycompat')
62 testmod('mercurial.pycompat')
63 testmod('mercurial.revlog')
63 testmod('mercurial.revlog')
64 testmod('mercurial.revlogutils.deltas')
64 testmod('mercurial.revlogutils.deltas')
65 testmod('mercurial.revset')
65 testmod('mercurial.revsetlang')
66 testmod('mercurial.revsetlang')
66 testmod('mercurial.smartset')
67 testmod('mercurial.smartset')
67 testmod('mercurial.store')
68 testmod('mercurial.store')
@@ -648,6 +648,9 b' parse errors of relation, subscript and '
648 $ hg debugrevspec '.#generations[1-2]'
648 $ hg debugrevspec '.#generations[1-2]'
649 hg: parse error: relation subscript must be an integer
649 hg: parse error: relation subscript must be an integer
650 [255]
650 [255]
651 $ hg debugrevspec '.#generations[foo:bar]'
652 hg: parse error: relation subscript bounds must be integers
653 [255]
651
654
652 suggested relations
655 suggested relations
653
656
@@ -1274,6 +1277,30 b' test ancestors/descendants relation subs'
1274 $ log '.#g[(-1)]'
1277 $ log '.#g[(-1)]'
1275 8
1278 8
1276
1279
1280 $ log '6#generations[0:1]'
1281 6
1282 7
1283 $ log '6#generations[-1:1]'
1284 4
1285 5
1286 6
1287 7
1288 $ log '6#generations[0:]'
1289 6
1290 7
1291 $ log '5#generations[:0]'
1292 0
1293 1
1294 3
1295 5
1296 $ log '3#generations[:]'
1297 0
1298 1
1299 3
1300 5
1301 6
1302 7
1303
1277 $ hg debugrevspec -p parsed 'roots(:)#g[2]'
1304 $ hg debugrevspec -p parsed 'roots(:)#g[2]'
1278 * parsed:
1305 * parsed:
1279 (relsubscript
1306 (relsubscript
General Comments 0
You need to be logged in to leave comments. Login now