45 def update(repo, partial, ctxgen): |
45 def update(repo, partial, ctxgen): |
46 """Given a branchhead cache, partial, that may have extra nodes or be |
46 """Given a branchhead cache, partial, that may have extra nodes or be |
47 missing heads, and a generator of nodes that are at least a superset of |
47 missing heads, and a generator of nodes that are at least a superset of |
48 heads missing, this function updates partial to be correct. |
48 heads missing, this function updates partial to be correct. |
49 """ |
49 """ |
|
50 cl = repo.changelog |
50 # collect new branch entries |
51 # collect new branch entries |
51 newbranches = {} |
52 newbranches = {} |
52 for c in ctxgen: |
53 for c in ctxgen: |
53 newbranches.setdefault(c.branch(), []).append(c.node()) |
54 newbranches.setdefault(c.branch(), []).append(c.node()) |
54 # if older branchheads are reachable from new ones, they aren't |
55 # if older branchheads are reachable from new ones, they aren't |
58 bheads = partial.setdefault(branch, []) |
59 bheads = partial.setdefault(branch, []) |
59 # Remove candidate heads that no longer are in the repo (e.g., as |
60 # Remove candidate heads that no longer are in the repo (e.g., as |
60 # the result of a strip that just happened). Avoid using 'node in |
61 # the result of a strip that just happened). Avoid using 'node in |
61 # self' here because that dives down into branchcache code somewhat |
62 # self' here because that dives down into branchcache code somewhat |
62 # recursively. |
63 # recursively. |
63 bheadrevs = [repo.changelog.rev(node) for node in bheads |
64 bheadrevs = [cl.rev(node) for node in bheads |
64 if repo.changelog.hasnode(node)] |
65 if cl.hasnode(node)] |
65 newheadrevs = [repo.changelog.rev(node) for node in newnodes |
66 newheadrevs = [cl.rev(node) for node in newnodes |
66 if repo.changelog.hasnode(node)] |
67 if cl.hasnode(node)] |
67 ctxisnew = bheadrevs and min(newheadrevs) > max(bheadrevs) |
68 ctxisnew = bheadrevs and min(newheadrevs) > max(bheadrevs) |
68 # Remove duplicates - nodes that are in newheadrevs and are already |
69 # Remove duplicates - nodes that are in newheadrevs and are already |
69 # in bheadrevs. This can happen if you strip a node whose parent |
70 # in bheadrevs. This can happen if you strip a node whose parent |
70 # was already a head (because they're on different branches). |
71 # was already a head (because they're on different branches). |
71 bheadrevs = sorted(set(bheadrevs).union(newheadrevs)) |
72 bheadrevs = sorted(set(bheadrevs).union(newheadrevs)) |
83 # heads because an existing head is their descendant. |
84 # heads because an existing head is their descendant. |
84 while iterrevs: |
85 while iterrevs: |
85 latest = iterrevs.pop() |
86 latest = iterrevs.pop() |
86 if latest not in bheadrevs: |
87 if latest not in bheadrevs: |
87 continue |
88 continue |
88 ancestors = set(repo.changelog.ancestors([latest], |
89 ancestors = set(cl.ancestors([latest], |
89 bheadrevs[0])) |
90 bheadrevs[0])) |
90 if ancestors: |
91 if ancestors: |
91 bheadrevs = [b for b in bheadrevs if b not in ancestors] |
92 bheadrevs = [b for b in bheadrevs if b not in ancestors] |
92 partial[branch] = [repo.changelog.node(rev) for rev in bheadrevs] |
93 partial[branch] = [cl.node(rev) for rev in bheadrevs] |
93 |
94 |
94 # There may be branches that cease to exist when the last commit in the |
95 # There may be branches that cease to exist when the last commit in the |
95 # branch was stripped. This code filters them out. Note that the |
96 # branch was stripped. This code filters them out. Note that the |
96 # branch that ceased to exist may not be in newbranches because |
97 # branch that ceased to exist may not be in newbranches because |
97 # newbranches is the set of candidate heads, which when you strip the |
98 # newbranches is the set of candidate heads, which when you strip the |
98 # last commit in a branch will be the parent branch. |
99 # last commit in a branch will be the parent branch. |
99 for branch in partial.keys(): |
100 for branch in partial.keys(): |
100 nodes = [head for head in partial[branch] |
101 nodes = [head for head in partial[branch] |
101 if repo.changelog.hasnode(head)] |
102 if cl.hasnode(head)] |
102 if not nodes: |
103 if not nodes: |
103 del partial[branch] |
104 del partial[branch] |
104 |
105 |
105 def updatecache(repo): |
106 def updatecache(repo): |
106 repo = repo.unfiltered() # Until we get a smarter cache management |
107 repo = repo.unfiltered() # Until we get a smarter cache management |