hgext/narrow/narrowdirstate.py
author Martin von Zweigbergk <martinvonz@google.com>
Fri, 03 Aug 2018 10:56:07 -0700
changeset 38836 fed6fe856333
parent 38128 1cba497491be
child 38869 ad24b581e4d9
permissions -rw-r--r--
narrow: extract part of narrowspec backup to core Just a little preparation for the next patch. Differential Revision: https://phab.mercurial-scm.org/D4095
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
# narrowdirstate.py - extensions to mercurial dirstate to support narrow clones
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
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    10
from mercurial.i18n import _
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    11
from mercurial import (
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,
36160
9fd8c2a3db5a narrowspec: move module into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36079
diff changeset
    14
    narrowspec,
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    15
)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    16
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    17
def wrapdirstate(repo, dirstate):
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    18
    """Add narrow spec dirstate ignore, block changes outside narrow spec."""
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    19
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    20
    def _editfunc(fn):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    21
        def _wrapper(self, *args):
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    22
            dirstate = repo.dirstate
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    23
            narrowmatch = repo.narrowmatch()
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    24
            for f in args:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    25
                if f is not None and not narrowmatch(f) and f not in dirstate:
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    26
                    raise error.Abort(_("cannot track '%s' - it is outside " +
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    27
                        "the narrow clone") % f)
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    28
            return fn(self, *args)
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    29
        return _wrapper
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    30
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    31
    def _narrowbackupname(backupname):
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    32
        assert 'dirstate' in backupname
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    33
        return backupname.replace('dirstate', narrowspec.FILENAME)
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    34
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    35
    class narrowdirstate(dirstate.__class__):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    36
        def walk(self, match, subrepos, unknown, ignored, full=True,
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    37
                 narrowonly=True):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    38
            if narrowonly:
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    39
                # hack to not exclude explicitly-specified paths so that they
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    40
                # can be warned later on e.g. dirstate.add()
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    41
                em = matchmod.exact(match._root, match._cwd, match.files())
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    42
                nm = matchmod.unionmatcher([repo.narrowmatch(), em])
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    43
                match = matchmod.intersectmatchers(match, nm)
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    44
            return super(narrowdirstate, self).walk(match, subrepos, unknown,
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    45
                                                    ignored, full)
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    46
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    47
        # Prevent adding/editing/copying/deleting files that are outside the
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    48
        # sparse checkout
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    49
        @_editfunc
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    50
        def normal(self, *args):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    51
            return super(narrowdirstate, self).normal(*args)
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    52
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    53
        @_editfunc
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    54
        def add(self, *args):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    55
            return super(narrowdirstate, self).add(*args)
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    56
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    57
        @_editfunc
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    58
        def normallookup(self, *args):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    59
            return super(narrowdirstate, self).normallookup(*args)
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    60
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    61
        @_editfunc
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    62
        def copy(self, *args):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    63
            return super(narrowdirstate, self).copy(*args)
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    64
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    65
        @_editfunc
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    66
        def remove(self, *args):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    67
            return super(narrowdirstate, self).remove(*args)
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    68
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    69
        @_editfunc
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    70
        def merge(self, *args):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    71
            return super(narrowdirstate, self).merge(*args)
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    72
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    73
        def rebuild(self, parent, allfiles, changedfiles=None):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    74
            if changedfiles is None:
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    75
                # Rebuilding entire dirstate, let's filter allfiles to match the
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    76
                # narrowspec.
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    77
                allfiles = [f for f in allfiles if repo.narrowmatch()(f)]
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    78
            super(narrowdirstate, self).rebuild(parent, allfiles, changedfiles)
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    79
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    80
        def restorebackup(self, tr, backupname):
38836
fed6fe856333 narrow: extract part of narrowspec backup to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 38128
diff changeset
    81
            narrowspec.restorebackup(self._opener,
fed6fe856333 narrow: extract part of narrowspec backup to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 38128
diff changeset
    82
                                     _narrowbackupname(backupname))
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    83
            super(narrowdirstate, self).restorebackup(tr, backupname)
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    84
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    85
        def savebackup(self, tr, backupname):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    86
            super(narrowdirstate, self).savebackup(tr, backupname)
38836
fed6fe856333 narrow: extract part of narrowspec backup to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 38128
diff changeset
    87
            narrowspec.savebackup(self._opener, _narrowbackupname(backupname))
36079
a2a6e724d61a narrow: import experimental extension from narrowhg revision cb51d673e9c5
Augie Fackler <augie@google.com>
parents:
diff changeset
    88
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    89
        def clearbackup(self, tr, backupname):
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    90
            super(narrowdirstate, self).clearbackup(tr, backupname)
38836
fed6fe856333 narrow: extract part of narrowspec backup to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 38128
diff changeset
    91
            narrowspec.clearbackup(self._opener, _narrowbackupname(backupname))
38128
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    92
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    93
    dirstate.__class__ = narrowdirstate
1cba497491be narrow: only wrap dirstate functions once, instead of per-reposetup
Kyle Lippincott <spectral@google.com>
parents: 36200
diff changeset
    94
    return dirstate