mercurial/revset.py
changeset 16402 1fb2f1400ea8
parent 16218 81a1a00f5738
child 16409 2cbd7dd0cc1f
equal deleted inserted replaced
16401:c292bbbcf10c 16402:1fb2f1400ea8
   856     except (TypeError, ValueError):
   856     except (TypeError, ValueError):
   857         # i18n: "rev" is a keyword
   857         # i18n: "rev" is a keyword
   858         raise error.ParseError(_("rev expects a number"))
   858         raise error.ParseError(_("rev expects a number"))
   859     return [r for r in subset if r == l]
   859     return [r for r in subset if r == l]
   860 
   860 
       
   861 def matching(repo, subset, x):
       
   862     """``matching(revision [, field])``
       
   863     Changesets in which a given set of fields match the set of fields in the
       
   864     selected revision or set.
       
   865     To match more than one field pass the list of fields to match separated
       
   866     by spaces (e.g. 'author description').
       
   867     Valid fields are most regular revision fields and some special fields:
       
   868     * regular fields:
       
   869       - description, author, branch, date, files, phase, parents,
       
   870       substate, user.
       
   871       Note that author and user are synonyms.
       
   872     * special fields: summary, metadata.
       
   873       - summary: matches the first line of the description.
       
   874       - metatadata: It is equivalent to matching 'description user date'
       
   875         (i.e. it matches the main metadata fields).
       
   876     metadata is the default field which is used when no fields are specified.
       
   877     You can match more than one field at a time.
       
   878     """
       
   879     l = getargs(x, 1, 2, _("matching takes 1 or 2 arguments"))
       
   880 
       
   881     revs = getset(repo, xrange(len(repo)), l[0])
       
   882 
       
   883     fieldlist = ['metadata']
       
   884     if len(l) > 1:
       
   885             fieldlist = getstring(l[1],
       
   886                 _("matching requires a string "
       
   887                 "as its second argument")).split()
       
   888 
       
   889     # Make sure that there are no repeated fields, and expand the
       
   890     # 'special' 'metadata' field type
       
   891     fields = []
       
   892     for field in fieldlist:
       
   893         if field == 'metadata':
       
   894             fields += ['user', 'description', 'date']
       
   895         else:
       
   896             if field == 'author':
       
   897                 field = 'user'
       
   898             fields.append(field)
       
   899     fields = set(fields)
       
   900 
       
   901     # We may want to match more than one field
       
   902     # Each field will be matched with its own "getfield" function
       
   903     # which will be added to the getfieldfuncs array of functions
       
   904     getfieldfuncs = []
       
   905     _funcs = {
       
   906         'user': lambda r: repo[r].user(),
       
   907         'branch': lambda r: repo[r].branch(),
       
   908         'date': lambda r: repo[r].date(),
       
   909         'description': lambda r: repo[r].description(),
       
   910         'files': lambda r: repo[r].files(),
       
   911         'parents': lambda r: repo[r].parents(),
       
   912         'phase': lambda r: repo[r].phase(),
       
   913         'substate': lambda r: repo[r].substate,
       
   914         'summary': lambda r: repo[r].description().splitlines()[0],
       
   915     }
       
   916     for info in fields:
       
   917         getfield = _funcs.get(info, None)
       
   918         if getfield is None:
       
   919             raise error.ParseError(
       
   920                 _("unexpected field name passed to matching: %s") % info)
       
   921         getfieldfuncs.append(getfield)
       
   922 
       
   923     # convert the getfield array of functions into a "getinfo" function
       
   924     # which returns an array of field values (or a single value if there
       
   925     # is only one field to match)
       
   926     if len(getfieldfuncs) == 1:
       
   927         getinfo = getfieldfuncs[0]
       
   928     else:
       
   929         getinfo = lambda r: [f(r) for f in getfieldfuncs]
       
   930 
       
   931     matches = []
       
   932     for rev in revs:
       
   933         target = getinfo(rev)
       
   934         matches += [r for r in subset if getinfo(r) == target]
       
   935     if len(revs) > 1:
       
   936         matches = sorted(set(matches))
       
   937     return matches
       
   938 
   861 def reverse(repo, subset, x):
   939 def reverse(repo, subset, x):
   862     """``reverse(set)``
   940     """``reverse(set)``
   863     Reverse order of set.
   941     Reverse order of set.
   864     """
   942     """
   865     l = getset(repo, subset, x)
   943     l = getset(repo, subset, x)
  1017     "rev": rev,
  1095     "rev": rev,
  1018     "reverse": reverse,
  1096     "reverse": reverse,
  1019     "roots": roots,
  1097     "roots": roots,
  1020     "sort": sort,
  1098     "sort": sort,
  1021     "secret": secret,
  1099     "secret": secret,
       
  1100     "matching": matching,
  1022     "tag": tag,
  1101     "tag": tag,
  1023     "tagged": tagged,
  1102     "tagged": tagged,
  1024     "user": user,
  1103     "user": user,
  1025     "_list": _list,
  1104     "_list": _list,
  1026 }
  1105 }