mercurial/revset.py
changeset 30719 42c75b4fa46a
parent 30702 7e4f431206cd
child 30753 c3a3896a9fa8
equal deleted inserted replaced
30718:ce662ee40d2d 30719:42c75b4fa46a
  1065 def _followfirst(repo, subset, x):
  1065 def _followfirst(repo, subset, x):
  1066     # ``followfirst([pattern[, startrev]])``
  1066     # ``followfirst([pattern[, startrev]])``
  1067     # Like ``follow([pattern[, startrev]])`` but follows only the first parent
  1067     # Like ``follow([pattern[, startrev]])`` but follows only the first parent
  1068     # of every revisions or files revisions.
  1068     # of every revisions or files revisions.
  1069     return _follow(repo, subset, x, '_followfirst', followfirst=True)
  1069     return _follow(repo, subset, x, '_followfirst', followfirst=True)
       
  1070 
       
  1071 @predicate('followlines(file, fromline, toline[, rev=.])', safe=True)
       
  1072 def followlines(repo, subset, x):
       
  1073     """Changesets modifying `file` in line range ('fromline', 'toline').
       
  1074 
       
  1075     Line range corresponds to 'file' content at 'rev' and should hence be
       
  1076     consistent with file size. If rev is not specified, working directory's
       
  1077     parent is used.
       
  1078     """
       
  1079     from . import context  # avoid circular import issues
       
  1080 
       
  1081     args = getargs(x, 3, 4, _("followlines takes at least three arguments"))
       
  1082 
       
  1083     rev = '.'
       
  1084     if len(args) == 4:
       
  1085         revarg = getargsdict(args[3], 'followlines', 'rev')
       
  1086         if 'rev' in revarg:
       
  1087             revs = getset(repo, fullreposet(repo), revarg['rev'])
       
  1088             if len(revs) != 1:
       
  1089                 raise error.ParseError(
       
  1090                     _("followlines expects exactly one revision"))
       
  1091             rev = revs.last()
       
  1092 
       
  1093     pat = getstring(args[0], _("followlines requires a pattern"))
       
  1094     if not matchmod.patkind(pat):
       
  1095         fname = pathutil.canonpath(repo.root, repo.getcwd(), pat)
       
  1096     else:
       
  1097         m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=repo[rev])
       
  1098         files = [f for f in repo[rev] if m(f)]
       
  1099         if len(files) != 1:
       
  1100             raise error.ParseError(_("followlines expects exactly one file"))
       
  1101         fname = files[0]
       
  1102 
       
  1103     try:
       
  1104         fromline, toline = [int(getsymbol(a)) for a in args[1:3]]
       
  1105     except ValueError:
       
  1106         raise error.ParseError(_("line range bounds must be integers"))
       
  1107     if toline - fromline < 0:
       
  1108         raise error.ParseError(_("line range must be positive"))
       
  1109     if fromline < 1:
       
  1110         raise error.ParseError(_("fromline must be strictly positive"))
       
  1111     fromline -= 1
       
  1112 
       
  1113     fctx = repo[rev].filectx(fname)
       
  1114     revs = (c.rev() for c in context.blockancestors(fctx, fromline, toline))
       
  1115     return subset & generatorset(revs, iterasc=False)
  1070 
  1116 
  1071 @predicate('all()', safe=True)
  1117 @predicate('all()', safe=True)
  1072 def getall(repo, subset, x):
  1118 def getall(repo, subset, x):
  1073     """All changesets, the same as ``0:tip``.
  1119     """All changesets, the same as ``0:tip``.
  1074     """
  1120     """