mercurial/narrowspec.py
author Augie Fackler <augie@google.com>
Tue, 18 Jun 2019 09:57:06 -0400
changeset 42512 df1419c5756a
parent 42472 87a34c767384
child 42823 268662aac075
permissions -rw-r--r--
remotefilelog: tell runbgcommand to not block on child process startup These two invocations will always find a binary because they're re-running hg. As a result, we can skip waiting for the subprocess to start running and save a little bit of wall-time. Differential Revision: https://phab.mercurial-scm.org/D6539
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36117
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
36198
9fd8c2a3db5a narrowspec: move module into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36197
diff changeset
    10
from .i18n import _
9fd8c2a3db5a narrowspec: move module into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36197
diff changeset
    11
from . import (
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    12
    error,
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    13
    match as matchmod,
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
    14
    merge,
38908
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38879
diff changeset
    15
    repository,
42192
770f5f586ae5 narrow: make warning about possibly dirty files respect ui.relative-paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 41687
diff changeset
    16
    scmutil,
38878
f64ebe7d2259 narrowspec: use sparse.parseconfig() to parse narrowspec file (BC)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 38875
diff changeset
    17
    sparse,
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    18
    util,
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    19
)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    20
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
    21
# The file in .hg/store/ that indicates which paths exit in the store
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    22
FILENAME = 'narrowspec'
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
    23
# The file in .hg/ that indicates which paths exit in the dirstate
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
    24
DIRSTATE_FILENAME = 'narrowspec.dirstate'
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    25
39548
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    26
# 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: 39542
diff changeset
    27
# 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: 39542
diff changeset
    28
# that patterns are supplied by clients and executed on remote servers
39816
ae20f52437e9 wireprotov2: advertise recognized path filter prefixes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39572
diff changeset
    29
# 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: 39572
diff changeset
    30
# 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: 39572
diff changeset
    31
# lightly - especially removals.
39548
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    32
VALID_PREFIXES = (
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    33
    b'path:',
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    34
    b'rootfilesin:',
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    35
)
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    36
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    37
def normalizesplitpattern(kind, pat):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    38
    """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
    39
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    40
    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
    41
    """
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    42
    pat = pat.rstrip('/')
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    43
    _validatepattern(pat)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    44
    return kind, pat
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    45
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    46
def _numlines(s):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    47
    """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
    48
    # 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
    49
    # 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
    50
    # it by adding a character at the end.
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    51
    return len((s + 'x').splitlines())
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    52
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    53
def _validatepattern(pat):
36136
9c55bbc29dcf narrowspec: document constraints when validating patterns
Augie Fackler <augie@google.com>
parents: 36117
diff changeset
    54
    """Validates the pattern and aborts if it is invalid.
9c55bbc29dcf narrowspec: document constraints when validating patterns
Augie Fackler <augie@google.com>
parents: 36117
diff changeset
    55
9c55bbc29dcf narrowspec: document constraints when validating patterns
Augie Fackler <augie@google.com>
parents: 36117
diff changeset
    56
    Patterns are stored in the narrowspec as newline-separated
9c55bbc29dcf narrowspec: document constraints when validating patterns
Augie Fackler <augie@google.com>
parents: 36117
diff changeset
    57
    POSIX-style bytestring paths. There's no escaping.
9c55bbc29dcf narrowspec: document constraints when validating patterns
Augie Fackler <augie@google.com>
parents: 36117
diff changeset
    58
    """
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    59
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    60
    # 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
    61
    # in patterns.
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    62
    if _numlines(pat) > 1:
36198
9fd8c2a3db5a narrowspec: move module into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36197
diff changeset
    63
        raise error.Abort(_('newlines are not allowed in narrowspec paths'))
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    64
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    65
    components = pat.split('/')
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    66
    if '.' in components or '..' in components:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    67
        raise error.Abort(_('"." and ".." are not allowed in narrowspec paths'))
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    68
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    69
def normalizepattern(pattern, defaultkind='path'):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    70
    """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
    71
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    72
    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
    73
    """
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    74
    kind, pat = matchmod._patsplit(pattern, defaultkind)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    75
    return '%s:%s' % normalizesplitpattern(kind, pat)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    76
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    77
def parsepatterns(pats):
39548
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    78
    """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: 39542
