mercurial/exchange.py
changeset 22542 6b180a0c703e
parent 22541 4e1a80c022a4
child 22543 6a669d5a62b8
equal deleted inserted replaced
22541:4e1a80c022a4 22542:6b180a0c703e
   959     caps = set(['HG2X'])
   959     caps = set(['HG2X'])
   960     capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
   960     capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
   961     caps.add('bundle2=' + urllib.quote(capsblob))
   961     caps.add('bundle2=' + urllib.quote(capsblob))
   962     return caps
   962     return caps
   963 
   963 
       
   964 # List of names of steps to perform for a bundle2 for getbundle, order matters.
       
   965 getbundle2partsorder = []
       
   966 
       
   967 # Mapping between step name and function
       
   968 #
       
   969 # This exists to help extensions wrap steps if necessary
       
   970 getbundle2partsmapping = {}
       
   971 
       
   972 def getbundle2partsgenerator(stepname):
       
   973     """decorator for function generating bundle2 part for getbundle
       
   974 
       
   975     The function is added to the step -> function mapping and appended to the
       
   976     list of steps.  Beware that decorated functions will be added in order
       
   977     (this may matter).
       
   978 
       
   979     You can only use this decorator for new steps, if you want to wrap a step
       
   980     from an extension, attack the getbundle2partsmapping dictionary directly."""
       
   981     def dec(func):
       
   982         assert stepname not in getbundle2partsmapping
       
   983         getbundle2partsmapping[stepname] = func
       
   984         getbundle2partsorder.append(stepname)
       
   985         return func
       
   986     return dec
       
   987 
   964 def getbundle(repo, source, heads=None, common=None, bundlecaps=None,
   988 def getbundle(repo, source, heads=None, common=None, bundlecaps=None,
   965               **kwargs):
   989               **kwargs):
   966     """return a full bundle (with potentially multiple kind of parts)
   990     """return a full bundle (with potentially multiple kind of parts)
   967 
   991 
   968     Could be a bundle HG10 or a bundle HG2X depending on bundlecaps
   992     Could be a bundle HG10 or a bundle HG2X depending on bundlecaps
   974     have a clearer idea of the API we what to query different data.
   998     have a clearer idea of the API we what to query different data.
   975 
   999 
   976     The implementation is at a very early stage and will get massive rework
  1000     The implementation is at a very early stage and will get massive rework
   977     when the API of bundle is refined.
  1001     when the API of bundle is refined.
   978     """
  1002     """
   979     cg = None
  1003     # bundle10 case
   980     if kwargs.get('cg', True):
       
   981         # build changegroup bundle here.
       
   982         cg = changegroup.getchangegroup(repo, source, heads=heads,
       
   983                                          common=common, bundlecaps=bundlecaps)
       
   984     elif 'HG2X' not in bundlecaps:
       
   985         raise ValueError(_('request for bundle10 must include changegroup'))
       
   986     if bundlecaps is None or 'HG2X' not in bundlecaps:
  1004     if bundlecaps is None or 'HG2X' not in bundlecaps:
       
  1005         if bundlecaps and not kwargs.get('cg', True):
       
  1006             raise ValueError(_('request for bundle10 must include changegroup'))
       
  1007 
   987         if kwargs:
  1008         if kwargs:
   988             raise ValueError(_('unsupported getbundle arguments: %s')
  1009             raise ValueError(_('unsupported getbundle arguments: %s')
   989                              % ', '.join(sorted(kwargs.keys())))
  1010                              % ', '.join(sorted(kwargs.keys())))
   990         return cg
  1011         return changegroup.getchangegroup(repo, source, heads=heads,
   991     # very crude first implementation,
  1012                                           common=common, bundlecaps=bundlecaps)
   992     # the bundle API will change and the generation will be done lazily.
  1013 
       
  1014     # bundle20 case
   993     b2caps = {}
  1015     b2caps = {}
   994     for bcaps in bundlecaps:
  1016     for bcaps in bundlecaps:
   995         if bcaps.startswith('bundle2='):
  1017         if bcaps.startswith('bundle2='):
   996             blob = urllib.unquote(bcaps[len('bundle2='):])
  1018             blob = urllib.unquote(bcaps[len('bundle2='):])
   997             b2caps.update(bundle2.decodecaps(blob))
  1019             b2caps.update(bundle2.decodecaps(blob))
   998     bundler = bundle2.bundle20(repo.ui, b2caps)
  1020     bundler = bundle2.bundle20(repo.ui, b2caps)
       
  1021 
       
  1022     for name in getbundle2partsorder:
       
  1023         func = getbundle2partsmapping[name]
       
  1024         func(bundler, repo, source, heads=heads, common=common,
       
  1025              bundlecaps=bundlecaps, b2caps=b2caps, **kwargs)
       
  1026 
       
  1027     return util.chunkbuffer(bundler.getchunks())
       
  1028 
       
  1029 @getbundle2partsgenerator('changegroup')
       
  1030 def _getbundlechangegrouppart(bundler, repo, source, heads=None, common=None,
       
  1031                               bundlecaps=None, b2caps=None, **kwargs):
       
  1032     """add a changegroup part to the requested bundle"""
       
  1033     cg = None
       
  1034     if kwargs.get('cg', True):
       
  1035         # build changegroup bundle here.
       
  1036         cg = changegroup.getchangegroup(repo, source, heads=heads,
       
  1037                                         common=common, bundlecaps=bundlecaps)
       
  1038 
   999     if cg:
  1039     if cg:
  1000         bundler.newpart('b2x:changegroup', data=cg.getchunks())
  1040         bundler.newpart('b2x:changegroup', data=cg.getchunks())
       
  1041 
       
  1042 @getbundle2partsgenerator('listkeys')
       
  1043 def _getbundlelistkeysparts(bundler, repo, source, heads=None, common=None,
       
  1044                            bundlecaps=None, b2caps=None, **kwargs):
       
  1045     """add parts containing listkeys namespaces to the requested bundle"""
  1001     listkeys = kwargs.get('listkeys', ())
  1046     listkeys = kwargs.get('listkeys', ())
  1002     for namespace in listkeys:
  1047     for namespace in listkeys:
  1003         part = bundler.newpart('b2x:listkeys')
  1048         part = bundler.newpart('b2x:listkeys')
  1004         part.addparam('namespace', namespace)
  1049         part.addparam('namespace', namespace)
  1005         keys = repo.listkeys(namespace).items()
  1050         keys = repo.listkeys(namespace).items()
  1006         part.data = pushkey.encodekeys(keys)
  1051         part.data = pushkey.encodekeys(keys)
  1007     _getbundleobsmarkerpart(bundler, repo, source, heads=heads, common=common,
  1052 
  1008                             bundlecaps=bundlecaps, b2caps=b2caps, **kwargs)
  1053 @getbundle2partsgenerator('obsmarkers')
  1009     _getbundleextrapart(bundler, repo, source, heads=heads, common=common,
       
  1010                         bundlecaps=bundlecaps, b2caps=b2caps, **kwargs)
       
  1011     return util.chunkbuffer(bundler.getchunks())
       
  1012 
       
  1013 def _getbundleobsmarkerpart(bundler, repo, source, heads=None, common=None,
  1054 def _getbundleobsmarkerpart(bundler, repo, source, heads=None, common=None,
  1014                             bundlecaps=None, b2caps=None, **kwargs):
  1055                             bundlecaps=None, b2caps=None, **kwargs):
  1015     """add an obsolescence markers part to the requested bundle"""
  1056     """add an obsolescence markers part to the requested bundle"""
  1016     if kwargs.get('obsmarkers', False):
  1057     if kwargs.get('obsmarkers', False):
  1017         if heads is None:
  1058         if heads is None:
  1018             heads = repo.heads()
  1059             heads = repo.heads()
  1019         subset = [c.node() for c in repo.set('::%ln', heads)]
  1060         subset = [c.node() for c in repo.set('::%ln', heads)]
  1020         markers = repo.obsstore.relevantmarkers(subset)
  1061         markers = repo.obsstore.relevantmarkers(subset)
  1021         buildobsmarkerspart(bundler, markers)
  1062         buildobsmarkerspart(bundler, markers)
  1022 
  1063 
       
  1064 @getbundle2partsgenerator('extra')
  1023 def _getbundleextrapart(bundler, repo, source, heads=None, common=None,
  1065 def _getbundleextrapart(bundler, repo, source, heads=None, common=None,
  1024                         bundlecaps=None, b2caps=None, **kwargs):
  1066                         bundlecaps=None, b2caps=None, **kwargs):
  1025     """hook function to let extensions add parts to the requested bundle"""
  1067     """hook function to let extensions add parts to the requested bundle"""
  1026     pass
  1068     pass
  1027 
  1069