comparison mercurial/context.py @ 31261:bd884ef2ee46

context: remove uses of manifest.matches This removes the uses of manifest.matches in context.py in favor of the new manifest.diff(match) api. This is part of removing manifest.matches since it is O(manifest). To drop the dependency on ctx._manifestmatches(s) we transfer responsibilty for creating status oriented manifests over to ctx._buildstatusmanifest(s). This already existed for workingctx, we just need to implement a simple version for basectx. The old _manifestmatches functionality is basically identical to the _buildstatusmanifest functionality (minus the matching part), so no behavior should be lost.
author Durham Goode <durham@fb.com>
date Tue, 07 Mar 2017 17:52:45 -0800
parents aac054e5389b
children 8908f985570c
comparison
equal deleted inserted replaced
31260:aac054e5389b 31261:bd884ef2ee46
16 from .node import ( 16 from .node import (
17 addednodeid, 17 addednodeid,
18 bin, 18 bin,
19 hex, 19 hex,
20 modifiednodeid, 20 modifiednodeid,
21 newnodeid,
22 nullid, 21 nullid,
23 nullrev, 22 nullrev,
24 short, 23 short,
25 wdirid, 24 wdirid,
26 wdirnodes, 25 wdirnodes,
89 return self.filectx(key) 88 return self.filectx(key)
90 89
91 def __iter__(self): 90 def __iter__(self):
92 return iter(self._manifest) 91 return iter(self._manifest)
93 92
94 def _manifestmatches(self, match, s): 93 def _buildstatusmanifest(self, status):
95 """generate a new manifest filtered by the match argument 94 """Builds a manifest that includes the given status results, if this is
96 95 a working copy context. For non-working copy contexts, it just returns
97 This method is for internal use only and mainly exists to provide an 96 the normal manifest."""
98 object oriented way for other contexts to customize the manifest 97 return self.manifest()
99 generation.
100 """
101 return self.manifest().matches(match)
102 98
103 def _matchstatus(self, other, match): 99 def _matchstatus(self, other, match):
104 """return match.always if match is none 100 """return match.always if match is none
105 101
106 This internal method provides a way for child objects to override the 102 This internal method provides a way for child objects to override the
117 # 1000 and cache it so that when you read 1001, we just need to apply a 113 # 1000 and cache it so that when you read 1001, we just need to apply a
118 # delta to what's in the cache. So that's one full reconstruction + one 114 # delta to what's in the cache. So that's one full reconstruction + one
119 # delta application. 115 # delta application.
120 mf2 = None 116 mf2 = None
121 if self.rev() is not None and self.rev() < other.rev(): 117 if self.rev() is not None and self.rev() < other.rev():
122 mf2 = self._manifestmatches(match, s) 118 mf2 = self._buildstatusmanifest(s)
123 mf1 = other._manifestmatches(match, s) 119 mf1 = other._buildstatusmanifest(s)
124 if mf2 is None: 120 if mf2 is None:
125 mf2 = self._manifestmatches(match, s) 121 mf2 = self._buildstatusmanifest(s)
126 122
127 modified, added = [], [] 123 modified, added = [], []
128 removed = [] 124 removed = []
129 clean = [] 125 clean = []
130 deleted, unknown, ignored = s.deleted, s.unknown, s.ignored 126 deleted, unknown, ignored = s.deleted, s.unknown, s.ignored
131 deletedset = set(deleted) 127 deletedset = set(deleted)
132 d = mf1.diff(mf2, clean=listclean) 128 d = mf1.diff(mf2, match=match, clean=listclean)
133 for fn, value in d.iteritems(): 129 for fn, value in d.iteritems():
134 if fn in deletedset: 130 if fn in deletedset:
135 continue 131 continue
136 if value is None: 132 if value is None:
137 clean.append(fn) 133 clean.append(fn)
154 else: 150 else:
155 clean.append(fn) 151 clean.append(fn)
156 152
157 if removed: 153 if removed:
158 # need to filter files if they are already reported as removed 154 # need to filter files if they are already reported as removed
159 unknown = [fn for fn in unknown if fn not in mf1] 155 unknown = [fn for fn in unknown if fn not in mf1 and
160 ignored = [fn for fn in ignored if fn not in mf1] 156 (not match or match(fn))]
157 ignored = [fn for fn in ignored if fn not in mf1 and
158 (not match or match(fn))]
161 # if they're deleted, don't report them as removed 159 # if they're deleted, don't report them as removed
162 removed = [fn for fn in removed if fn not in deletedset] 160 removed = [fn for fn in removed if fn not in deletedset]
163 161
164 return scmutil.status(modified, added, removed, deleted, unknown, 162 return scmutil.status(modified, added, removed, deleted, unknown,
165 ignored, clean) 163 ignored, clean)
1579 self._repo.dirstate.write(self._repo.currenttransaction()) 1577 self._repo.dirstate.write(self._repo.currenttransaction())
1580 except error.LockError: 1578 except error.LockError:
1581 pass 1579 pass
1582 return modified, fixup 1580 return modified, fixup
1583 1581
1584 def _manifestmatches(self, match, s):
1585 """Slow path for workingctx
1586
1587 The fast path is when we compare the working directory to its parent
1588 which means this function is comparing with a non-parent; therefore we
1589 need to build a manifest and return what matches.
1590 """
1591 mf = self._repo['.']._manifestmatches(match, s)
1592 for f in s.modified + s.added:
1593 mf[f] = newnodeid
1594 mf.setflag(f, self.flags(f))
1595 for f in s.removed:
1596 if f in mf:
1597 del mf[f]
1598 return mf
1599
1600 def _dirstatestatus(self, match=None, ignored=False, clean=False, 1582 def _dirstatestatus(self, match=None, ignored=False, clean=False,
1601 unknown=False): 1583 unknown=False):
1602 '''Gets the status from the dirstate -- internal use only.''' 1584 '''Gets the status from the dirstate -- internal use only.'''
1603 listignored, listclean, listunknown = ignored, clean, unknown 1585 listignored, listclean, listunknown = ignored, clean, unknown
1604 match = match or matchmod.always(self._repo.root, self._repo.getcwd()) 1586 match = match or matchmod.always(self._repo.root, self._repo.getcwd())