hgext/evolve.py
branchstable
changeset 1244 3249814dabd1
parent 1230 e886bc501796
child 1248 4279ec5ff3a7
child 1249 1556d8fed538
equal deleted inserted replaced
1243:3ffa12edc05a 1244:3249814dabd1
  2338     return caps
  2338     return caps
  2339 
  2339 
  2340 @eh.extsetup
  2340 @eh.extsetup
  2341 def _installobsmarkersdiscovery(ui):
  2341 def _installobsmarkersdiscovery(ui):
  2342     hgweb_mod.perms['evoext_obshash'] = 'pull'
  2342     hgweb_mod.perms['evoext_obshash'] = 'pull'
       
  2343     hgweb_mod.perms['evoext_obshash1'] = 'pull'
  2343     # wrap command content
  2344     # wrap command content
  2344     oldcap, args = wireproto.commands['capabilities']
  2345     oldcap, args = wireproto.commands['capabilities']
  2345     def newcap(repo, proto):
  2346     def newcap(repo, proto):
  2346         return discocapabilities(oldcap, repo, proto)
  2347         return discocapabilities(oldcap, repo, proto)
  2347     wireproto.commands['capabilities'] = (newcap, args)
  2348     wireproto.commands['capabilities'] = (newcap, args)
  2348     wireproto.commands['evoext_obshash'] = (srv_obshash, 'nodes')
  2349     wireproto.commands['evoext_obshash'] = (srv_obshash, 'nodes')
       
  2350     wireproto.commands['evoext_obshash1'] = (srv_obshash1, 'nodes')
  2349     if getattr(exchange, '_pushdiscoveryobsmarkers', None) is None:
  2351     if getattr(exchange, '_pushdiscoveryobsmarkers', None) is None:
  2350         ui.warn('evolve: your mercurial version is too old\n'
  2352         ui.warn('evolve: your mercurial version is too old\n'
  2351                 'evolve: (running in degraded mode, push will includes all markers)\n')
  2353                 'evolve: (running in degraded mode, push will includes all markers)\n')
  2352     else:
  2354     else:
  2353         olddisco = exchange.pushdiscoverymapping['obsmarker']
  2355         olddisco = exchange.pushdiscoverymapping['obsmarker']
  2358 ### Set discovery START
  2360 ### Set discovery START
  2359 
  2361 
  2360 from mercurial import dagutil
  2362 from mercurial import dagutil
  2361 from mercurial import setdiscovery
  2363 from mercurial import setdiscovery
  2362 
  2364 
  2363 def _obshash(repo, nodes):
  2365 def _obshash(repo, nodes, version=0):
  2364     hashs = _obsrelsethashtree(repo)
  2366     if version == 0:
       
  2367         hashs = _obsrelsethashtreefm0(repo)
       
  2368     elif version ==1:
       
  2369         hashs = _obsrelsethashtreefm1(repo)
       
  2370     else:
       
  2371         assert False
  2365     nm = repo.changelog.nodemap
  2372     nm = repo.changelog.nodemap
  2366     revs = [nm.get(n) for n in nodes]
  2373     revs = [nm.get(n) for n in nodes]
  2367     return [r is None and nullid or hashs[r][1] for r in revs]
  2374     return [r is None and nullid or hashs[r][1] for r in revs]
  2368 
  2375 
  2369 def srv_obshash(repo, proto, nodes):
  2376 def srv_obshash(repo, proto, nodes):
  2370     return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes)))
  2377     return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes)))
  2371 
  2378 
       
  2379 def srv_obshash1(repo, proto, nodes):
       
  2380     return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes), version=1))
       
  2381 
  2372 @eh.addattr(localrepo.localpeer, 'evoext_obshash')
  2382 @eh.addattr(localrepo.localpeer, 'evoext_obshash')
  2373 def local_obshash(peer, nodes):
  2383 def local_obshash(peer, nodes):
  2374     return _obshash(peer._repo, nodes)
  2384     return _obshash(peer._repo, nodes)
       
  2385 
       
  2386 @eh.addattr(localrepo.localpeer, 'evoext_obshash1')
       
  2387 def local_obshash1(peer, nodes):
       
  2388     return _obshash(peer._repo, nodes, version=1)
  2375 
  2389 
  2376 @eh.addattr(wireproto.wirepeer, 'evoext_obshash')
  2390 @eh.addattr(wireproto.wirepeer, 'evoext_obshash')
  2377 def peer_obshash(self, nodes):
  2391 def peer_obshash(self, nodes):
  2378     d = self._call("evoext_obshash", nodes=wireproto.encodelist(nodes))
  2392     d = self._call("evoext_obshash", nodes=wireproto.encodelist(nodes))
  2379     try:
  2393     try:
  2380         return wireproto.decodelist(d)
  2394         return wireproto.decodelist(d)
  2381     except ValueError:
  2395     except ValueError:
  2382         self._abort(error.ResponseError(_("unexpected response:"), d))
  2396         self._abort(error.ResponseError(_("unexpected response:"), d))
  2383 
  2397 
       
  2398 @eh.addattr(wireproto.wirepeer, 'evoext_obshash1')
       
  2399 def peer_obshash1(self, nodes):
       
  2400     d = self._call("evoext_obshash1", nodes=wireproto.encodelist(nodes))
       
  2401     try:
       
  2402         return wireproto.decodelist(d)
       
  2403     except ValueError:
       
  2404         self._abort(error.ResponseError(_("unexpected response:"), d))
       
  2405 
  2384 def findcommonobsmarkers(ui, local, remote, probeset,
  2406 def findcommonobsmarkers(ui, local, remote, probeset,
  2385                          initialsamplesize=100,
  2407                          initialsamplesize=100,
  2386                          fullsamplesize=200):
  2408                          fullsamplesize=200):
  2387     # from discovery
  2409     # from discovery
  2388     roundtrips = 0
  2410     roundtrips = 0
  2389     cl = local.changelog
  2411     cl = local.changelog
  2390     dag = dagutil.revlogdag(cl)
  2412     dag = dagutil.revlogdag(cl)
  2391     localhash = _obsrelsethashtree(local)
       
  2392     missing = set()
  2413     missing = set()
  2393     common = set()
  2414     common = set()
  2394     undecided = set(probeset)
  2415     undecided = set(probeset)
  2395     _takefullsample = setdiscovery._takefullsample
  2416     _takefullsample = setdiscovery._takefullsample
       
  2417     if remote.capable('_evoext_obshash_1'):
       
  2418         remotehash = remote.evoext_obshash1
       
  2419         localhash = _obsrelsethashtreefm1(local)
       
  2420     else:
       
  2421         remotehash = remote.evoext_obshash
       
  2422         localhash = _obsrelsethashtreefm0(local)
  2396 
  2423 
  2397     while undecided:
  2424     while undecided:
  2398 
  2425 
  2399         ui.note(_("sampling from both directions\n"))
  2426         ui.note(_("sampling from both directions\n"))
  2400         if len(undecided) < fullsamplesize:
  2427         if len(undecided) < fullsamplesize:
  2405         roundtrips += 1
  2432         roundtrips += 1
  2406         ui.debug("query %i; still undecided: %i, sample size is: %i\n"
  2433         ui.debug("query %i; still undecided: %i, sample size is: %i\n"
  2407                  % (roundtrips, len(undecided), len(sample)))
  2434                  % (roundtrips, len(undecided), len(sample)))
  2408         # indices between sample and externalized version must match
  2435         # indices between sample and externalized version must match
  2409         sample = list(sample)
  2436         sample = list(sample)
  2410         remotehash = remote.evoext_obshash(dag.externalizeall(sample))
  2437         remotehash = remotehash(dag.externalizeall(sample))
  2411 
  2438 
  2412         yesno = [localhash[ix][1] == remotehash[si]
  2439         yesno = [localhash[ix][1] == remotehash[si]
  2413                  for si, ix in enumerate(sample)]
  2440                  for si, ix in enumerate(sample)]
  2414 
  2441 
  2415         commoninsample = set(n for i, n in enumerate(sample) if yesno[i])
  2442         commoninsample = set(n for i, n in enumerate(sample) if yesno[i])
  2736     finaldata.write('%20i' % len(obsdata))
  2763     finaldata.write('%20i' % len(obsdata))
  2737     finaldata.write(obsdata)
  2764     finaldata.write(obsdata)
  2738     finaldata.seek(0)
  2765     finaldata.seek(0)
  2739     return wireproto.streamres(proto.groupchunks(finaldata))
  2766     return wireproto.streamres(proto.groupchunks(finaldata))
  2740 
  2767 
  2741 def _obsrelsethashtree(repo):
  2768 def _obsrelsethashtreefm0(repo):
       
  2769     return _obsrelsethashtree(repo, obsolete._fm0encodeonemarker)
       
  2770 
       
  2771 def _obsrelsethashtreefm1(repo):
       
  2772     return _obsrelsethashtree(repo, obsolete._fm1encodeonemarker)
       
  2773 
       
  2774 def _obsrelsethashtree(repo, encodeonemarker):
  2742     cache = []
  2775     cache = []
  2743     unfi = repo.unfiltered()
  2776     unfi = repo.unfiltered()
  2744     markercache = {}
  2777     markercache = {}
  2745     for i in unfi:
  2778     for i in unfi:
  2746         ctx = unfi[i]
  2779         ctx = unfi[i]
  2759         tmarkers = repo.obsstore.relevantmarkers([ctx.node()])
  2792         tmarkers = repo.obsstore.relevantmarkers([ctx.node()])
  2760         if tmarkers:
  2793         if tmarkers:
  2761             bmarkers = []
  2794             bmarkers = []
  2762             for m in tmarkers:
  2795             for m in tmarkers:
  2763                 if not m in markercache:
  2796                 if not m in markercache:
  2764                     markercache[m] = obsolete._fm0encodeonemarker(m)
  2797                     markercache[m] = encodeonemarker(m)
  2765                 bmarkers.append(markercache[m])
  2798                 bmarkers.append(markercache[m])
  2766             bmarkers.sort()
  2799             bmarkers.sort()
  2767             for m in bmarkers:
  2800             for m in bmarkers:
  2768                 entry += 1
  2801                 entry += 1
  2769                 sha.update(m)
  2802                 sha.update(m)
  2772         else:
  2805         else:
  2773             cache.append((ctx.node(), nullid))
  2806             cache.append((ctx.node(), nullid))
  2774     return cache
  2807     return cache
  2775 
  2808 
  2776 @command('debugobsrelsethashtree',
  2809 @command('debugobsrelsethashtree',
  2777         [] , _(''))
  2810         [('', 'v0', None, 'hash on marker format "0"'),
  2778 def debugobsrelsethashtree(ui, repo):
  2811          ('', 'v1', None, 'hash on marker format "1" (default)')
       
  2812          ,] , _(''))
       
  2813 def debugobsrelsethashtree(ui, repo, v0=False, v1=False):
  2779     """display Obsolete markers, Relevant Set, Hash Tree
  2814     """display Obsolete markers, Relevant Set, Hash Tree
  2780     changeset-node obsrelsethashtree-node
  2815     changeset-node obsrelsethashtree-node
  2781 
  2816 
  2782     It computed form the "orsht" of its parent and markers
  2817     It computed form the "orsht" of its parent and markers
  2783     relevant to the changeset itself."""
  2818     relevant to the changeset itself."""
  2784     for chg, obs in _obsrelsethashtree(repo):
  2819     if v0 and v1:
       
  2820         raise util.Abort('cannot only specify one format')
       
  2821     elif v0:
       
  2822         treefunc = _obsrelsethashtreefm0
       
  2823     else:
       
  2824         treefunc = _obsrelsethashtreefm1
       
  2825 
       
  2826     treefunc = _obsrelsethashtree
       
  2827     for chg, obs in treefunc(repo):
  2785         ui.status('%s %s\n' % (node.hex(chg), node.hex(obs)))
  2828         ui.status('%s %s\n' % (node.hex(chg), node.hex(obs)))
  2786 
  2829 
  2787 _bestformat = max(obsolete.formats.keys())
  2830 _bestformat = max(obsolete.formats.keys())
  2788 
  2831 
  2789 
  2832 
  2838     caps = orig(repo, proto)
  2881     caps = orig(repo, proto)
  2839     if obsolete._enabled:
  2882     if obsolete._enabled:
  2840         caps += ' _evoext_pushobsmarkers_0'
  2883         caps += ' _evoext_pushobsmarkers_0'
  2841         caps += ' _evoext_pullobsmarkers_0'
  2884         caps += ' _evoext_pullobsmarkers_0'
  2842         caps += ' _evoext_obshash_0'
  2885         caps += ' _evoext_obshash_0'
       
  2886         caps += ' _evoext_obshash_1'
  2843         caps += ' _evoext_getbundle_obscommon'
  2887         caps += ' _evoext_getbundle_obscommon'
  2844     return caps
  2888     return caps
  2845 
  2889 
  2846 
  2890 
  2847 @eh.extsetup
  2891 @eh.extsetup