Show More
@@ -28,7 +28,6 b' from . import (' | |||||
28 | narrowchangegroup, |
|
28 | narrowchangegroup, | |
29 | narrowcommands, |
|
29 | narrowcommands, | |
30 | narrowcopies, |
|
30 | narrowcopies, | |
31 | narrowdirstate, |
|
|||
32 | narrowpatch, |
|
31 | narrowpatch, | |
33 | narrowrepo, |
|
32 | narrowrepo, | |
34 | narrowrevlog, |
|
33 | narrowrevlog, | |
@@ -72,10 +71,9 b' def reposetup(ui, repo):' | |||||
72 | if not repo.local(): |
|
71 | if not repo.local(): | |
73 | return |
|
72 | return | |
74 |
|
73 | |||
75 | narrowrepo.wraprepo(repo) |
|
|||
76 | if changegroup.NARROW_REQUIREMENT in repo.requirements: |
|
74 | if changegroup.NARROW_REQUIREMENT in repo.requirements: | |
|
75 | narrowrepo.wraprepo(repo) | |||
77 | narrowcopies.setup(repo) |
|
76 | narrowcopies.setup(repo) | |
78 | narrowdirstate.setup(repo) |
|
|||
79 | narrowpatch.setup(repo) |
|
77 | narrowpatch.setup(repo) | |
80 | narrowwirepeer.reposetup(repo) |
|
78 | narrowwirepeer.reposetup(repo) | |
81 |
|
79 |
@@ -9,74 +9,91 b' 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 | dirstate, |
|
|||
13 | error, |
|
12 | error, | |
14 | extensions, |
|
|||
15 | match as matchmod, |
|
13 | match as matchmod, | |
16 | narrowspec, |
|
14 | narrowspec, | |
17 | util as hgutil, |
|
15 | util as hgutil, | |
18 | ) |
|
16 | ) | |
19 |
|
17 | |||
20 | def setup(repo): |
|
18 | def wrapdirstate(repo, dirstate): | |
21 | """Add narrow spec dirstate ignore, block changes outside narrow spec.""" |
|
19 | """Add narrow spec dirstate ignore, block changes outside narrow spec.""" | |
22 |
|
20 | |||
23 | def walk(orig, self, match, subrepos, unknown, ignored, full=True, |
|
21 | def _editfunc(fn): | |
24 | narrowonly=True): |
|
22 | def _wrapper(self, *args): | |
25 | if narrowonly: |
|
|||
26 | # hack to not exclude explicitly-specified paths so that they can |
|
|||
27 | # be warned later on e.g. dirstate.add() |
|
|||
28 | em = matchmod.exact(match._root, match._cwd, match.files()) |
|
|||
29 | nm = matchmod.unionmatcher([repo.narrowmatch(), em]) |
|
|||
30 | match = matchmod.intersectmatchers(match, nm) |
|
|||
31 | return orig(self, match, subrepos, unknown, ignored, full) |
|
|||
32 |
|
||||
33 | extensions.wrapfunction(dirstate.dirstate, 'walk', walk) |
|
|||
34 |
|
||||
35 | # Prevent adding files that are outside the sparse checkout |
|
|||
36 | editfuncs = ['normal', 'add', 'normallookup', 'copy', 'remove', 'merge'] |
|
|||
37 | for func in editfuncs: |
|
|||
38 | def _wrapper(orig, self, *args): |
|
|||
39 | dirstate = repo.dirstate |
|
23 | dirstate = repo.dirstate | |
40 | narrowmatch = repo.narrowmatch() |
|
24 | narrowmatch = repo.narrowmatch() | |
41 | for f in args: |
|
25 | for f in args: | |
42 | if f is not None and not narrowmatch(f) and f not in dirstate: |
|
26 | if f is not None and not narrowmatch(f) and f not in dirstate: | |
43 | raise error.Abort(_("cannot track '%s' - it is outside " + |
|
27 | raise error.Abort(_("cannot track '%s' - it is outside " + | |
44 | "the narrow clone") % f) |
|
28 | "the narrow clone") % f) | |
45 |
return |
|
29 | return fn(self, *args) | |
46 | extensions.wrapfunction(dirstate.dirstate, func, _wrapper) |
|
30 | return _wrapper | |
47 |
|
||||
48 | def filterrebuild(orig, self, parent, allfiles, changedfiles=None): |
|
|||
49 | if changedfiles is None: |
|
|||
50 | # Rebuilding entire dirstate, let's filter allfiles to match the |
|
|||
51 | # narrowspec. |
|
|||
52 | allfiles = [f for f in allfiles if repo.narrowmatch()(f)] |
|
|||
53 | orig(self, parent, allfiles, changedfiles) |
|
|||
54 |
|
||||
55 | extensions.wrapfunction(dirstate.dirstate, 'rebuild', filterrebuild) |
|
|||
56 |
|
31 | |||
57 | def _narrowbackupname(backupname): |
|
32 | def _narrowbackupname(backupname): | |
58 | assert 'dirstate' in backupname |
|
33 | assert 'dirstate' in backupname | |
59 | return backupname.replace('dirstate', narrowspec.FILENAME) |
|
34 | return backupname.replace('dirstate', narrowspec.FILENAME) | |
60 |
|
35 | |||
61 | def restorebackup(orig, self, tr, backupname): |
|
36 | class narrowdirstate(dirstate.__class__): | |
62 | self._opener.rename(_narrowbackupname(backupname), narrowspec.FILENAME, |
|
37 | def walk(self, match, subrepos, unknown, ignored, full=True, | |
63 |
|
|
38 | narrowonly=True): | |
64 | orig(self, tr, backupname) |
|
39 | if narrowonly: | |
|
40 | # hack to not exclude explicitly-specified paths so that they | |||
|
41 | # can be warned later on e.g. dirstate.add() | |||
|
42 | em = matchmod.exact(match._root, match._cwd, match.files()) | |||
|
43 | nm = matchmod.unionmatcher([repo.narrowmatch(), em]) | |||
|
44 | match = matchmod.intersectmatchers(match, nm) | |||
|
45 | return super(narrowdirstate, self).walk(match, subrepos, unknown, | |||
|
46 | ignored, full) | |||
65 |
|
47 | |||
66 | extensions.wrapfunction(dirstate.dirstate, 'restorebackup', restorebackup) |
|
48 | # Prevent adding/editing/copying/deleting files that are outside the | |
|
49 | # sparse checkout | |||
|
50 | @_editfunc | |||
|
51 | def normal(self, *args): | |||
|
52 | return super(narrowdirstate, self).normal(*args) | |||
67 |
|
53 | |||
68 | def savebackup(orig, self, tr, backupname): |
|
54 | @_editfunc | |
69 | orig(self, tr, backupname) |
|
55 | def add(self, *args): | |
|
56 | return super(narrowdirstate, self).add(*args) | |||
|
57 | ||||
|
58 | @_editfunc | |||
|
59 | def normallookup(self, *args): | |||
|
60 | return super(narrowdirstate, self).normallookup(*args) | |||
|
61 | ||||
|
62 | @_editfunc | |||
|
63 | def copy(self, *args): | |||
|
64 | return super(narrowdirstate, self).copy(*args) | |||
70 |
|
65 | |||
71 | narrowbackupname = _narrowbackupname(backupname) |
|
66 | @_editfunc | |
72 | self._opener.tryunlink(narrowbackupname) |
|
67 | def remove(self, *args): | |
73 | hgutil.copyfile(self._opener.join(narrowspec.FILENAME), |
|
68 | return super(narrowdirstate, self).remove(*args) | |
74 | self._opener.join(narrowbackupname), hardlink=True) |
|
69 | ||
|
70 | @_editfunc | |||
|
71 | def merge(self, *args): | |||
|
72 | return super(narrowdirstate, self).merge(*args) | |||
|
73 | ||||
|
74 | def rebuild(self, parent, allfiles, changedfiles=None): | |||
|
75 | if changedfiles is None: | |||
|
76 | # Rebuilding entire dirstate, let's filter allfiles to match the | |||
|
77 | # narrowspec. | |||
|
78 | allfiles = [f for f in allfiles if repo.narrowmatch()(f)] | |||
|
79 | super(narrowdirstate, self).rebuild(parent, allfiles, changedfiles) | |||
75 |
|
80 | |||
76 | extensions.wrapfunction(dirstate.dirstate, 'savebackup', savebackup) |
|
81 | def restorebackup(self, tr, backupname): | |
|
82 | self._opener.rename(_narrowbackupname(backupname), | |||
|
83 | narrowspec.FILENAME, checkambig=True) | |||
|
84 | super(narrowdirstate, self).restorebackup(tr, backupname) | |||
|
85 | ||||
|
86 | def savebackup(self, tr, backupname): | |||
|
87 | super(narrowdirstate, self).savebackup(tr, backupname) | |||
77 |
|
88 | |||
78 | def clearbackup(orig, self, tr, backupname): |
|
89 | narrowbackupname = _narrowbackupname(backupname) | |
79 | orig(self, tr, backupname) |
|
90 | self._opener.tryunlink(narrowbackupname) | |
80 | self._opener.unlink(_narrowbackupname(backupname)) |
|
91 | hgutil.copyfile(self._opener.join(narrowspec.FILENAME), | |
|
92 | self._opener.join(narrowbackupname), hardlink=True) | |||
81 |
|
93 | |||
82 | extensions.wrapfunction(dirstate.dirstate, 'clearbackup', clearbackup) |
|
94 | def clearbackup(self, tr, backupname): | |
|
95 | super(narrowdirstate, self).clearbackup(tr, backupname) | |||
|
96 | self._opener.unlink(_narrowbackupname(backupname)) | |||
|
97 | ||||
|
98 | dirstate.__class__ = narrowdirstate | |||
|
99 | return dirstate |
@@ -15,6 +15,7 b' from mercurial import (' | |||||
15 | ) |
|
15 | ) | |
16 |
|
16 | |||
17 | from . import ( |
|
17 | from . import ( | |
|
18 | narrowdirstate, | |||
18 | narrowrevlog, |
|
19 | narrowrevlog, | |
19 | ) |
|
20 | ) | |
20 |
|
21 | |||
@@ -62,4 +63,8 b' def wraprepo(repo):' | |||||
62 | return scmutil.status(modified, added, removed, deleted, unknown, |
|
63 | return scmutil.status(modified, added, removed, deleted, unknown, | |
63 | ignored, clean) |
|
64 | ignored, clean) | |
64 |
|
65 | |||
|
66 | def _makedirstate(self): | |||
|
67 | dirstate = super(narrowrepository, self)._makedirstate() | |||
|
68 | return narrowdirstate.wrapdirstate(self, dirstate) | |||
|
69 | ||||
65 | repo.__class__ = narrowrepository |
|
70 | repo.__class__ = narrowrepository |
@@ -778,6 +778,9 b' class localrepository(object):' | |||||
778 |
|
778 | |||
779 | @repofilecache('dirstate') |
|
779 | @repofilecache('dirstate') | |
780 | def dirstate(self): |
|
780 | def dirstate(self): | |
|
781 | return self._makedirstate() | |||
|
782 | ||||
|
783 | def _makedirstate(self): | |||
781 | sparsematchfn = lambda: sparse.matcher(self) |
|
784 | sparsematchfn = lambda: sparse.matcher(self) | |
782 |
|
785 | |||
783 | return dirstate.dirstate(self.vfs, self.ui, self.root, |
|
786 | return dirstate.dirstate(self.vfs, self.ui, self.root, |
@@ -72,29 +72,31 b' have this method available in narrowhg p' | |||||
72 | > for f in repo[b'.'].manifest().walk(added): |
|
72 | > for f in repo[b'.'].manifest().walk(added): | |
73 | > repo.dirstate.normallookup(f) |
|
73 | > repo.dirstate.normallookup(f) | |
74 | > |
|
74 | > | |
75 |
> def |
|
75 | > def wrapds(ui, repo, ds): | |
76 | > def wrapds(orig, self): |
|
76 | > class expandingdirstate(ds.__class__): | |
77 | > ds = orig(self) |
|
77 | > @hgutil.propertycache | |
78 | > class expandingdirstate(ds.__class__): |
|
78 | > def _map(self): | |
79 | > @hgutil.propertycache |
|
79 | > ret = super(expandingdirstate, self)._map | |
80 | > def _map(self): |
|
80 | > with repo.wlock(), repo.lock(), repo.transaction( | |
81 | > ret = super(expandingdirstate, self)._map |
|
81 | > b'expandnarrowspec'): | |
82 | > with repo.wlock(), repo.lock(), repo.transaction( |
|
82 | > expandnarrowspec(ui, repo, | |
83 | > b'expandnarrowspec'): |
|
83 | > encoding.environ.get(b'DIRSTATEINCLUDES')) | |
84 | > expandnarrowspec(ui, repo, |
|
84 | > return ret | |
85 | > encoding.environ.get(b'DIRSTATEINCLUDES')) |
|
85 | > ds.__class__ = expandingdirstate | |
86 |
|
|
86 | > return ds | |
87 | > ds.__class__ = expandingdirstate |
|
|||
88 | > return ds |
|
|||
89 | > return wrapds |
|
|||
90 | > |
|
87 | > | |
91 | > def reposetup(ui, repo): |
|
88 | > def reposetup(ui, repo): | |
92 | > extensions.wrapfilecache(localrepo.localrepository, b'dirstate', |
|
89 | > class expandingrepo(repo.__class__): | |
93 | > makeds(ui, repo)) |
|
90 | > def _makedirstate(self): | |
94 | > def overridepatch(orig, *args, **kwargs): |
|
91 | > dirstate = super(expandingrepo, self)._makedirstate() | |
|
92 | > return wrapds(ui, repo, dirstate) | |||
|
93 | > repo.__class__ = expandingrepo | |||
|
94 | > | |||
|
95 | > def extsetup(unused_ui): | |||
|
96 | > def overridepatch(orig, ui, repo, *args, **kwargs): | |||
95 | > with repo.wlock(): |
|
97 | > with repo.wlock(): | |
96 | > expandnarrowspec(ui, repo, encoding.environ.get(b'PATCHINCLUDES')) |
|
98 | > expandnarrowspec(ui, repo, encoding.environ.get(b'PATCHINCLUDES')) | |
97 | > return orig(*args, **kwargs) |
|
99 | > return orig(ui, repo, *args, **kwargs) | |
98 | > |
|
100 | > | |
99 | > extensions.wrapfunction(patch, b'patch', overridepatch) |
|
101 | > extensions.wrapfunction(patch, b'patch', overridepatch) | |
100 | > EOF |
|
102 | > EOF |
General Comments 0
You need to be logged in to leave comments.
Login now