219 # Abort may be raise by read only opener |
219 # Abort may be raise by read only opener |
220 pass |
220 pass |
221 |
221 |
222 def update(self, repo, revgen): |
222 def update(self, repo, revgen): |
223 """Given a branchhead cache, self, that may have extra nodes or be |
223 """Given a branchhead cache, self, that may have extra nodes or be |
224 missing heads, and a generator of nodes that are at least a superset of |
224 missing heads, and a generator of nodes that are strictly a superset of |
225 heads missing, this function updates self to be correct. |
225 heads missing, this function updates self to be correct. |
226 """ |
226 """ |
227 cl = repo.changelog |
227 cl = repo.changelog |
228 # collect new branch entries |
228 # collect new branch entries |
229 newbranches = {} |
229 newbranches = {} |
237 # really branchheads. Note checking parents is insufficient: |
237 # really branchheads. Note checking parents is insufficient: |
238 # 1 (branch a) -> 2 (branch b) -> 3 (branch a) |
238 # 1 (branch a) -> 2 (branch b) -> 3 (branch a) |
239 for branch, newheadrevs in newbranches.iteritems(): |
239 for branch, newheadrevs in newbranches.iteritems(): |
240 bheads = self.setdefault(branch, []) |
240 bheads = self.setdefault(branch, []) |
241 bheadrevs = [cl.rev(node) for node in bheads] |
241 bheadrevs = [cl.rev(node) for node in bheads] |
242 ctxisnew = bheadrevs and min(newheadrevs) > max(bheadrevs) |
242 |
243 # Remove duplicates - nodes that are in newheadrevs and are already |
243 # This have been tested True on all internal usage of this function. |
244 # in bheadrevs. This can happen if you strip a node whose parent |
244 # run it again in case of doubt |
245 # was already a head (because they're on different branches). |
245 # assert not (set(bheadrevs) & set(newheadrevs)) |
246 bheadrevs = sorted(set(bheadrevs).union(newheadrevs)) |
246 newheadrevs.sort() |
247 |
247 bheadrevs.extend(newheadrevs) |
248 # Starting from tip means fewer passes over reachable. If we know |
248 bheadrevs.sort() |
249 # the new candidates are not ancestors of existing heads, we don't |
|
250 # have to examine ancestors of existing heads |
|
251 if ctxisnew: |
|
252 iterrevs = sorted(newheadrevs) |
|
253 else: |
|
254 iterrevs = list(bheadrevs) |
|
255 |
249 |
256 # This loop prunes out two kinds of heads - heads that are |
250 # This loop prunes out two kinds of heads - heads that are |
257 # superseded by a head in newheadrevs, and newheadrevs that are not |
251 # superseded by a head in newheadrevs, and newheadrevs that are not |
258 # heads because an existing head is their descendant. |
252 # heads because an existing head is their descendant. |
259 while iterrevs: |
253 while newheadrevs: |
260 latest = iterrevs.pop() |
254 latest = newheadrevs.pop() |
261 if latest not in bheadrevs: |
255 if latest not in bheadrevs: |
262 continue |
256 continue |
263 ancestors = set(cl.ancestors([latest], bheadrevs[0])) |
257 ancestors = set(cl.ancestors([latest], bheadrevs[0])) |
264 if ancestors: |
258 if ancestors: |
265 bheadrevs = [b for b in bheadrevs if b not in ancestors] |
259 bheadrevs = [b for b in bheadrevs if b not in ancestors] |
266 self[branch] = [cl.node(rev) for rev in bheadrevs] |
260 self[branch] = [cl.node(rev) for rev in bheadrevs] |
267 tiprev = max(bheadrevs) |
261 tiprev = bheadrevs[-1] |
268 if tiprev > self.tiprev: |
262 if tiprev > self.tiprev: |
269 self.tipnode = cl.node(tiprev) |
263 self.tipnode = cl.node(tiprev) |
270 self.tiprev = tiprev |
264 self.tiprev = tiprev |
271 |
265 |
272 if not self.validfor(repo): |
266 if not self.validfor(repo): |