diff changeset
    79
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    80
    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: 39542
diff changeset
    81
    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: 39542
diff changeset
    82
    See ``validatepatterns()``.
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    83
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    84
    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: 39542
diff changeset
    85
    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: 39542
diff changeset
    86
    representing patterns.
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    87
    """
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    88
    res = {normalizepattern(orig) for orig in pats}
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    89
    validatepatterns(res)
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    90
    return res
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    91
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    92
def validatepatterns(pats):
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    93
    """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: 39542
diff changeset
    94
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    95
    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: 39542
diff changeset
    96
    ``rootfilesin:``.
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    97
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
    98
    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: 39542
diff changeset
    99
    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: 39542
diff changeset
   100
    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: 39542
diff changeset
   101
    """
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   102
    if not isinstance(pats, set):
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   103
        raise error.ProgrammingError('narrow patterns should be a set; '
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   104
                                     'got %r' % pats)
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   105
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   106
    for pat in pats:
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   107
        if not pat.startswith(VALID_PREFIXES):
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   108
            # 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: 39542
diff changeset
   109
            # bugs (e.g. manually updating spec file).
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   110
            raise error.Abort(_('invalid prefix on narrow pattern: %s') % pat,
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   111
                              hint=_('narrow patterns must begin with one of '
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   112
                                     'the following: %s') %
0d572769046a narrowspec: limit patterns to path: and rootfilesin: (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39542
diff changeset
   113
                                   ', '.join(VALID_PREFIXES))
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   114
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   115
def format(includes, excludes):
38878
f64ebe7d2259 narrowspec: use sparse.parseconfig() to parse narrowspec file (BC)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 38875
diff changeset
   116
    output = '[include]\n'
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   117
    for i in sorted(includes - excludes):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   118
        output += i + '\n'
38878
f64ebe7d2259 narrowspec: use sparse.parseconfig() to parse narrowspec file (BC)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 38875
diff changeset
   119
    output += '[exclude]\n'
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   120
    for e in sorted(excludes):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   121
        output += e + '\n'
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   122
    return output
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   123
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   124
def match(root, include=None, exclude=None):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   125
    if not include:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   126
        # 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
   127
        # 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
   128
        # the nevermatcher.
41687
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41298
diff changeset
   129
        return matchmod.never()
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   130
    return matchmod.match(root, '', [], include=include or [],
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   131
                          exclude=exclude or [])
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   132
40729
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   133
def parseconfig(ui, spec):
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   134
    # maybe we should care about the profiles returned too
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   135
    includepats, excludepats, profiles = sparse.parseconfig(ui, spec, 'narrow')
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   136
    if profiles:
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   137
        raise error.Abort(_("including other spec files using '%include' is not"
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   138
                            " supported in narrowspec"))
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   139
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   140
    validatepatterns(includepats)
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   141
    validatepatterns(excludepats)
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   142
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   143
    return includepats, excludepats
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   144
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   145
def load(repo):
42423
0c0a22f5b0b5 narrowspec: use vfs.tryread() instead of reimplementing
Martin von Zweigbergk <martinvonz@google.com>
parents: 42213
diff changeset
   146
    # 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: 42213
diff changeset
   147
    # and is empty".
0c0a22f5b0b5 narrowspec: use vfs.tryread() instead of reimplementing
Martin von Zweigbergk <martinvonz@google.com>
parents: 42213
diff changeset
   148
    spec = repo.svfs.tryread(FILENAME)
40729
efd0f79246e3 narrow: extract helper for parsing narrowspec file
Martin von Zweigbergk <martinvonz@google.com>
parents: 39816
diff changeset
   149
    return parseconfig(repo.ui, spec)
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   150
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   151
def save(repo, includepats, excludepats):
39556
8d8e61df8259 narrowspec: validate patterns when loading and saving spec file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39548
diff changeset
   152
    validatepatterns(includepats)
8d8e61df8259 narrowspec: validate patterns when loading and saving spec file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39548
diff changeset
   153
    validatepatterns(excludepats)
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   154
    spec = format(includepats, excludepats)
38911
576eef1ab43d narrow: move .hg/narrowspec to .hg/store/narrowspec (BC)
Martin von Zweigbergk <martinvonz@google.com>
parents: 38910
diff changeset
   155
    repo.svfs.write(FILENAME, spec)
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   156
41229
50ca531f1f24 narrow: copy store narrowspec to working copy immediately
Martin von Zweigbergk <martinvonz@google.com>
parents: 41227
diff changeset
   157
def copytoworkingcopy(repo):
50ca531f1f24 narrow: copy store narrowspec to working copy immediately
Martin von Zweigbergk <martinvonz@google.com>
parents: 41227
diff changeset
   158
    spec = repo.svfs.read(FILENAME)
50ca531f1f24 narrow: copy store narrowspec to working copy immediately
Martin von Zweigbergk <martinvonz@google.com>
parents: 41227
diff changeset
   159
    repo.vfs.write(DIRSTATE_FILENAME, spec)
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   160
38908
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38879
diff changeset
   161
def savebackup(repo, backupname):
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38879
diff changeset
   162
    if repository.NARROW_REQUIREMENT not in repo.requirements:
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38879
diff changeset
   163
        return
41044
1e8d9f472ea1 narrow: keep narrowspec backup in store
Martin von Zweigbergk <martinvonz@google.com>
parents: 40729
diff changeset
   164
    svfs = repo.svfs
1e8d9f472ea1 narrow: keep narrowspec backup in store
Martin von Zweigbergk <martinvonz@google.com>
parents: 40729
diff changeset
   165
    svfs.tryunlink(backupname)
1e8d9f472ea1 narrow: keep narrowspec backup in store
Martin von Zweigbergk <martinvonz@google.com>
parents: 40729
diff changeset
   166
    util.copyfile(svfs.join(FILENAME), svfs.join(backupname), hardlink=True)
38875
fed6fe856333 narrow: extract part of narrowspec backup to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 36500
diff changeset
   167
38908
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38879
diff changeset
   168
def restorebackup(repo, backupname):
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38879
diff changeset
   169
    if repository.NARROW_REQUIREMENT not in repo.requirements:
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38879
diff changeset
   170
        return
41044
1e8d9f472ea1 narrow: keep narrowspec backup in store
Martin von Zweigbergk <martinvonz@google.com>
parents: 40729
diff changeset
   171
    util.rename(repo.svfs.join(backupname), repo.svfs.join(FILENAME))
38875
fed6fe856333 narrow: extract part of narrowspec backup to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 36500
diff changeset
   172
41227
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   173
def savewcbackup(repo, backupname):
38908
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38879
diff changeset
   174
    if repository.NARROW_REQUIREMENT not in repo.requirements:
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38879
diff changeset
   175
        return
41227
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   176
    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
   177
    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
   178
    # 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
   179
    if vfs.exists(DIRSTATE_FILENAME):
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   180
        util.copyfile(vfs.join(DIRSTATE_FILENAME), vfs.join(backupname),
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   181
                      hardlink=True)
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   182
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   183
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
   184
    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
   185
        return
41298
88a7c211b21e narrow: fix crash when restoring backup in legacy repo
Martin von Zweigbergk <martinvonz@google.com>
parents: 41238
diff changeset
   186
    # 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
   187
    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
   188
        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
   189
b74481038438 narrow: make dirstateguard back up and restore working copy narrowspec instead
Martin von Zweigbergk <martinvonz@google.com>
parents: 41177
diff changeset
   190
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
   191
    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
   192
        return
41298
88a7c211b21e narrow: fix crash when restoring backup in legacy repo
Martin von Zweigbergk <martinvonz@google.com>
parents: 41238
diff changeset
   193
    repo.vfs.tryunlink(backupname)
38875
fed6fe856333 narrow: extract part of narrowspec backup to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 36500
diff changeset
   194
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   195
def restrictpatterns(req_includes, req_excludes, repo_includes, repo_excludes):
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   196
    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
   197
    results in a logical AND operation
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   198
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   199
    :param req_includes: requested includes
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   200
    :param req_excludes: requested excludes
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   201
    :param repo_includes: repo includes
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   202
    :param repo_excludes: repo excludes
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   203
    :return: include patterns, exclude patterns, and invalid include patterns.
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   204
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   205
    >>> restrictpatterns({'f1','f2'}, {}, ['f1'], [])
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   206
    (set(['f1']), {}, [])
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   207
    >>> restrictpatterns({'f1'}, {}, ['f1','f2'], [])
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   208
    (set(['f1']), {}, [])
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   209
    >>> restrictpatterns({'f1/fc1', 'f3/fc3'}, {}, ['f1','f2'], [])
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   210
    (set(['f1/fc1']), {}, [])
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   211
    >>> restrictpatterns({'f1_fc1'}, {}, ['f1','f2'], [])
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   212
    ([], set(['path:.']), [])
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   213
    >>> restrictpatterns({'f1/../f2/fc2'}, {}, ['f1','f2'], [])
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   214
    (set(['f2/fc2']), {}, [])
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   215
    >>> restrictpatterns({'f1/../f3/fc3'}, {}, ['f1','f2'], [])
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   216
    ([], set(['path:.']), [])
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   217
    >>> restrictpatterns({'f1/$non_exitent_var'}, {}, ['f1','f2'], [])
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   218
    (set(['f1/$non_exitent_var']), {}, [])
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   219
    """
