mercurial/revset.py
changeset 49447 6dbe74669eba
parent 49279 127d33e63d1a
child 49510 e02dcc625171
equal deleted inserted replaced
49445:cd21f2b4226f 49447:6dbe74669eba
     5 # This software may be used and distributed according to the terms of the
     5 # This software may be used and distributed according to the terms of the
     6 # GNU General Public License version 2 or any later version.
     6 # GNU General Public License version 2 or any later version.
     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
    14 from .node import (
    17 from .node import (
    15     bin,
    18     bin,
  2345         return True
  2348         return True
  2346 
  2349 
  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(),
  2353     b'desc': lambda c: c.description(),
  2365     b'desc': lambda c: c.description(),
  2354     b'user': lambda c: c.user(),
  2366     b'user': lambda c: c.user(),
  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'))
  2367     keys = b"rev"
  2384     keys = b"rev"
  2368     if b'keys' in args:
  2385     if b'keys' in args:
  2398                     b'topo.firstbranch can only be used '
  2415                     b'topo.firstbranch can only be used '
  2399                     b'when using the topo sort key'
  2416                     b'when using the topo sort key'
  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 
  2406 @predicate(
  2437 @predicate(
  2407     b'sort(set[, [-]key... [, ...]])', safe=True, takeorder=True, weight=10
  2438     b'sort(set[, [-]key... [, ...]])', safe=True, takeorder=True, weight=10
  2417     - ``desc`` for the commit message (description),
  2448     - ``desc`` for the commit message (description),
  2418     - ``user`` for user name (``author`` can be used as an alias),
  2449     - ``user`` for user name (``author`` can be used as an alias),
  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)
  2430 
  2464 
  2431     if not keyflags or order != defineorder:
  2465     if not keyflags or order != defineorder:
  2446         return revs
  2480         return revs
  2447 
  2481 
  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 
  2455 @predicate(b'subrepo([pattern])')
  2494 @predicate(b'subrepo([pattern])')
  2456 def subrepo(repo, subset, x):
  2495 def subrepo(repo, subset, x):