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__