mercurial/fileset.py
changeset 38863 61ab546b71c3
parent 38830 bfd5def3fe02
child 38865 899b4c74209c
equal deleted inserted replaced
38862:1ff45c518e6f 38863:61ab546b71c3
    23 )
    23 )
    24 from .utils import (
    24 from .utils import (
    25     stringutil,
    25     stringutil,
    26 )
    26 )
    27 
    27 
       
    28 # common weight constants
       
    29 _WEIGHT_CHECK_FILENAME = filesetlang.WEIGHT_CHECK_FILENAME
       
    30 _WEIGHT_READ_CONTENTS = filesetlang.WEIGHT_READ_CONTENTS
       
    31 _WEIGHT_STATUS = filesetlang.WEIGHT_STATUS
       
    32 _WEIGHT_STATUS_THOROUGH = filesetlang.WEIGHT_STATUS_THOROUGH
       
    33 
    28 # helpers for processing parsed tree
    34 # helpers for processing parsed tree
    29 getsymbol = filesetlang.getsymbol
    35 getsymbol = filesetlang.getsymbol
    30 getstring = filesetlang.getstring
    36 getstring = filesetlang.getstring
    31 _getkindpat = filesetlang.getkindpat
    37 _getkindpat = filesetlang.getkindpat
    32 getpattern = filesetlang.getpattern
    38 getpattern = filesetlang.getpattern
    86 # filesets using matchctx.status()
    92 # filesets using matchctx.status()
    87 _statuscallers = set()
    93 _statuscallers = set()
    88 
    94 
    89 predicate = registrar.filesetpredicate()
    95 predicate = registrar.filesetpredicate()
    90 
    96 
    91 @predicate('modified()', callstatus=True, weight=10)
    97 @predicate('modified()', callstatus=True, weight=_WEIGHT_STATUS)
    92 def modified(mctx, x):
    98 def modified(mctx, x):
    93     """File that is modified according to :hg:`status`.
    99     """File that is modified according to :hg:`status`.
    94     """
   100     """
    95     # i18n: "modified" is a keyword
   101     # i18n: "modified" is a keyword
    96     getargs(x, 0, 0, _("modified takes no arguments"))
   102     getargs(x, 0, 0, _("modified takes no arguments"))
    97     s = set(mctx.status().modified)
   103     s = set(mctx.status().modified)
    98     return mctx.predicate(s.__contains__, predrepr='modified')
   104     return mctx.predicate(s.__contains__, predrepr='modified')
    99 
   105 
   100 @predicate('added()', callstatus=True, weight=10)
   106 @predicate('added()', callstatus=True, weight=_WEIGHT_STATUS)
   101 def added(mctx, x):
   107 def added(mctx, x):
   102     """File that is added according to :hg:`status`.
   108     """File that is added according to :hg:`status`.
   103     """
   109     """
   104     # i18n: "added" is a keyword
   110     # i18n: "added" is a keyword
   105     getargs(x, 0, 0, _("added takes no arguments"))
   111     getargs(x, 0, 0, _("added takes no arguments"))
   106     s = set(mctx.status().added)
   112     s = set(mctx.status().added)
   107     return mctx.predicate(s.__contains__, predrepr='added')
   113     return mctx.predicate(s.__contains__, predrepr='added')
   108 
   114 
   109 @predicate('removed()', callstatus=True, weight=10)
   115 @predicate('removed()', callstatus=True, weight=_WEIGHT_STATUS)
   110 def removed(mctx, x):
   116 def removed(mctx, x):
   111     """File that is removed according to :hg:`status`.
   117     """File that is removed according to :hg:`status`.
   112     """
   118     """
   113     # i18n: "removed" is a keyword
   119     # i18n: "removed" is a keyword
   114     getargs(x, 0, 0, _("removed takes no arguments"))
   120     getargs(x, 0, 0, _("removed takes no arguments"))
   115     s = set(mctx.status().removed)
   121     s = set(mctx.status().removed)
   116     return mctx.predicate(s.__contains__, predrepr='removed')
   122     return mctx.predicate(s.__contains__, predrepr='removed')
   117 
   123 
   118 @predicate('deleted()', callstatus=True, weight=10)
   124 @predicate('deleted()', callstatus=True, weight=_WEIGHT_STATUS)
   119 def deleted(mctx, x):
   125 def deleted(mctx, x):
   120     """Alias for ``missing()``.
   126     """Alias for ``missing()``.
   121     """
   127     """
   122     # i18n: "deleted" is a keyword
   128     # i18n: "deleted" is a keyword
   123     getargs(x, 0, 0, _("deleted takes no arguments"))
   129     getargs(x, 0, 0, _("deleted takes no arguments"))
   124     s = set(mctx.status().deleted)
   130     s = set(mctx.status().deleted)
   125     return mctx.predicate(s.__contains__, predrepr='deleted')
   131     return mctx.predicate(s.__contains__, predrepr='deleted')
   126 
   132 
   127 @predicate('missing()', callstatus=True, weight=10)
   133 @predicate('missing()', callstatus=True, weight=_WEIGHT_STATUS)
   128 def missing(mctx, x):
   134 def missing(mctx, x):
   129     """File that is missing according to :hg:`status`.
   135     """File that is missing according to :hg:`status`.
   130     """
   136     """
   131     # i18n: "missing" is a keyword
   137     # i18n: "missing" is a keyword
   132     getargs(x, 0, 0, _("missing takes no arguments"))
   138     getargs(x, 0, 0, _("missing takes no arguments"))
   133     s = set(mctx.status().deleted)
   139     s = set(mctx.status().deleted)
   134     return mctx.predicate(s.__contains__, predrepr='deleted')
   140     return mctx.predicate(s.__contains__, predrepr='deleted')
   135 
   141 
   136 @predicate('unknown()', callstatus=True, weight=50)
   142 @predicate('unknown()', callstatus=True, weight=_WEIGHT_STATUS_THOROUGH)
   137 def unknown(mctx, x):
   143 def unknown(mctx, x):
   138     """File that is unknown according to :hg:`status`."""
   144     """File that is unknown according to :hg:`status`."""
   139     # i18n: "unknown" is a keyword
   145     # i18n: "unknown" is a keyword
   140     getargs(x, 0, 0, _("unknown takes no arguments"))
   146     getargs(x, 0, 0, _("unknown takes no arguments"))
   141     s = set(mctx.status().unknown)
   147     s = set(mctx.status().unknown)
   142     return mctx.predicate(s.__contains__, predrepr='unknown')
   148     return mctx.predicate(s.__contains__, predrepr='unknown')
   143 
   149 
   144 @predicate('ignored()', callstatus=True, weight=50)
   150 @predicate('ignored()', callstatus=True, weight=_WEIGHT_STATUS_THOROUGH)
   145 def ignored(mctx, x):
   151 def ignored(mctx, x):
   146     """File that is ignored according to :hg:`status`."""
   152     """File that is ignored according to :hg:`status`."""
   147     # i18n: "ignored" is a keyword
   153     # i18n: "ignored" is a keyword
   148     getargs(x, 0, 0, _("ignored takes no arguments"))
   154     getargs(x, 0, 0, _("ignored takes no arguments"))
   149     s = set(mctx.status().ignored)
   155     s = set(mctx.status().ignored)
   150     return mctx.predicate(s.__contains__, predrepr='ignored')
   156     return mctx.predicate(s.__contains__, predrepr='ignored')
   151 
   157 
   152 @predicate('clean()', callstatus=True, weight=10)
   158 @predicate('clean()', callstatus=True, weight=_WEIGHT_STATUS)
   153 def clean(mctx, x):
   159 def clean(mctx, x):
   154     """File that is clean according to :hg:`status`.
   160     """File that is clean according to :hg:`status`.
   155     """
   161     """
   156     # i18n: "clean" is a keyword
   162     # i18n: "clean" is a keyword
   157     getargs(x, 0, 0, _("clean takes no arguments"))
   163     getargs(x, 0, 0, _("clean takes no arguments"))
   163     """File that is under Mercurial control."""
   169     """File that is under Mercurial control."""
   164     # i18n: "tracked" is a keyword
   170     # i18n: "tracked" is a keyword
   165     getargs(x, 0, 0, _("tracked takes no arguments"))
   171     getargs(x, 0, 0, _("tracked takes no arguments"))
   166     return mctx.predicate(mctx.ctx.__contains__, predrepr='tracked')
   172     return mctx.predicate(mctx.ctx.__contains__, predrepr='tracked')
   167 
   173 
   168 @predicate('binary()', weight=30)
   174 @predicate('binary()', weight=_WEIGHT_READ_CONTENTS)
   169 def binary(mctx, x):
   175 def binary(mctx, x):
   170     """File that appears to be binary (contains NUL bytes).
   176     """File that appears to be binary (contains NUL bytes).
   171     """
   177     """
   172     # i18n: "binary" is a keyword
   178     # i18n: "binary" is a keyword
   173     getargs(x, 0, 0, _("binary takes no arguments"))
   179     getargs(x, 0, 0, _("binary takes no arguments"))
   190     # i18n: "symlink" is a keyword
   196     # i18n: "symlink" is a keyword
   191     getargs(x, 0, 0, _("symlink takes no arguments"))
   197     getargs(x, 0, 0, _("symlink takes no arguments"))
   192     ctx = mctx.ctx
   198     ctx = mctx.ctx
   193     return mctx.predicate(lambda f: ctx.flags(f) == 'l', predrepr='symlink')
   199     return mctx.predicate(lambda f: ctx.flags(f) == 'l', predrepr='symlink')
   194 
   200 
   195 @predicate('resolved()', weight=10)
   201 @predicate('resolved()', weight=_WEIGHT_STATUS)
   196 def resolved(mctx, x):
   202 def resolved(mctx, x):
   197     """File that is marked resolved according to :hg:`resolve -l`.
   203     """File that is marked resolved according to :hg:`resolve -l`.
   198     """
   204     """
   199     # i18n: "resolved" is a keyword
   205     # i18n: "resolved" is a keyword
   200     getargs(x, 0, 0, _("resolved takes no arguments"))
   206     getargs(x, 0, 0, _("resolved takes no arguments"))
   202         return mctx.never()
   208         return mctx.never()
   203     ms = merge.mergestate.read(mctx.ctx.repo())
   209     ms = merge.mergestate.read(mctx.ctx.repo())
   204     return mctx.predicate(lambda f: f in ms and ms[f] == 'r',
   210     return mctx.predicate(lambda f: f in ms and ms[f] == 'r',
   205                           predrepr='resolved')
   211                           predrepr='resolved')
   206 
   212 
   207 @predicate('unresolved()', weight=10)
   213 @predicate('unresolved()', weight=_WEIGHT_STATUS)
   208 def unresolved(mctx, x):
   214 def unresolved(mctx, x):
   209     """File that is marked unresolved according to :hg:`resolve -l`.
   215     """File that is marked unresolved according to :hg:`resolve -l`.
   210     """
   216     """
   211     # i18n: "unresolved" is a keyword
   217     # i18n: "unresolved" is a keyword
   212     getargs(x, 0, 0, _("unresolved takes no arguments"))
   218     getargs(x, 0, 0, _("unresolved takes no arguments"))
   214         return mctx.never()
   220         return mctx.never()
   215     ms = merge.mergestate.read(mctx.ctx.repo())
   221     ms = merge.mergestate.read(mctx.ctx.repo())
   216     return mctx.predicate(lambda f: f in ms and ms[f] == 'u',
   222     return mctx.predicate(lambda f: f in ms and ms[f] == 'u',
   217                           predrepr='unresolved')
   223                           predrepr='unresolved')
   218 
   224 
   219 @predicate('hgignore()', weight=10)
   225 @predicate('hgignore()', weight=_WEIGHT_STATUS)
   220 def hgignore(mctx, x):
   226 def hgignore(mctx, x):
   221     """File that matches the active .hgignore pattern.
   227     """File that matches the active .hgignore pattern.
   222     """
   228     """
   223     # i18n: "hgignore" is a keyword
   229     # i18n: "hgignore" is a keyword
   224     getargs(x, 0, 0, _("hgignore takes no arguments"))
   230     getargs(x, 0, 0, _("hgignore takes no arguments"))
   225     return mctx.ctx.repo().dirstate._ignore
   231     return mctx.ctx.repo().dirstate._ignore
   226 
   232 
   227 @predicate('portable()', weight=0.5)
   233 @predicate('portable()', weight=_WEIGHT_CHECK_FILENAME)
   228 def portable(mctx, x):
   234 def portable(mctx, x):
   229     """File that has a portable name. (This doesn't include filenames with case
   235     """File that has a portable name. (This doesn't include filenames with case
   230     collisions.)
   236     collisions.)
   231     """
   237     """
   232     # i18n: "portable" is a keyword
   238     # i18n: "portable" is a keyword
   233     getargs(x, 0, 0, _("portable takes no arguments"))
   239     getargs(x, 0, 0, _("portable takes no arguments"))
   234     return mctx.predicate(lambda f: util.checkwinfilename(f) is None,
   240     return mctx.predicate(lambda f: util.checkwinfilename(f) is None,
   235                           predrepr='portable')
   241                           predrepr='portable')
   236 
   242 
   237 @predicate('grep(regex)', weight=30)
   243 @predicate('grep(regex)', weight=_WEIGHT_READ_CONTENTS)
   238 def grep(mctx, x):
   244 def grep(mctx, x):
   239     """File contains the given regular expression.
   245     """File contains the given regular expression.
   240     """
   246     """
   241     try:
   247     try:
   242         # i18n: "grep" is a keyword
   248         # i18n: "grep" is a keyword
   286     else:
   292     else:
   287         a = util.sizetoint(expr)
   293         a = util.sizetoint(expr)
   288         b = _sizetomax(expr)
   294         b = _sizetomax(expr)
   289         return lambda x: x >= a and x <= b
   295         return lambda x: x >= a and x <= b
   290 
   296 
   291 @predicate('size(expression)', weight=10)
   297 @predicate('size(expression)', weight=_WEIGHT_STATUS)
   292 def size(mctx, x):
   298 def size(mctx, x):
   293     """File size matches the given expression. Examples:
   299     """File size matches the given expression. Examples:
   294 
   300 
   295     - size('1k') - files from 1024 to 2047 bytes
   301     - size('1k') - files from 1024 to 2047 bytes
   296     - size('< 20k') - files less than 20480 bytes
   302     - size('< 20k') - files less than 20480 bytes
   301     expr = getstring(x, _("size requires an expression"))
   307     expr = getstring(x, _("size requires an expression"))
   302     m = sizematcher(expr)
   308     m = sizematcher(expr)
   303     return mctx.fpredicate(lambda fctx: m(fctx.size()),
   309     return mctx.fpredicate(lambda fctx: m(fctx.size()),
   304                            predrepr=('size(%r)', expr), cache=True)
   310                            predrepr=('size(%r)', expr), cache=True)
   305 
   311 
   306 @predicate('encoding(name)', weight=30)
   312 @predicate('encoding(name)', weight=_WEIGHT_READ_CONTENTS)
   307 def encoding(mctx, x):
   313 def encoding(mctx, x):
   308     """File can be successfully decoded with the given character
   314     """File can be successfully decoded with the given character
   309     encoding. May not be useful for encodings other than ASCII and
   315     encoding. May not be useful for encodings other than ASCII and
   310     UTF-8.
   316     UTF-8.
   311     """
   317     """
   323         except UnicodeDecodeError:
   329         except UnicodeDecodeError:
   324             return False
   330             return False
   325 
   331 
   326     return mctx.fpredicate(encp, predrepr=('encoding(%r)', enc), cache=True)
   332     return mctx.fpredicate(encp, predrepr=('encoding(%r)', enc), cache=True)
   327 
   333 
   328 @predicate('eol(style)', weight=30)
   334 @predicate('eol(style)', weight=_WEIGHT_READ_CONTENTS)
   329 def eol(mctx, x):
   335 def eol(mctx, x):
   330     """File contains newlines of the given style (dos, unix, mac). Binary
   336     """File contains newlines of the given style (dos, unix, mac). Binary
   331     files are excluded, files with mixed line endings match multiple
   337     files are excluded, files with mixed line endings match multiple
   332     styles.
   338     styles.
   333     """
   339     """
   357     def copiedp(fctx):
   363     def copiedp(fctx):
   358         p = fctx.parents()
   364         p = fctx.parents()
   359         return p and p[0].path() != fctx.path()
   365         return p and p[0].path() != fctx.path()
   360     return mctx.fpredicate(copiedp, predrepr='copied', cache=True)
   366     return mctx.fpredicate(copiedp, predrepr='copied', cache=True)
   361 
   367 
   362 @predicate('revs(revs, pattern)', weight=10)
   368 @predicate('revs(revs, pattern)', weight=_WEIGHT_STATUS)
   363 def revs(mctx, x):
   369 def revs(mctx, x):
   364     """Evaluate set in the specified revisions. If the revset match multiple
   370     """Evaluate set in the specified revisions. If the revset match multiple
   365     revs, this will return file matching pattern in any of the revision.
   371     revs, this will return file matching pattern in any of the revision.
   366     """
   372     """
   367     # i18n: "revs" is a keyword
   373     # i18n: "revs" is a keyword
   379         return mctx.never()
   385         return mctx.never()
   380     if len(matchers) == 1:
   386     if len(matchers) == 1:
   381         return matchers[0]
   387         return matchers[0]
   382     return matchmod.unionmatcher(matchers)
   388     return matchmod.unionmatcher(matchers)
   383 
   389 
   384 @predicate('status(base, rev, pattern)', weight=10)
   390 @predicate('status(base, rev, pattern)', weight=_WEIGHT_STATUS)
   385 def status(mctx, x):
   391 def status(mctx, x):
   386     """Evaluate predicate using status change between ``base`` and
   392     """Evaluate predicate using status change between ``base`` and
   387     ``rev``. Examples:
   393     ``rev``. Examples:
   388 
   394 
   389     - ``status(3, 7, added())`` - matches files added from "3" to "7"
   395     - ``status(3, 7, added())`` - matches files added from "3" to "7"