190 def _setupdirstate(ui): |
190 def _setupdirstate(ui): |
191 """Modify the dirstate to prevent stat'ing excluded files, |
191 """Modify the dirstate to prevent stat'ing excluded files, |
192 and to prevent modifications to files outside the checkout. |
192 and to prevent modifications to files outside the checkout. |
193 """ |
193 """ |
194 |
194 |
195 # The atrocity below is needed to wrap dirstate._ignore. It is a cached |
195 def walk(orig, self, match, subrepos, unknown, ignored, full=True): |
196 # property, which means normal function wrapping doesn't work. |
196 match = matchmod.intersectmatchers(match, self._sparsematcher) |
197 class ignorewrapper(object): |
197 return orig(self, match, subrepos, unknown, ignored, full) |
198 def __init__(self, orig): |
198 |
199 self.orig = orig |
199 extensions.wrapfunction(dirstate.dirstate, 'walk', walk) |
200 self.origignore = None |
|
201 self.func = None |
|
202 self.sparsematch = None |
|
203 |
|
204 def __get__(self, obj, type=None): |
|
205 origignore = self.orig.__get__(obj) |
|
206 |
|
207 sparsematch = obj._sparsematcher |
|
208 if sparsematch.always(): |
|
209 return origignore |
|
210 |
|
211 if self.sparsematch != sparsematch or self.origignore != origignore: |
|
212 self.func = matchmod.unionmatcher([ |
|
213 origignore, matchmod.negatematcher(sparsematch)]) |
|
214 self.sparsematch = sparsematch |
|
215 self.origignore = origignore |
|
216 return self.func |
|
217 |
|
218 def __set__(self, obj, value): |
|
219 return self.orig.__set__(obj, value) |
|
220 |
|
221 def __delete__(self, obj): |
|
222 return self.orig.__delete__(obj) |
|
223 |
|
224 replacefilecache(dirstate.dirstate, '_ignore', ignorewrapper) |
|
225 |
200 |
226 # dirstate.rebuild should not add non-matching files |
201 # dirstate.rebuild should not add non-matching files |
227 def _rebuild(orig, self, parent, allfiles, changedfiles=None): |
202 def _rebuild(orig, self, parent, allfiles, changedfiles=None): |
228 matcher = self._sparsematcher |
203 matcher = self._sparsematcher |
229 if not matcher.always(): |
204 if not matcher.always(): |