comparison mercurial/branchmap.py @ 20263:ea4996754d91

branchmap: simplify update code We drop iterrevs which are not needed anymore. The know head are never a descendant of the updated set. It was possible with the old strip code. This simplification make the code easier to read an update.
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Mon, 06 Jan 2014 14:26:49 -0800
parents cf450ee3f8f7
children d9e1c167943b
comparison
equal deleted inserted replaced
20262:cf450ee3f8f7 20263:ea4996754d91
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):