##// END OF EJS Templates
narrow: avoid looking up dirstate again when editing dirstate...
Martin von Zweigbergk -
r39996:1a7d901a default
parent child Browse files
Show More
@@ -1,76 +1,75 b''
1 # narrowdirstate.py - extensions to mercurial dirstate to support narrow clones
1 # narrowdirstate.py - extensions to mercurial dirstate to support narrow clones
2 #
2 #
3 # Copyright 2017 Google, Inc.
3 # Copyright 2017 Google, Inc.
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from mercurial.i18n import _
10 from mercurial.i18n import _
11 from mercurial import (
11 from mercurial import (
12 error,
12 error,
13 match as matchmod,
13 match as matchmod,
14 )
14 )
15
15
16 def wrapdirstate(repo, dirstate):
16 def wrapdirstate(repo, dirstate):
17 """Add narrow spec dirstate ignore, block changes outside narrow spec."""
17 """Add narrow spec dirstate ignore, block changes outside narrow spec."""
18
18
19 def _editfunc(fn):
19 def _editfunc(fn):
20 def _wrapper(self, *args):
20 def _wrapper(self, *args):
21 dirstate = repo.dirstate
22 narrowmatch = repo.narrowmatch()
21 narrowmatch = repo.narrowmatch()
23 for f in args:
22 for f in args:
24 if f is not None and not narrowmatch(f) and f not in dirstate:
23 if f is not None and not narrowmatch(f) and f not in self:
25 raise error.Abort(_("cannot track '%s' - it is outside " +
24 raise error.Abort(_("cannot track '%s' - it is outside " +
26 "the narrow clone") % f)
25 "the narrow clone") % f)
27 return fn(self, *args)
26 return fn(self, *args)
28 return _wrapper
27 return _wrapper
29
28
30 class narrowdirstate(dirstate.__class__):
29 class narrowdirstate(dirstate.__class__):
31 def walk(self, match, subrepos, unknown, ignored, full=True,
30 def walk(self, match, subrepos, unknown, ignored, full=True,
32 narrowonly=True):
31 narrowonly=True):
33 if narrowonly:
32 if narrowonly:
34 # hack to not exclude explicitly-specified paths so that they
33 # hack to not exclude explicitly-specified paths so that they
35 # can be warned later on e.g. dirstate.add()
34 # can be warned later on e.g. dirstate.add()
36 em = matchmod.exact(match._root, match._cwd, match.files())
35 em = matchmod.exact(match._root, match._cwd, match.files())
37 nm = matchmod.unionmatcher([repo.narrowmatch(), em])
36 nm = matchmod.unionmatcher([repo.narrowmatch(), em])
38 match = matchmod.intersectmatchers(match, nm)
37 match = matchmod.intersectmatchers(match, nm)
39 return super(narrowdirstate, self).walk(match, subrepos, unknown,
38 return super(narrowdirstate, self).walk(match, subrepos, unknown,
40 ignored, full)
39 ignored, full)
41
40
42 # Prevent adding/editing/copying/deleting files that are outside the
41 # Prevent adding/editing/copying/deleting files that are outside the
43 # sparse checkout
42 # sparse checkout
44 @_editfunc
43 @_editfunc
45 def normal(self, *args):
44 def normal(self, *args):
46 return super(narrowdirstate, self).normal(*args)
45 return super(narrowdirstate, self).normal(*args)
47
46
48 @_editfunc
47 @_editfunc
49 def add(self, *args):
48 def add(self, *args):
50 return super(narrowdirstate, self).add(*args)
49 return super(narrowdirstate, self).add(*args)
51
50
52 @_editfunc
51 @_editfunc
53 def normallookup(self, *args):
52 def normallookup(self, *args):
54 return super(narrowdirstate, self).normallookup(*args)
53 return super(narrowdirstate, self).normallookup(*args)
55
54
56 @_editfunc
55 @_editfunc
57 def copy(self, *args):
56 def copy(self, *args):
58 return super(narrowdirstate, self).copy(*args)
57 return super(narrowdirstate, self).copy(*args)
59
58
60 @_editfunc
59 @_editfunc
61 def remove(self, *args):
60 def remove(self, *args):
62 return super(narrowdirstate, self).remove(*args)
61 return super(narrowdirstate, self).remove(*args)
63
62
64 @_editfunc
63 @_editfunc
65 def merge(self, *args):
64 def merge(self, *args):
66 return super(narrowdirstate, self).merge(*args)
65 return super(narrowdirstate, self).merge(*args)
67
66
68 def rebuild(self, parent, allfiles, changedfiles=None):
67 def rebuild(self, parent, allfiles, changedfiles=None):
69 if changedfiles is None:
68 if changedfiles is None:
70 # Rebuilding entire dirstate, let's filter allfiles to match the
69 # Rebuilding entire dirstate, let's filter allfiles to match the
71 # narrowspec.
70 # narrowspec.
72 allfiles = [f for f in allfiles if repo.narrowmatch()(f)]
71 allfiles = [f for f in allfiles if repo.narrowmatch()(f)]
73 super(narrowdirstate, self).rebuild(parent, allfiles, changedfiles)
72 super(narrowdirstate, self).rebuild(parent, allfiles, changedfiles)
74
73
75 dirstate.__class__ = narrowdirstate
74 dirstate.__class__ = narrowdirstate
76 return dirstate
75 return dirstate
General Comments 0
You need to be logged in to leave comments. Login now