hgext3rd/evolve/obsdiscovery.py
changeset 2061 302aa8bbb3af
parent 2054 f9d65d24b9f9
child 2075 a7c0685ba6d9
equal deleted inserted replaced
2060:cbdb68189432 2061:302aa8bbb3af
    12     StringIO = io.StringIO
    12     StringIO = io.StringIO
    13 except ImportError:
    13 except ImportError:
    14     import io
    14     import io
    15     StringIO = io.StringIO
    15     StringIO = io.StringIO
    16 
    16 
       
    17 import hashlib
       
    18 
    17 from mercurial import (
    19 from mercurial import (
    18     error,
    20     error,
    19     exchange,
    21     exchange,
       
    22     extensions,
    20     localrepo,
    23     localrepo,
    21     node,
    24     node,
    22     obsolete,
    25     obsolete,
    23     wireproto,
    26     wireproto,
    24 )
    27 )
       
    28 from mercurial.hgweb import hgweb_mod
    25 from mercurial.i18n import _
    29 from mercurial.i18n import _
    26 
    30 
    27 from . import (
    31 from . import (
    28     exthelper,
    32     exthelper,
    29     serveronly,
       
    30     utility,
    33     utility,
    31 )
    34 )
    32 
    35 
    33 eh = exthelper.exthelper()
    36 eh = exthelper.exthelper()
    34 obsexcmsg = utility.obsexcmsg
    37 obsexcmsg = utility.obsexcmsg
    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)