mercurial/narrowspec.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 21 Nov 2019 23:25:08 +0100
changeset 44107 5a012404503b
parent 43117 8ff1ecfadcd1
child 44563 1922694d638f
permissions -rw-r--r--
localrepo: also fast past the parents of working copies parents There are descent odds that they will be needed too. So we also cache and fastpath them. Differential Revision: https://phab.mercurial-scm.org/D7498
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
     1
# narrowspec.py - methods for working with a narrow view of a repository
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
     2
#
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
     3
# Copyright 2017 Google, Inc.
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
     4
#
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
     7
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
     8
from __future__ import absolute_import
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
     9
36160
9fd8c2a3db5a narrowspec: move module into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36159
diff changeset
    10
from .i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
    11
from .pycompat import getattr
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
    12
from .interfaces import repository
36160
9fd8c2a3db5a narrowspec: move module into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36159
diff changeset
    13
from . import (
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    14
    error,
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    15
    match as matchmod,
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
    16
    merge,
42150
770f5f586ae5 narrow: make warning about possibly dirty files respect ui.relative-paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 41676
diff changeset
    17
    scmutil,
38839
f64ebe7d2259 narrowspec: use sparse.parseconfig() to parse narrowspec file (BC)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 38836
diff changeset
    18
    sparse,
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    19
    util,
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    20
)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    21
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
    22
# The file in .hg/store/ that indicates which paths exit in the store
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    23
FILENAME = b'narrowspec'
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
    24
# The file in .hg/ that indicates which paths exit in the dirstate
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    25
DIRSTATE_FILENAME = b'narrowspec.dirstate'
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    26
39531
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    27
# Pattern prefixes that are allowed in narrow patterns. This list MUST
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    28
# only contain patterns that are fast and safe to evaluate. Keep in mind
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    29
# that patterns are supplied by clients and executed on remote servers
39811
ae20f52437e9 wireprotov2: advertise recognized path filter prefixes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39556
diff changeset
    30
# as part of wire protocol commands. That means that changes to this
ae20f52437e9 wireprotov2: advertise recognized path filter prefixes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39556
diff changeset
    31
# data structure influence the wire protocol and should not be taken
ae20f52437e9 wireprotov2: advertise recognized path filter prefixes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39556
diff changeset
    32
# lightly - especially removals.
39531
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    33
VALID_PREFIXES = (
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    34
    b'path:',
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    35
    b'rootfilesin:',
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    36
)
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    37
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
    38
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    39
def normalizesplitpattern(kind, pat):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    40
    """Returns the normalized version of a pattern and kind.
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    41
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    42
    Returns a tuple with the normalized kind and normalized pattern.
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    43
    """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    44
    pat = pat.rstrip(b'/')
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    45
    _validatepattern(pat)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    46
    return kind, pat
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    47
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
    48
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    49
def _numlines(s):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    50
    """Returns the number of lines in s, including ending empty lines."""
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    51
    # We use splitlines because it is Unicode-friendly and thus Python 3
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    52
    # compatible. However, it does not count empty lines at the end, so trick
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    53
    # it by adding a character at the end.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    54
    return len((s + b'x').splitlines())
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    55
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
    56
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    57
def _validatepattern(pat):
36098
9c55bbc29dcf narrowspec: document constraints when validating patterns
Augie Fackler <augie@google.com>
parents: 36079
diff changeset
    58
    """Validates the pattern and aborts if it is invalid.
9c55bbc29dcf narrowspec: document constraints when validating patterns
Augie Fackler <augie@google.com>
parents: 36079
diff changeset
    59
9c55bbc29dcf narrowspec: document constraints when validating patterns
Augie Fackler <augie@google.com>
parents: 36079
diff changeset
    60
    Patterns are stored in the narrowspec as newline-separated
9c55bbc29dcf narrowspec: document constraints when validating patterns
Augie Fackler <augie@google.com>
parents: 36079
diff changeset
    61
    POSIX-style bytestring paths. There's no escaping.
9c55bbc29dcf narrowspec: document constraints when validating patterns
Augie Fackler <augie@google.com>
parents: 36079
diff changeset
    62
    """
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    63
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    64
    # We use newlines as separators in the narrowspec file, so don't allow them
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    65
    # in patterns.
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    66
    if _numlines(pat) > 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    67
        raise error.Abort(_(b'newlines are not allowed in narrowspec paths'))
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    68
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    69
    components = pat.split(b'/')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    70
    if b'.' in components or b'..' in components:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    71
        raise error.Abort(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    72
            _(b'"." and ".." are not allowed in narrowspec paths')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    73
        )
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    74
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
    75
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    76
def normalizepattern(pattern, defaultkind=b'path'):
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    77
    """Returns the normalized version of a text-format pattern.
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    78
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    79
    If the pattern has no kind, the default will be added.
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    80
    """
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    81
    kind, pat = matchmod._patsplit(pattern, defaultkind)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    82
    return b'%s:%s' % normalizesplitpattern(kind, pat)
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    83
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
    84
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    85
def parsepatterns(pats):
39531
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    86
    """Parses an iterable of patterns into a typed pattern set.
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    87
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    88
    Patterns are assumed to be ``path:`` if no prefix is present.
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    89
    For safety and performance reasons, only some prefixes are allowed.
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    90
    See ``validatepatterns()``.
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    91
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    92
    This function should be used on patterns that come from the user to
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    93
    normalize and validate them to the internal data structure used for
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    94
    representing patterns.
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    95
    """
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    96
    res = {normalizepattern(orig) for orig in pats}
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    97
    validatepatterns(res)
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    98
    return res
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
    99
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   100
39531
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   101
def validatepatterns(pats):
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   102
    """Validate that patterns are in the expected data structure and format.
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   103
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   104
    And that is a set of normalized patterns beginning with ``path:`` or
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   105
    ``rootfilesin:``.
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   106
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   107
    This function should be used to validate internal data structures
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   108
    and patterns that are loaded from sources that use the internal,
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   109
    prefixed pattern representation (but can't necessarily be fully trusted).
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   110
    """
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   111
    if not isinstance(pats, set):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   112
        raise error.ProgrammingError(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43089
diff changeset
   113
            b'narrow patterns should be a set; got %r' % pats
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   114
        )
