##// END OF EJS Templates
sort-revset: introduce a `random` variant...
marmoute -
r50342:6dbe7466 default
parent child Browse files
Show More
@@ -7,7 +7,10 b''
7
7
8
8
9 import binascii
9 import binascii
10 import functools
11 import random
10 import re
12 import re
13 import sys
11
14
12 from .i18n import _
15 from .i18n import _
13 from .pycompat import getattr
16 from .pycompat import getattr
@@ -2347,6 +2350,15 b' def roots(repo, subset, x):'
2347 return subset & s.filter(filter, condrepr=b'<roots>')
2350 return subset & s.filter(filter, condrepr=b'<roots>')
2348
2351
2349
2352
2353 MAXINT = sys.maxsize
2354 MININT = -MAXINT - 1
2355
2356
2357 def pick_random(c, gen=random):
2358 # exists as its own function to make it possible to overwrite the seed
2359 return gen.randint(MININT, MAXINT)
2360
2361
2350 _sortkeyfuncs = {
2362 _sortkeyfuncs = {
2351 b'rev': scmutil.intrev,
2363 b'rev': scmutil.intrev,
2352 b'branch': lambda c: c.branch(),
2364 b'branch': lambda c: c.branch(),
@@ -2355,12 +2367,17 b' def roots(repo, subset, x):'
2355 b'author': lambda c: c.user(),
2367 b'author': lambda c: c.user(),
2356 b'date': lambda c: c.date()[0],
2368 b'date': lambda c: c.date()[0],
2357 b'node': scmutil.binnode,
2369 b'node': scmutil.binnode,
2370 b'random': pick_random,
2358 }
2371 }
2359
2372
2360
2373
2361 def _getsortargs(x):
2374 def _getsortargs(x):
2362 """Parse sort options into (set, [(key, reverse)], opts)"""
2375 """Parse sort options into (set, [(key, reverse)], opts)"""
2363 args = getargsdict(x, b'sort', b'set keys topo.firstbranch')
2376 args = getargsdict(
2377 x,
2378 b'sort',
2379 b'set keys topo.firstbranch random.seed',
2380 )
2364 if b'set' not in args:
2381 if b'set' not in args:
2365 # i18n: "sort" is a keyword
2382 # i18n: "sort" is a keyword
2366 raise error.ParseError(_(b'sort requires one or two arguments'))
2383 raise error.ParseError(_(b'sort requires one or two arguments'))
@@ -2400,6 +2417,20 b' def _getsortargs(x):'
2400 )
2417 )
2401 )
2418 )
2402
2419
2420 if b'random.seed' in args:
2421 if any(k == b'random' for k, reverse in keyflags):
2422 s = args[b'random.seed']
2423 seed = getstring(s, _(b"random.seed must be a string"))
2424 opts[b'random.seed'] = seed
2425 else:
2426 # i18n: "random" and "random.seed" are keywords
2427 raise error.ParseError(
2428 _(
2429 b'random.seed can only be used '
2430 b'when using the random sort key'
2431 )
2432 )
2433
2403 return args[b'set'], keyflags, opts
2434 return args[b'set'], keyflags, opts
2404
2435
2405
2436
@@ -2419,11 +2450,14 b' def sort(repo, subset, x, order):'
2419 - ``date`` for the commit date
2450 - ``date`` for the commit date
2420 - ``topo`` for a reverse topographical sort
2451 - ``topo`` for a reverse topographical sort
2421 - ``node`` the nodeid of the revision
2452 - ``node`` the nodeid of the revision
2453 - ``random`` randomly shuffle revisions
2422
2454
2423 The ``topo`` sort order cannot be combined with other sort keys. This sort
2455 The ``topo`` sort order cannot be combined with other sort keys. This sort
2424 takes one optional argument, ``topo.firstbranch``, which takes a revset that
2456 takes one optional argument, ``topo.firstbranch``, which takes a revset that
2425 specifies what topographical branches to prioritize in the sort.
2457 specifies what topographical branches to prioritize in the sort.
2426
2458
2459 The ``random`` sort takes one optional ``random.seed`` argument to control
2460 the pseudo-randomness of the result.
2427 """
2461 """
2428 s, keyflags, opts = _getsortargs(x)
2462 s, keyflags, opts = _getsortargs(x)
2429 revs = getset(repo, subset, s, order)
2463 revs = getset(repo, subset, s, order)
@@ -2448,7 +2482,12 b' def sort(repo, subset, x, order):'
2448 # sort() is guaranteed to be stable
2482 # sort() is guaranteed to be stable
2449 ctxs = [repo[r] for r in revs]
2483 ctxs = [repo[r] for r in revs]
2450 for k, reverse in reversed(keyflags):
2484 for k, reverse in reversed(keyflags):
2451 ctxs.sort(key=_sortkeyfuncs[k], reverse=reverse)
2485 func = _sortkeyfuncs[k]
2486 if k == b'random' and b'random.seed' in opts:
2487 seed = opts[b'random.seed']
2488 r = random.Random(seed)
2489 func = functools.partial(func, gen=r)
2490 ctxs.sort(key=func, reverse=reverse)
2452 return baseset([c.rev() for c in ctxs])
2491 return baseset([c.rev() for c in ctxs])
2453
2492
2454
2493
@@ -2974,6 +2974,25 b' test sorting by multiple keys including '
2974 1 b11 m12 u111 112 7200
2974 1 b11 m12 u111 112 7200
2975 0 b12 m111 u112 111 10800
2975 0 b12 m111 u112 111 10800
2976
2976
2977 random sort
2978
2979 $ hg log --rev 'sort(all(), "random")' | wc -l
2980 \s*8 (re)
2981 $ hg log --rev 'sort(all(), "-random")' | wc -l
2982 \s*8 (re)
2983 $ hg log --rev 'sort(all(), "random", random.seed=celeste)'
2984 6 b111 t2 tu 130 0
2985 7 b111 t3 tu 130 0
2986 4 b111 m112 u111 110 14400
2987 3 b112 m111 u11 120 0
2988 5 b111 t1 tu 130 0
2989 0 b12 m111 u112 111 10800
2990 1 b11 m12 u111 112 7200
2991 2 b111 m11 u12 111 3600
2992 $ hg log --rev 'first(sort(all(), "random", random.seed=celeste))'
2993 6 b111 t2 tu 130 0
2994
2995
2977 topographical sorting can't be combined with other sort keys, and you can't
2996 topographical sorting can't be combined with other sort keys, and you can't
2978 use the topo.firstbranch option when topo sort is not active:
2997 use the topo.firstbranch option when topo sort is not active:
2979
2998
General Comments 0
You need to be logged in to leave comments. Login now