37 from mercurial import dagutil |
40 from mercurial import dagutil |
38 from mercurial import setdiscovery |
41 from mercurial import setdiscovery |
39 |
42 |
40 @eh.addattr(localrepo.localpeer, 'evoext_obshash') |
43 @eh.addattr(localrepo.localpeer, 'evoext_obshash') |
41 def local_obshash(peer, nodes): |
44 def local_obshash(peer, nodes): |
42 return serveronly._obshash(peer._repo, nodes) |
45 return _obshash(peer._repo, nodes) |
43 |
46 |
44 @eh.addattr(localrepo.localpeer, 'evoext_obshash1') |
47 @eh.addattr(localrepo.localpeer, 'evoext_obshash1') |
45 def local_obshash1(peer, nodes): |
48 def local_obshash1(peer, nodes): |
46 return serveronly._obshash(peer._repo, nodes, version=1) |
49 return _obshash(peer._repo, nodes, version=1) |
47 |
50 |
48 @eh.addattr(wireproto.wirepeer, 'evoext_obshash') |
51 @eh.addattr(wireproto.wirepeer, 'evoext_obshash') |
49 def peer_obshash(self, nodes): |
52 def peer_obshash(self, nodes): |
50 d = self._call("evoext_obshash", nodes=wireproto.encodelist(nodes)) |
53 d = self._call("evoext_obshash", nodes=wireproto.encodelist(nodes)) |
51 try: |
54 try: |
74 totalnb = len(undecided) |
77 totalnb = len(undecided) |
75 ui.progress(_("comparing with other"), 0, total=totalnb) |
78 ui.progress(_("comparing with other"), 0, total=totalnb) |
76 _takefullsample = setdiscovery._takefullsample |
79 _takefullsample = setdiscovery._takefullsample |
77 if remote.capable('_evoext_obshash_1'): |
80 if remote.capable('_evoext_obshash_1'): |
78 getremotehash = remote.evoext_obshash1 |
81 getremotehash = remote.evoext_obshash1 |
79 localhash = serveronly._obsrelsethashtreefm1(local) |
82 localhash = _obsrelsethashtreefm1(local) |
80 else: |
83 else: |
81 getremotehash = remote.evoext_obshash |
84 getremotehash = remote.evoext_obshash |
82 localhash = serveronly._obsrelsethashtreefm0(local) |
85 localhash = _obsrelsethashtreefm0(local) |
83 |
86 |
84 while undecided: |
87 while undecided: |
85 |
88 |
86 ui.note(_("sampling from both directions\n")) |
89 ui.note(_("sampling from both directions\n")) |
87 if len(undecided) < fullsamplesize: |
90 if len(undecided) < fullsamplesize: |
194 It computed form the "orsht" of its parent and markers |
197 It computed form the "orsht" of its parent and markers |
195 relevant to the changeset itself.""" |
198 relevant to the changeset itself.""" |
196 if v0 and v1: |
199 if v0 and v1: |
197 raise error.Abort('cannot only specify one format') |
200 raise error.Abort('cannot only specify one format') |
198 elif v0: |
201 elif v0: |
199 treefunc = serveronly._obsrelsethashtreefm0 |
202 treefunc = _obsrelsethashtreefm0 |
200 else: |
203 else: |
201 treefunc = serveronly._obsrelsethashtreefm1 |
204 treefunc = _obsrelsethashtreefm1 |
202 |
205 |
203 for chg, obs in treefunc(repo): |
206 for chg, obs in treefunc(repo): |
204 ui.status('%s %s\n' % (node.hex(chg), node.hex(obs))) |
207 ui.status('%s %s\n' % (node.hex(chg), node.hex(obs))) |
|
208 |
|
209 def _obsrelsethashtreefm0(repo): |
|
210 return _obsrelsethashtree(repo, obsolete._fm0encodeonemarker) |
|
211 |
|
212 def _obsrelsethashtreefm1(repo): |
|
213 return _obsrelsethashtree(repo, obsolete._fm1encodeonemarker) |
|
214 |
|
215 def _obsrelsethashtree(repo, encodeonemarker): |
|
216 cache = [] |
|
217 unfi = repo.unfiltered() |
|
218 markercache = {} |
|
219 repo.ui.progress(_("preparing locally"), 0, total=len(unfi)) |
|
220 for i in unfi: |
|
221 ctx = unfi[i] |
|
222 entry = 0 |
|
223 sha = hashlib.sha1() |
|
224 # add data from p1 |
|
225 for p in ctx.parents(): |
|
226 p = p.rev() |
|
227 if p < 0: |
|
228 p = node.nullid |
|
229 else: |
|
230 p = cache[p][1] |
|
231 if p != node.nullid: |
|
232 entry += 1 |
|
233 sha.update(p) |
|
234 tmarkers = repo.obsstore.relevantmarkers([ctx.node()]) |
|
235 if tmarkers: |
|
236 bmarkers = [] |
|
237 for m in tmarkers: |
|
238 if m not in markercache: |
|
239 markercache[m] = encodeonemarker(m) |
|
240 bmarkers.append(markercache[m]) |
|
241 bmarkers.sort() |
|
242 for m in bmarkers: |
|
243 entry += 1 |
|
244 sha.update(m) |
|
245 if entry: |
|
246 cache.append((ctx.node(), sha.digest())) |
|
247 else: |
|
248 cache.append((ctx.node(), node.nullid)) |
|
249 repo.ui.progress(_("preparing locally"), i, total=len(unfi)) |
|
250 repo.ui.progress(_("preparing locally"), None) |
|
251 return cache |
|
252 |
|
253 def _obshash(repo, nodes, version=0): |
|
254 if version == 0: |
|
255 hashs = _obsrelsethashtreefm0(repo) |
|
256 elif version == 1: |
|
257 hashs = _obsrelsethashtreefm1(repo) |
|
258 else: |
|
259 assert False |
|
260 nm = repo.changelog.nodemap |
|
261 revs = [nm.get(n) for n in nodes] |
|
262 return [r is None and node.nullid or hashs[r][1] for r in revs] |
|
263 |
|
264 def srv_obshash(repo, proto, nodes): |
|
265 return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes))) |
|
266 |
|
267 def srv_obshash1(repo, proto, nodes): |
|
268 return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes), |
|
269 version=1)) |
|
270 |
|
271 def _obshash_capabilities(orig, repo, proto): |
|
272 """wrapper to advertise new capability""" |
|
273 caps = orig(repo, proto) |
|
274 advertise = repo.ui.configbool('__temporary__', 'advertiseobsolete', True) |
|
275 if obsolete.isenabled(repo, obsolete.exchangeopt) and advertise: |
|
276 caps = caps.split() |
|
277 caps.append('_evoext_obshash_0') |
|
278 caps.append('_evoext_obshash_1') |
|
279 caps.sort() |
|
280 caps = ' '.join(caps) |
|
281 return caps |
|
282 |
|
283 @eh.extsetup |
|
284 def obshash_extsetup(ui): |
|
285 hgweb_mod.perms['evoext_obshash'] = 'pull' |
|
286 hgweb_mod.perms['evoext_obshash1'] = 'pull' |
|
287 |
|
288 wireproto.commands['evoext_obshash'] = (srv_obshash, 'nodes') |
|
289 wireproto.commands['evoext_obshash1'] = (srv_obshash1, 'nodes') |
|
290 extensions.wrapfunction(wireproto, 'capabilities', _obshash_capabilities) |
|
291 # wrap command content |
|
292 oldcap, args = wireproto.commands['capabilities'] |
|
293 |
|
294 def newcap(repo, proto): |
|
295 return _obshash_capabilities(oldcap, repo, proto) |
|
296 wireproto.commands['capabilities'] = (newcap, args) |