39531
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   115
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   116
    for pat in pats:
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   117
        if not pat.startswith(VALID_PREFIXES):
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   118
            # Use a Mercurial exception because this can happen due to user
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39525
diff changeset
   119
            # bugs (e.g. manually updating spec file).
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   120
            raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   121
                _(b'invalid prefix on narrow pattern: %s') % pat,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   122
                hint=_(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   123
                    b'narrow patterns must begin with one of '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   124
                    b'the following: %s'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   125
                )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   126
                % b', '.join(VALID_PREFIXES),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   127
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   128
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   129
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   130
def format(includes, excludes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   131
    output = b'[include]\n'
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   132
    for i in sorted(includes - excludes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   133
        output += i + b'\n'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   134
    output += b'[exclude]\n'
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   135
    for e in sorted(excludes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   136
        output += e + b'\n'
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   137
    return output
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   138
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   139
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   140
def match(root, include=None, exclude=None):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   141
    if not include:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   142
        # Passing empty include and empty exclude to matchmod.match()
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   143
        # gives a matcher that matches everything, so explicitly use
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   144
        # the nevermatcher.
41676
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41298
diff changeset
   145
        return matchmod.never()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   146
    return matchmod.match(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   147
        root, b'', [], include=include or [], exclude=exclude or []
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   148
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   149
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   150
40690
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39811
diff changeset
   151
def parseconfig(ui, spec):
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39811
diff changeset
   152
    # maybe we should care about the profiles returned too
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   153
    includepats, excludepats, profiles = sparse.parseconfig(ui, spec, b'narrow')
40690
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39811
diff changeset
   154
    if profiles:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   155
        raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   156
            _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   157
                b"including other spec files using '%include' is not"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   158
                b" supported in narrowspec"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   159
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   160
        )
40690
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39811
diff changeset
   161
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39811
diff changeset
   162
    validatepatterns(includepats)
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39811
diff changeset
   163
    validatepatterns(excludepats)
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39811
diff changeset
   164
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39811
diff changeset
   165
    return includepats, excludepats
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39811
diff changeset
   166
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   167
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   168
def load(repo):
42404
0c0a22f5b0b5 narrowspec: use vfs.tryread() instead of reimplementing
Martin von Zweigbergk <martinvonz@google.com>
parents: 42171
diff changeset
   169
    # Treat "narrowspec does not exist" the same as "narrowspec file exists
0c0a22f5b0b5 narrowspec: use vfs.tryread() instead of reimplementing
Martin von Zweigbergk <martinvonz@google.com>
parents: 42171
diff changeset
   170
    # and is empty".
0c0a22f5b0b5 narrowspec: use vfs.tryread() instead of reimplementing
Martin von Zweigbergk <martinvonz@google.com>
parents: 42171
diff changeset
   171
    spec = repo.svfs.tryread(FILENAME)
40690
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39811
diff changeset
   172
    return parseconfig(repo.ui, spec)
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   173
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   174
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   175
def save(repo, includepats, excludepats):
39539
8d8e61df8259 narrowspec: validate patterns when loading and saving spec file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39531
diff changeset
   176
    validatepatterns(includepats)
8d8e61df8259 narrowspec: validate patterns when loading and saving spec file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39531
diff changeset
   177
    validatepatterns(excludepats)
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   178
    spec = format(includepats, excludepats)
38872
576eef1ab43d narrow: move .hg/narrowspec to .hg/store/narrowspec (BC)
Martin von Zweigbergk <martinvonz@google.com>
parents: 38871
diff changeset
   179
    repo.svfs.write(FILENAME, spec)
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   180
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   181
41229
50ca531f1f24 narrow: copy store narrowspec to working copy immediately
Martin von Zweigbergk <martinvonz@google.com>
parents: 41227
diff changeset
   182
def copytoworkingcopy(repo):
50ca531f1f24 narrow: copy store narrowspec to working copy immediately
Martin von Zweigbergk <martinvonz@google.com>
parents: 41227
diff changeset
   183
    spec = repo.svfs.read(FILENAME)
50ca531f1f24 narrow: copy store narrowspec to working copy immediately
Martin von Zweigbergk <martinvonz@google.com>
parents: 41227
diff changeset
   184
    repo.vfs.write(DIRSTATE_FILENAME, spec)
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   185
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   186
38869
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38840
diff changeset
   187
def savebackup(repo, backupname):
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38840
diff changeset
   188
    if repository.NARROW_REQUIREMENT not in repo.requirements:
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38840
diff changeset
   189
        return
41041
1e8d9f472ea1 narrow: keep narrowspec backup in store
Martin von Zweigbergk <martinvonz@google.com>
parents: 40690
diff changeset
   190
    svfs = repo.svfs
1e8d9f472ea1 narrow: keep narrowspec backup in store
Martin von Zweigbergk <martinvonz@google.com>
parents: 40690
diff changeset
   191
    svfs.tryunlink(backupname)
1e8d9f472ea1 narrow: keep narrowspec backup in store
Martin von Zweigbergk <martinvonz@google.com>
parents: 40690
diff changeset
   192
    util.copyfile(svfs.join(FILENAME), svfs.join(backupname), hardlink=True)
38836
fed6fe856333 narrow: extract part of narrowspec backup to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 36470
diff changeset
   193
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   194
38869
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38840
diff changeset
   195
def restorebackup(repo, backupname):
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38840
diff changeset
   196
    if repository.NARROW_REQUIREMENT not in repo.requirements:
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38840
diff changeset
   197
        return
41041
1e8d9f472ea1 narrow: keep narrowspec backup in store
Martin von Zweigbergk <martinvonz@google.com>
parents: 40690
diff changeset
   198
    util.rename(repo.svfs.join(backupname), repo.svfs.join(FILENAME))
38836
fed6fe856333 narrow: extract part of narrowspec backup to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 36470
diff changeset
   199
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   200
41227
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   201
def savewcbackup(repo, backupname):
38869
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38840
diff changeset
   202
    if repository.NARROW_REQUIREMENT not in repo.requirements:
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38840
diff changeset
   203
        return
41227
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   204
    vfs = repo.vfs
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   205
    vfs.tryunlink(backupname)
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   206
    # It may not exist in old repos
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   207
    if vfs.exists(DIRSTATE_FILENAME):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   208
        util.copyfile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   209
            vfs.join(DIRSTATE_FILENAME), vfs.join(backupname), hardlink=True
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   210
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   211
41227
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   212
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   213
def restorewcbackup(repo, backupname):
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   214
    if repository.NARROW_REQUIREMENT not in repo.requirements:
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   215
        return
41298
88a7c211b21e narrow: fix crash when restoring backup in legacy repo
Martin von Zweigbergk <martinvonz@google.com>
parents: 41238
diff changeset
   216
    # It may not exist in old repos
88a7c211b21e narrow: fix crash when restoring backup in legacy repo
Martin von Zweigbergk <martinvonz@google.com>
parents: 41238
diff changeset
   217
    if repo.vfs.exists(backupname):
88a7c211b21e narrow: fix crash when restoring backup in legacy repo
Martin von Zweigbergk <martinvonz@google.com>
parents: 41238
diff changeset
   218
        util.rename(repo.vfs.join(backupname), repo.vfs.join(DIRSTATE_FILENAME))
41227
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   219
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   220
41227
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   221
def clearwcbackup(repo, backupname):
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   222
    if repository.NARROW_REQUIREMENT not in repo.requirements:
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   223
        return
41298
88a7c211b21e narrow: fix crash when restoring backup in legacy repo
Martin von Zweigbergk <martinvonz@google.com>
parents: 41238
diff changeset
   224
    repo.vfs.tryunlink(backupname)
38836
fed6fe856333 narrow: extract part of narrowspec backup to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 36470
diff changeset
   225
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   226
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   227
def restrictpatterns(req_includes, req_excludes, repo_includes, repo_excludes):
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   228
    r""" Restricts the patterns according to repo settings,
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   229
    results in a logical AND operation
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   230
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   231
    :param req_includes: requested includes
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   232
    :param req_excludes: requested excludes
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   233
    :param repo_includes: repo includes
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   234
    :param repo_excludes: repo excludes
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   235
    :return: include patterns, exclude patterns, and invalid include patterns.
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   236
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   237
    >>> restrictpatterns({'f1','f2'}, {}, ['f1'], [])
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   238
    (set(['f1']), {}, [])
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   239
    >>> restrictpatterns({'f1'}, {}, ['f1','f2'], [])
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   240
    (set(['f1']), {}, [])
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   241
    >>> restrictpatterns({'f1/fc1', 'f3/fc3'}, {}, ['f1','f2'], [])
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   242
    (set(['f1/fc1']), {}, [])
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   243
    >>> restrictpatterns({'f1_fc1'}, {}, ['f1','f2'], [])
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   244
    ([], set(['path:.']), [])
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   245
    >>> restrictpatterns({'f1/../f2/fc2'}, {}, ['f1','f2'], [])
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   246
    (set(['f2/fc2']), {}, [])
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   247
    >>> restrictpatterns({'f1/../f3/fc3'}, {}, ['f1','f2'], [])
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   248
    ([], set(['path:.']), [])
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   249
    >>> restrictpatterns({'f1/$non_exitent_var'}, {}, ['f1','f2'], [])
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   250
    (set(['f1/$non_exitent_var']), {}, [])
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   251
    """
36099
b8bbe589fd47 narrowspec: consistently use set() to copy sets
Augie Fackler <augie@google.com>
parents: 36098
diff changeset
   252
    res_excludes = set(req_excludes)
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   253
    res_excludes.update(repo_excludes)
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   254
    invalid_includes = []
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   255
    if not req_includes:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   256
        res_includes = set(repo_includes)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   257
    elif b'path:.' not in repo_includes:
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   258
        res_includes = []
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   259
        for req_include in req_includes:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   260
            req_include = util.expandpath(util.normpath(req_include))
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   261
            if req_include in repo_includes:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   262
                res_includes.append(req_include)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   263
                continue
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   264
            valid = False
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   265
            for repo_include in repo_includes:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   266
                if req_include.startswith(repo_include + b'/'):
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   267
                    valid = True
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   268
                    res_includes.append(req_include)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   269
                    break
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   270
            if not valid:
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   271
                invalid_includes.append(req_include)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   272
        if len(res_includes) == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   273
            res_excludes = {b'path:.'}
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   274
        else:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   275
            res_includes = set(res_includes)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   276
    else:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   277
        res_includes = set(req_includes)
36100
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36099
diff changeset
   278
    return res_includes, res_excludes, invalid_includes
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   279
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   280
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   281
# These two are extracted for extensions (specifically for Google's CitC file
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   282
# system)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   283
def _deletecleanfiles(repo, files):
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   284
    for f in files:
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   285
        repo.wvfs.unlinkpath(f)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   286
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   287
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   288
def _writeaddedfiles(repo, pctx, files):
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   289
    actions = merge.emptyactions()
41177
5838afea8213 narrow: use merge.ACTION_GET instead of duplicating 'g' constant
Martin von Zweigbergk <martinvonz@google.com>
parents: 41176
diff changeset
   290
    addgaction = actions[merge.ACTION_GET].append
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   291
    mf = repo[b'.'].manifest()
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   292
    for f in files:
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   293
        if not repo.wvfs.exists(f):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   294
            addgaction((f, (mf.flags(f), False), b"narrowspec updated"))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   295
    merge.applyupdates(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   296
        repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   297
        actions,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   298
        wctx=repo[None],
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   299
        mctx=repo[b'.'],
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   300
        overwrite=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   301
        wantfiledata=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   302
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   303
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   304
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   305
def checkworkingcopynarrowspec(repo):
42411
4738c292a520 narrowspec: replace one recursion-avoidance hack with another
Martin von Zweigbergk <martinvonz@google.com>
parents: 42404
diff changeset
   306
    # Avoid infinite recursion when updating the working copy
4738c292a520 narrowspec: replace one recursion-avoidance hack with another
Martin von Zweigbergk <martinvonz@google.com>
parents: 42404
diff changeset
   307
    if getattr(repo, '_updatingnarrowspec', False):
4738c292a520 narrowspec: replace one recursion-avoidance hack with another
Martin von Zweigbergk <martinvonz@google.com>
parents: 42404
diff changeset
   308
        return
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   309
    storespec = repo.svfs.tryread(FILENAME)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   310
    wcspec = repo.vfs.tryread(DIRSTATE_FILENAME)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   311
    if wcspec != storespec:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   312
        raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   313
            _(b"working copy's narrowspec is stale"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   314
            hint=_(b"run 'hg tracked --update-working-copy'"),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   315
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   316
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   317
41238
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   318
def updateworkingcopy(repo, assumeclean=False):
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   319
    """updates the working copy and dirstate from the store narrowspec
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   320
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   321
    When assumeclean=True, files that are not known to be clean will also
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   322
    be deleted. It is then up to the caller to make sure they are clean.
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   323
    """
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   324
    oldspec = repo.vfs.tryread(DIRSTATE_FILENAME)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   325
    newspec = repo.svfs.tryread(FILENAME)
42411
4738c292a520 narrowspec: replace one recursion-avoidance hack with another
Martin von Zweigbergk <martinvonz@google.com>
parents: 42404
diff changeset
   326
    repo._updatingnarrowspec = True
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   327
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   328
    oldincludes, oldexcludes = parseconfig(repo.ui, oldspec)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   329
    newincludes, newexcludes = parseconfig(repo.ui, newspec)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   330
    oldmatch = match(repo.root, include=oldincludes, exclude=oldexcludes)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   331
    newmatch = match(repo.root, include=newincludes, exclude=newexcludes)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   332
    addedmatch = matchmod.differencematcher(newmatch, oldmatch)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   333
    removedmatch = matchmod.differencematcher(oldmatch, newmatch)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   334
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   335
    ds = repo.dirstate
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   336
    lookup, status = ds.status(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   337
        removedmatch, subrepos=[], ignored=True, clean=True, unknown=True
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42813
diff changeset
   338
    )
41238
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   339
    trackeddirty = status.modified + status.added
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   340
    clean = status.clean
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   341
    if assumeclean:
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   342
        assert not trackeddirty
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   343
        clean.extend(lookup)
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   344
    else:
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   345
        trackeddirty.extend(lookup)
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   346
    _deletecleanfiles(repo, clean)
42150
770f5f586ae5 narrow: make warning about possibly dirty files respect ui.relative-paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 41676
diff changeset
   347
    uipathfn = scmutil.getuipathfn(repo)
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   348
    for f in sorted(trackeddirty):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   349
        repo.ui.status(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   350
            _(b'not deleting possibly dirty file %s\n') % uipathfn(f)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   351
        )
42171
84bd6ae2d1f6 narrow: also warn when not deleting untracked or ignored files
Martin von Zweigbergk <martinvonz@google.com>
parents: 42150
diff changeset
   352
    for f in sorted(status.unknown):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   353
        repo.ui.status(_(b'not deleting unknown file %s\n') % uipathfn(f))
42171
84bd6ae2d1f6 narrow: also warn when not deleting untracked or ignored files
Martin von Zweigbergk <martinvonz@google.com>
parents: 42150
diff changeset
   354
    for f in sorted(status.ignored):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   355
        repo.ui.status(_(b'not deleting ignored file %s\n') % uipathfn(f))
41238
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   356
    for f in clean + trackeddirty:
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   357
        ds.drop(f)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   358
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   359
    pctx = repo[b'.']
41043
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   360
    newfiles = [f for f in pctx.manifest().walk(addedmatch) if f not in ds]
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   361
    for f in newfiles:
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   362
        ds.normallookup(f)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41041
diff changeset
   363
    _writeaddedfiles(repo, pctx, newfiles)
42411
4738c292a520 narrowspec: replace one recursion-avoidance hack with another
Martin von Zweigbergk <martinvonz@google.com>
parents: 42404
diff changeset
   364
    repo._updatingnarrowspec = False