comparison mercurial/changelog.py @ 17677:5c89e7fa5bc2

clfilter: introduce `filteredrevs` attribute on changelog This changeset allows changelog object to be "filtered". You can assign a set of revision numbers to the `changelog.filteredrevs` attributes. The changelog will then pretends these revision does not exists in this repo. A few methods need to be altered to achieve this behavior: - tip - __iter_ - irevs - hasnode - headrevs For consistency and to help debugging, the following methods are altered too. Tests tend to show it's not necessary to alter them but have them raise proper exception helps to detect bad acces to filtered revisions. - rev - node - linkrev - parentrevs - flags The following methods would also need alteration for consistency purpose but this is non-trivial and not done yet. - nodemap - strip The C version of headrevs is not run if there is any revision to filter. It'll need a proper rewrite later to restore performance.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Thu, 20 Sep 2012 19:02:47 +0200
parents e7cfe3587ea4
children 2894d180afa1
comparison
equal deleted inserted replaced
17676:f87683a1b02a 17677:5c89e7fa5bc2
118 self.version &= ~revlog.REVLOGGENERALDELTA 118 self.version &= ~revlog.REVLOGGENERALDELTA
119 self._generaldelta = False 119 self._generaldelta = False
120 self._realopener = opener 120 self._realopener = opener
121 self._delayed = False 121 self._delayed = False
122 self._divert = False 122 self._divert = False
123 self.filteredrevs = ()
124
125 def tip(self):
126 """filtered version of revlog.tip"""
127 for i in xrange(len(self) -1, -2, -1):
128 if i not in self.filteredrevs:
129 return self.node(i)
130
131 def __iter__(self):
132 """filtered version of revlog.__iter__"""
133 for i in xrange(len(self)):
134 if i not in self.filteredrevs:
135 yield i
136
137 def revs(self, start=0, stop=None):
138 """filtered version of revlog.revs"""
139 for i in super(changelog, self).revs(start, stop):
140 if i not in self.filteredrevs:
141 yield i
142
143 @util.propertycache
144 def nodemap(self):
145 # XXX need filtering too
146 self.rev(self.node(0))
147 return self._nodecache
148
149 def hasnode(self, node):
150 """filtered version of revlog.hasnode"""
151 try:
152 i = self.rev(node)
153 return i not in self.filteredrevs
154 except KeyError:
155 return False
156
157 def headrevs(self):
158 if self.filteredrevs:
159 # XXX we should fix and use the C version
160 return self._headrevs()
161 return super(changelog, self).headrevs()
162
163 def strip(self, *args, **kwargs):
164 # XXX make something better than assert
165 # We can't expect proper strip behavior if we are filtered.
166 assert not self.filteredrevs
167 super(changelog, self).strip(*args, **kwargs)
168
169 def rev(self, node):
170 """filtered version of revlog.rev"""
171 r = super(changelog, self).rev(node)
172 if r in self.filteredrevs:
173 raise error.LookupError(node, self.indexfile, _('no node'))
174 return r
175
176 def node(self, rev):
177 """filtered version of revlog.node"""
178 if rev in self.filteredrevs:
179 raise IndexError(rev)
180 return super(changelog, self).node(rev)
181
182 def linkrev(self, rev):
183 """filtered version of revlog.linkrev"""
184 if rev in self.filteredrevs:
185 raise IndexError(rev)
186 return super(changelog, self).linkrev(rev)
187
188 def parentrevs(self, rev):
189 """filtered version of revlog.parentrevs"""
190 if rev in self.filteredrevs:
191 raise IndexError(rev)
192 return super(changelog, self).parentrevs(rev)
193
194 def flags(self, rev):
195 """filtered version of revlog.flags"""
196 if rev in self.filteredrevs:
197 raise IndexError(rev)
198 return super(changelog, self).flags(rev)
123 199
124 def delayupdate(self): 200 def delayupdate(self):
125 "delay visibility of index updates to other readers" 201 "delay visibility of index updates to other readers"
126 self._delayed = True 202 self._delayed = True
127 self._divert = (len(self) == 0) 203 self._divert = (len(self) == 0)