36137
b8bbe589fd47 narrowspec: consistently use set() to copy sets
Augie Fackler <augie@google.com>
parents: 36136
diff changeset
   220
    res_excludes = set(req_excludes)
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   221
    res_excludes.update(repo_excludes)
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   222
    invalid_includes = []
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   223
    if not req_includes:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   224
        res_includes = set(repo_includes)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   225
    elif 'path:.' not in repo_includes:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   226
        res_includes = []
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   227
        for req_include in req_includes:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   228
            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
   229
            if req_include in repo_includes:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   230
                res_includes.append(req_include)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   231
                continue
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   232
            valid = False
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   233
            for repo_include in repo_includes:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   234
                if req_include.startswith(repo_include + '/'):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   235
                    valid = True
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   236
                    res_includes.append(req_include)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   237
                    break
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   238
            if not valid:
36117
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   239
                invalid_includes.append(req_include)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   240
        if len(res_includes) == 0:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   241
            res_excludes = {'path:.'}
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   242
        else:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   243
            res_includes = set(res_includes)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   244
    else:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
   245
        res_includes = set(req_includes)
36138
8fd0a9e2d7e9 narrow: make restrictpatterns a little more idiomatic
Augie Fackler <augie@google.com>
parents: 36137
diff changeset
   246
    return res_includes, res_excludes, invalid_includes
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   247
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   248
# 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: 41044
diff changeset
   249
