view hgext/narrow/narrowdirstate.py @ 44647:99fa161a883c

phabricator: extract the logic to amend diff properties to a function This will be needed on a separate code path when dealing with folding revisions. And since we know that will involve adding multiple local commmits to the diff properties instead of just one, restructure the logic slightly to allow it. Differential Revision: https://phab.mercurial-scm.org/D8312
author Matt Harbison <matt_harbison@yahoo.com>
date Mon, 16 Mar 2020 14:33:35 -0400
parents 687b865b95ad
children f927ad5a4e2c
line wrap: on
line source

# narrowdirstate.py - extensions to mercurial dirstate to support narrow clones
#
# Copyright 2017 Google, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

from __future__ import absolute_import

from mercurial.i18n import _
from mercurial import error


def wrapdirstate(repo, dirstate):
    """Add narrow spec dirstate ignore, block changes outside narrow spec."""

    def _editfunc(fn):
        def _wrapper(self, *args, **kwargs):
            narrowmatch = repo.narrowmatch()
            for f in args:
                if f is not None and not narrowmatch(f) and f not in self:
                    raise error.Abort(
                        _(
                            b"cannot track '%s' - it is outside "
                            + b"the narrow clone"
                        )
                        % f
                    )
            return fn(self, *args, **kwargs)

        return _wrapper

    class narrowdirstate(dirstate.__class__):
        # Prevent adding/editing/copying/deleting files that are outside the
        # sparse checkout
        @_editfunc
        def normal(self, *args, **kwargs):
            return super(narrowdirstate, self).normal(*args, **kwargs)

        @_editfunc
        def add(self, *args):
            return super(narrowdirstate, self).add(*args)

        @_editfunc
        def normallookup(self, *args):
            return super(narrowdirstate, self).normallookup(*args)

        @_editfunc
        def copy(self, *args):
            return super(narrowdirstate, self).copy(*args)

        @_editfunc
        def remove(self, *args):
            return super(narrowdirstate, self).remove(*args)

        @_editfunc
        def merge(self, *args):
            return super(narrowdirstate, self).merge(*args)

        def rebuild(self, parent, allfiles, changedfiles=None):
            if changedfiles is None:
                # Rebuilding entire dirstate, let's filter allfiles to match the
                # narrowspec.
                allfiles = [f for f in allfiles if repo.narrowmatch()(f)]
            super(narrowdirstate, self).rebuild(parent, allfiles, changedfiles)

    dirstate.__class__ = narrowdirstate
    return dirstate