hgext/evolve.py
changeset 960 0c1142059a82
parent 959 d39a5c8c82ad
child 961 8de88b323fb6
equal deleted inserted replaced
959:d39a5c8c82ad 960:0c1142059a82
    24 
    24 
    25 import sys
    25 import sys
    26 import random
    26 import random
    27 from StringIO import StringIO
    27 from StringIO import StringIO
    28 import struct
    28 import struct
       
    29 import urllib
    29 
    30 
    30 import mercurial
    31 import mercurial
    31 from mercurial import util
    32 from mercurial import util
    32 
    33 
    33 try:
    34 try:
  2274         else:
  2275         else:
  2275             repo.ui.status("OBSEXC: markers already in sync\n")
  2276             repo.ui.status("OBSEXC: markers already in sync\n")
  2276             markers = []
  2277             markers = []
  2277         if not markers:
  2278         if not markers:
  2278             repo.ui.status("OBSEXC: no marker to push\n")
  2279             repo.ui.status("OBSEXC: no marker to push\n")
  2279         elif remote.capable('_evoext_b2x_obsmarkers_0_pushonly'):
  2280         elif remote.capable('_evoext_b2x_obsmarkers_0'):
  2280             obsdata = StringIO()
  2281             obsdata = StringIO()
  2281             _encodemarkersstream(obsdata, markers)
  2282             _encodemarkersstream(obsdata, markers)
  2282             obsdata.seek(0)
  2283             obsdata.seek(0)
  2283             repo.ui.status("OBSEXC: pushing %i markers (%i bytes)\n"
  2284             repo.ui.status("OBSEXC: pushing %i markers (%i bytes)\n"
  2284                            % (len(markers), len(obsdata.getvalue())))
  2285                            % (len(markers), len(obsdata.getvalue())))
  2396         repo.ui.status("OBSEXC: looking for common markers in %i nodes\n"
  2397         repo.ui.status("OBSEXC: looking for common markers in %i nodes\n"
  2397                        % len(revs))
  2398                        % len(revs))
  2398         common = findcommonobsmarkers(repo.ui, repo, remote, revs)
  2399         common = findcommonobsmarkers(repo.ui, repo, remote, revs)
  2399     return {'heads': pullop.pulledsubset, 'common': common}
  2400     return {'heads': pullop.pulledsubset, 'common': common}
  2400 
  2401 
       
  2402 @eh.uisetup
       
  2403 def addgetbundleargs(self):
       
  2404     if gboptsmap is not None:
       
  2405         gboptsmap['evo_obsmarker'] = 'plain'
       
  2406         gboptsmap['evo_obscommon'] = 'plain'
       
  2407         gboptsmap['evo_obsheads'] = 'plain'
       
  2408     else:
       
  2409         gboptslist.append('evo_obsheads')
       
  2410         gboptslist.append('evo_obscommon')
       
  2411         gboptslist.append('evo_obsmarker')
       
  2412 
       
  2413 
       
  2414 
       
  2415 @eh.wrapfunction(exchange, '_getbundleextrapart')
       
  2416 def _getbundleextrapart(orig, bundler, repo, source, **kwargs):
       
  2417     if int(kwargs.pop('evo_obsmarker', False)):
       
  2418         common = kwargs.pop('evo_obscommon')
       
  2419         common = wireproto.decodelist(common)
       
  2420         heads = kwargs.pop('evo_obsheads')
       
  2421         heads = wireproto.decodelist(heads)
       
  2422         obsdata = _getobsmarkersstream(repo, common=common, heads=heads)
       
  2423         if len(obsdata.getvalue()) > 5:
       
  2424             obspart = bundle2.bundlepart('EVOLVE:B2X:OBSMARKERV1', data=obsdata)
       
  2425             bundler.addpart(obspart)
       
  2426     orig(bundler, repo, source)
  2401 
  2427 
  2402 @eh.wrapfunction(exchange, '_pullobsolete')
  2428 @eh.wrapfunction(exchange, '_pullobsolete')
  2403 def _pullobsolete(orig, pullop):
  2429 def _pullobsolete(orig, pullop):
  2404     if not obsolete._enabled:
  2430     if not obsolete._enabled:
  2405         return None
  2431         return None
  2406     if not pullop.remote.capable('_evoext_pullobsmarkers_0'):
  2432     b2xpull = pullop.remote.capable('_evoext_b2x_obsmarkers_0')
       
  2433     wirepull = pullop.remote.capable('_evoext_pullobsmarkers_0')
       
  2434     if not (b2xpull or wirepull):
  2407         return orig(pullop)
  2435         return orig(pullop)
  2408     if 'obsolete' not in pullop.remote.listkeys('namespaces'):
  2436     if 'obsolete' not in pullop.remote.listkeys('namespaces'):
  2409         return None # remote opted out of obsolescence marker exchange
  2437         return None # remote opted out of obsolescence marker exchange
  2410     tr = None
  2438     tr = None
  2411     ui = pullop.repo.ui
  2439     ui = pullop.repo.ui
  2412     ui.status("OBSEXC: pull obsolescence markers\n")
  2440     ui.status("OBSEXC: pull obsolescence markers\n")
  2413     boundaries = _buildpullobsmerkersboundaries(pullop)
  2441     boundaries = _buildpullobsmerkersboundaries(pullop)
  2414     obsdata = pullop.remote.evoext_pullobsmarkers_0(**boundaries)
  2442     new = 0
  2415     obsdata = obsdata.read()
  2443 
  2416     if len(obsdata) > 5:
  2444     if b2xpull:
  2417         ui.status("OBSEXC: merging obsolescence markers (%i bytes)\n"
  2445         kwargs = {'bundlecaps': set(['HG2X'])}
  2418                        % len(obsdata))
  2446         capsblob = bundle2.encodecaps(pullop.repo.bundle2caps)
  2419         tr = pullop.gettransaction()
  2447         kwargs['bundlecaps'].add('bundle2=' + urllib.quote(capsblob))
  2420         old = len(pullop.repo.obsstore._all)
  2448         kwargs['heads'] = [nullid]
  2421         pullop.repo.obsstore.mergemarkers(tr, obsdata)
  2449         kwargs['common'] = [nullid]
  2422         new = len(pullop.repo.obsstore._all) - old
  2450         kwargs['evo_obsmarker'] = '1'
  2423         ui.status("OBSEXC: %i markers added\n" % new)
  2451         kwargs['evo_obscommon'] = wireproto.encodelist(boundaries['common'])
  2424         if new:
  2452         kwargs['evo_obsheads'] = wireproto.encodelist(boundaries['heads'])
  2425             pullop.repo.invalidatevolatilesets()
  2453         bundle = pullop.remote.getbundle('pull', **kwargs)
  2426     else:
  2454         try:
  2427         ui.status("OBSEXC: no unknown remote markers\n")
  2455             op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction)
  2428     ui.status("OBSEXC: DONE\n")
  2456         except bundle2.UnknownPartError, exc:
       
  2457             raise util.Abort('missing support for %s' % exc)
       
  2458         bytes = new = 0
       
  2459         for entry in op.records['evo_obsmarkers']:
       
  2460             bytes += entry.get('bytes', 0)
       
  2461             new += entry.get('new', 0)
       
  2462         if 5 < bytes:
       
  2463             ui.status("OBSEXC: merging obsolescence markers (%i bytes)\n"
       
  2464                       % bytes)
       
  2465             ui.status("OBSEXC: %i markers added\n" % new)
       
  2466             tr = op.gettransaction()
       
  2467         else:
       
  2468             ui.status("OBSEXC: no unknown remote markers\n")
       
  2469         ui.status("OBSEXC: DONE\n")
       
  2470     elif wirepull:
       
  2471         obsdata = pullop.remote.evoext_pullobsmarkers_0(**boundaries)
       
  2472         obsdata = obsdata.read()
       
  2473         if len(obsdata) > 5:
       
  2474             ui.status("OBSEXC: merging obsolescence markers (%i bytes)\n"
       
  2475                            % len(obsdata))
       
  2476             tr = pullop.gettransaction()
       
  2477             old = len(pullop.repo.obsstore._all)
       
  2478             pullop.repo.obsstore.mergemarkers(tr, obsdata)
       
  2479             new = len(pullop.repo.obsstore._all) - old
       
  2480             ui.status("OBSEXC: %i markers added\n" % new)
       
  2481         else:
       
  2482             ui.status("OBSEXC: no unknown remote markers\n")
       
  2483         ui.status("OBSEXC: DONE\n")
       
  2484     if new:
       
  2485         pullop.repo.invalidatevolatilesets()
  2429     return tr
  2486     return tr
  2430 
  2487 
  2431 def _getobsmarkersstream(repo, heads=None, common=None):
  2488 def _getobsmarkersstream(repo, heads=None, common=None):
  2432     revset = ''
  2489     revset = ''
  2433     args = []
  2490     args = []
  2613     caps = orig(repo, proto)
  2670     caps = orig(repo, proto)
  2614     if obsolete._enabled:
  2671     if obsolete._enabled:
  2615         caps += ' _evoext_pushobsmarkers_0'
  2672         caps += ' _evoext_pushobsmarkers_0'
  2616         caps += ' _evoext_pullobsmarkers_0'
  2673         caps += ' _evoext_pullobsmarkers_0'
  2617         caps += ' _evoext_obshash_0'
  2674         caps += ' _evoext_obshash_0'
  2618         caps += ' _evoext_b2x_obsmarkers_0_pushonly'
  2675         caps += ' _evoext_b2x_obsmarkers_0'
  2619     return caps
  2676     return caps
  2620 
  2677 
  2621 
  2678 
  2622 @eh.extsetup
  2679 @eh.extsetup
  2623 def _installwireprotocol(ui):
  2680 def _installwireprotocol(ui):
  2624     localrepo.moderncaps.add('_evoext_pullobsmarkers_0')
  2681     localrepo.moderncaps.add('_evoext_pullobsmarkers_0')
  2625     localrepo.moderncaps.add('_evoext_b2x_obsmarkers_0_pushonly')
  2682     localrepo.moderncaps.add('_evoext_b2x_obsmarkers_0')
  2626     hgweb_mod.perms['evoext_pushobsmarkers_0'] = 'push'
  2683     hgweb_mod.perms['evoext_pushobsmarkers_0'] = 'push'
  2627     hgweb_mod.perms['evoext_pullobsmarkers_0'] = 'pull'
  2684     hgweb_mod.perms['evoext_pullobsmarkers_0'] = 'pull'
  2628     hgweb_mod.perms['evoext_obshash'] = 'pull'
  2685     hgweb_mod.perms['evoext_obshash'] = 'pull'
  2629     wireproto.commands['evoext_pushobsmarkers_0'] = (srv_pushobsmarkers, '')
  2686     wireproto.commands['evoext_pushobsmarkers_0'] = (srv_pushobsmarkers, '')
  2630     wireproto.commands['evoext_pullobsmarkers_0'] = (srv_pullobsmarkers, '*')
  2687     wireproto.commands['evoext_pullobsmarkers_0'] = (srv_pullobsmarkers, '*')