# system)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   250
def _deletecleanfiles(repo, files):
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   251
    for f in files:
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   252
        repo.wvfs.unlinkpath(f)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   253
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   254
def _writeaddedfiles(repo, pctx, files):
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   255
    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
   256
    addgaction = actions[merge.ACTION_GET].append
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   257
    mf = repo['.'].manifest()
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   258
    for f in files:
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   259
        if not repo.wvfs.exists(f):
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   260
            addgaction((f, (mf.flags(f), False), "narrowspec updated"))
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   261
    merge.applyupdates(repo, actions, wctx=repo[None],
42472
87a34c767384 merge: fix race that could cause wrong size in dirstate
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42430
diff changeset
   262
                       mctx=repo['.'], overwrite=False, wantfiledata=False)
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   263
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   264
def checkworkingcopynarrowspec(repo):
42430
4738c292a520 narrowspec: replace one recursion-avoidance hack with another
Martin von Zweigbergk <martinvonz@google.com>
parents: 42423
diff changeset
   265
    # Avoid infinite recursion when updating the working copy
4738c292a520 narrowspec: replace one recursion-avoidance hack with another
Martin von Zweigbergk <martinvonz@google.com>
parents: 42423
diff changeset
   266
    if getattr(repo, '_updatingnarrowspec', False):
