Mercurial > evolve
comparison hgext3rd/topic/discovery.py @ 5683:1dece375d2ab
topic: extract awful `ctx.branch` hijacking used in discovery
We will need it for `hg summary`, so we start by making it its own context
manager.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 23 Dec 2020 13:36:02 +0100 |
parents | 36ccafa69095 |
children | 4de216446c53 |
comparison
equal
deleted
inserted
replaced
5682:f0d46ffbf1bb | 5683:1dece375d2ab |
---|---|
1 from __future__ import absolute_import | 1 from __future__ import absolute_import |
2 | 2 |
3 import collections | 3 import collections |
4 import contextlib | |
4 import weakref | 5 import weakref |
5 | 6 |
6 from mercurial.i18n import _ | 7 from mercurial.i18n import _ |
7 from mercurial import ( | 8 from mercurial import ( |
8 bundle2, | 9 bundle2, |
17 common, | 18 common, |
18 compat, | 19 compat, |
19 ) | 20 ) |
20 | 21 |
21 from mercurial import wireprotov1server | 22 from mercurial import wireprotov1server |
23 | |
24 @contextlib.contextmanager | |
25 def override_context_branch(repo, publishedset=()): | |
26 unfi = repo.unfiltered() | |
27 | |
28 class repocls(unfi.__class__): | |
29 # awful hack to see branch as "branch:topic" | |
30 def __getitem__(self, key): | |
31 ctx = super(repocls, self).__getitem__(key) | |
32 oldbranch = ctx.branch | |
33 rev = ctx.rev() | |
34 | |
35 def branch(): | |
36 branch = oldbranch() | |
37 if rev in publishedset: | |
38 return branch | |
39 topic = ctx.topic() | |
40 if topic: | |
41 branch = b"%s:%s" % (branch, topic) | |
42 return branch | |
43 | |
44 ctx.branch = branch | |
45 return ctx | |
46 | |
47 def revbranchcache(self): | |
48 rbc = super(repocls, self).revbranchcache() | |
49 localchangelog = self.changelog | |
50 | |
51 def branchinfo(rev, changelog=None): | |
52 if changelog is None: | |
53 changelog = localchangelog | |
54 branch, close = changelog.branchinfo(rev) | |
55 if rev in publishedset: | |
56 return branch, close | |
57 topic = unfi[rev].topic() | |
58 if topic: | |
59 branch = b"%s:%s" % (branch, topic) | |
60 return branch, close | |
61 | |
62 rbc.branchinfo = branchinfo | |
63 return rbc | |
64 | |
65 oldrepocls = unfi.__class__ | |
66 try: | |
67 unfi.__class__ = repocls | |
68 if repo.filtername is not None: | |
69 repo = unfi.filtered(repo.filtername) | |
70 else: | |
71 repo = unfi | |
72 yield repo | |
73 finally: | |
74 unfi.__class__ = oldrepocls | |
75 | |
22 | 76 |
23 def _headssummary(orig, pushop, *args, **kwargs): | 77 def _headssummary(orig, pushop, *args, **kwargs): |
24 repo = pushop.repo.unfiltered() | 78 repo = pushop.repo.unfiltered() |
25 remote = pushop.remote | 79 remote = pushop.remote |
26 | 80 |
59 result[branch].append(h) | 113 result[branch].append(h) |
60 for heads in result.values(): | 114 for heads in result.values(): |
61 heads.sort() | 115 heads.sort() |
62 return result | 116 return result |
63 | 117 |
64 class repocls(repo.__class__): | 118 with override_context_branch(repo, publishedset=publishedset): |
65 # awful hack to see branch as "branch:topic" | 119 try: |
66 def __getitem__(self, key): | 120 if remotebranchmap is not None: |
67 ctx = super(repocls, self).__getitem__(key) | 121 remote.branchmap = remotebranchmap |
68 oldbranch = ctx.branch | 122 unxx = repo.filtered(b'unfiltered-topic') |
69 rev = ctx.rev() | 123 repo.unfiltered = lambda: unxx |
70 | 124 pushop.repo = repo |
71 def branch(): | 125 summary = orig(pushop) |
72 branch = oldbranch() | 126 for key, value in summary.items(): |
73 if rev in publishedset: | 127 if b':' in key: # This is a topic |
74 return branch | 128 if value[0] is None and value[1]: |
75 topic = ctx.topic() | 129 summary[key] = ([value[1][0]], ) + value[1:] |
76 if topic: | 130 return summary |
77 branch = b"%s:%s" % (branch, topic) | 131 finally: |
78 return branch | 132 if r'unfiltered' in vars(repo): |
79 | 133 del repo.unfiltered |
80 ctx.branch = branch | 134 if remotebranchmap is not None: |
81 return ctx | 135 remote.branchmap = origremotebranchmap |
82 | |
83 def revbranchcache(self): | |
84 rbc = super(repocls, self).revbranchcache() | |
85 localchangelog = self.changelog | |
86 | |
87 def branchinfo(rev, changelog=None): | |
88 if changelog is None: | |
89 changelog = localchangelog | |
90 branch, close = changelog.branchinfo(rev) | |
91 if rev in publishedset: | |
92 return branch, close | |
93 topic = repo[rev].topic() | |
94 if topic: | |
95 branch = b"%s:%s" % (branch, topic) | |
96 return branch, close | |
97 | |
98 rbc.branchinfo = branchinfo | |
99 return rbc | |
100 | |
101 oldrepocls = repo.__class__ | |
102 try: | |
103 repo.__class__ = repocls | |
104 if remotebranchmap is not None: | |
105 remote.branchmap = remotebranchmap | |
106 unxx = repo.filtered(b'unfiltered-topic') | |
107 repo.unfiltered = lambda: unxx | |
108 pushop.repo = repo | |
109 summary = orig(pushop) | |
110 for key, value in summary.items(): | |
111 if b':' in key: # This is a topic | |
112 if value[0] is None and value[1]: | |
113 summary[key] = ([value[1][0]], ) + value[1:] | |
114 return summary | |
115 finally: | |
116 if r'unfiltered' in vars(repo): | |
117 del repo.unfiltered | |
118 repo.__class__ = oldrepocls | |
119 if remotebranchmap is not None: | |
120 remote.branchmap = origremotebranchmap | |
121 | 136 |
122 def wireprotobranchmap(orig, repo, proto): | 137 def wireprotobranchmap(orig, repo, proto): |
123 if not common.hastopicext(repo): | 138 if not common.hastopicext(repo): |
124 return orig(repo, proto) | 139 return orig(repo, proto) |
125 oldrepo = repo.__class__ | 140 oldrepo = repo.__class__ |