4738c292a520 narrowspec: replace one recursion-avoidance hack with another
Martin von Zweigbergk <martinvonz@google.com>
parents: 42423
diff changeset
   267
        return
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   268
    storespec = repo.svfs.tryread(FILENAME)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   269
    wcspec = repo.vfs.tryread(DIRSTATE_FILENAME)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   270
    if wcspec != storespec:
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   271
        raise error.Abort(_("working copy's narrowspec is stale"),
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   272
                          hint=_("run 'hg tracked --update-working-copy'"))
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   273
41238
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   274
def updateworkingcopy(repo, assumeclean=False):
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   275
    """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
   276
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   277
    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
   278
    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
   279
    """
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   280
    oldspec = repo.vfs.tryread(DIRSTATE_FILENAME)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   281
    newspec = repo.svfs.tryread(FILENAME)
42430
4738c292a520 narrowspec: replace one recursion-avoidance hack with another
Martin von Zweigbergk <martinvonz@google.com>
parents: 42423
diff changeset
   282
    repo._updatingnarrowspec = True
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   283
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   284
    oldincludes, oldexcludes = parseconfig(repo.ui, oldspec)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   285
    newincludes, newexcludes = parseconfig(repo.ui, newspec)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   286
    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: 41044
diff changeset
   287
    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: 41044
diff changeset
   288
    addedmatch = matchmod.differencematcher(newmatch, oldmatch)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   289
    removedmatch = matchmod.differencematcher(oldmatch, newmatch)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   290
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   291
    ds = repo.dirstate
42213
84bd6ae2d1f6 narrow: also warn when not deleting untracked or ignored files
Martin von Zweigbergk <martinvonz@google.com>
parents: 42192
diff changeset
   292
    lookup, status = ds.status(removedmatch, subrepos=[], ignored=True,
84bd6ae2d1f6 narrow: also warn when not deleting untracked or ignored files
Martin von Zweigbergk <martinvonz@google.com>
parents: 42192
diff changeset
   293
                               clean=True, unknown=True)
41238
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   294
    trackeddirty = status.modified + status.added
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   295
    clean = status.clean
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   296
    if assumeclean:
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   297
        assert not trackeddirty
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   298
        clean.extend(lookup)
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   299
    else:
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   300
        trackeddirty.extend(lookup)
8c366af085f4 narrow: reuse narrowspec.updateworkingcopy() when narrowing
Martin von Zweigbergk <martinvonz@google.com>
parents: 41229
diff changeset
   301
    _deletecleanfiles(repo, clean)
42192
770f5f586ae5 narrow: make warning about possibly dirty files respect ui.relative-paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 41687
diff changeset
   302
    uipathfn = scmutil.getuipathfn(repo)
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   303
    for f in sorted(trackeddirty):
42192
770f5f586ae5 narrow: make warning about possibly dirty files respect ui.relative-paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 41687
diff changeset
   304
        repo.ui.status(_('not deleting possibly dirty file %s\n') % uipathfn(f))
42213
84bd6ae2d1f6 narrow: also warn when not deleting untracked or ignored files
Martin von Zweigbergk <martinvonz@google.com>
parents: 42192
diff changeset
   305
    for f in sorted(status.unknown):
84bd6ae2d1f6 narrow: also warn when not deleting untracked or ignored files
Martin von Zweigbergk <martinvonz@google.com>
parents: 42192
diff changeset
   306
        repo.ui.status(_('not deleting unknown file %s\n') % uipathfn(f))
84bd6ae2d1f6 narrow: also warn when not deleting untracked or ignored files
Martin von Zweigbergk <martinvonz@google.com>
parents: 42192
diff changeset
   307
    for f in sorted(status.ignored):
84bd6ae2d1f6 narrow: also warn when not deleting untracked or ignored files
Martin von Zweigbergk <martinvonz@google.com>
parents: 42192
diff changeset
   308
        repo.ui.status(_('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
   309
    for f in clean + trackeddirty:
41046
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   310
        ds.drop(f)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   311
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   312
    pctx = repo['.']
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   313
    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: 41044
diff changeset
   314
    for f in newfiles:
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   315
        ds.normallookup(f)
ce0bc2952e2a narrow: detect if narrowspec was changed in a different share
Martin von Zweigbergk <martinvonz@google.com>
parents: 41044
diff changeset
   316
    _writeaddedfiles(repo, pctx, newfiles)
42430
4738c292a520 narrowspec: replace one recursion-avoidance hack with another
Martin von Zweigbergk <martinvonz@google.com>
parents: 42423
diff changeset
   317
    repo._updatingnarrowspec = False