bundle-ng: add bundlecaps argument to getbundle() command
authorBenoit Boissinot <benoit.boissinot@ens-lyon.org>
Sat, 09 Feb 2013 23:42:03 +0100
changeset 19201 309c439cdbaa
parent 19200 4cfdec944edf
child 19202 0455fc94ae00
bundle-ng: add bundlecaps argument to getbundle() command
mercurial/changegroup.py
mercurial/commands.py
mercurial/localrepo.py
mercurial/wireproto.py
--- a/mercurial/changegroup.py	Fri May 10 21:03:01 2013 +0200
+++ b/mercurial/changegroup.py	Sat Feb 09 23:42:03 2013 +0100
@@ -225,8 +225,11 @@
 
 class bundle10(object):
     deltaheader = _BUNDLE10_DELTA_HEADER
-    def __init__(self):
-        pass
+    def __init__(self, bundlecaps=None):
+        # Set of capabilities we can use to build the bundle.
+        if bundlecaps is None:
+            bundlecaps = set()
+        self._bundlecaps = bundlecaps
     def start(self, lookup):
         self._lookup = lookup
     def close(self):
--- a/mercurial/commands.py	Fri May 10 21:03:01 2013 +0200
+++ b/mercurial/commands.py	Sat Feb 09 23:42:03 2013 +0100
@@ -1096,13 +1096,16 @@
         base = ['null']
     else:
         base = scmutil.revrange(repo, opts.get('base'))
+    # TODO: get desired bundlecaps from command line.
+    bundlecaps = None
     if base:
         if dest:
             raise util.Abort(_("--base is incompatible with specifying "
                                "a destination"))
         common = [repo.lookup(rev) for rev in base]
         heads = revs and map(repo.lookup, revs) or revs
-        cg = repo.getbundle('bundle', heads=heads, common=common)
+        cg = repo.getbundle('bundle', heads=heads, common=common,
+                            bundlecaps=bundlecaps)
         outgoing = None
     else:
         dest = ui.expandpath(dest or 'default-push', dest or 'default')
@@ -1114,7 +1117,7 @@
                                                 onlyheads=heads,
                                                 force=opts.get('force'),
                                                 portable=True)
-        cg = repo.getlocalbundle('bundle', outgoing)
+        cg = repo.getlocalbundle('bundle', outgoing, bundlecaps)
     if not cg:
         scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
         return 1
@@ -1913,6 +1916,8 @@
         args['common'] = [bin(s) for s in common]
     if head:
         args['heads'] = [bin(s) for s in head]
+    # TODO: get desired bundlecaps from command line.
+    args['bundlecaps'] = None
     bundle = repo.getbundle('debug', **args)
 
     bundletype = opts.get('type', 'bzip2').lower()
--- a/mercurial/localrepo.py	Fri May 10 21:03:01 2013 +0200
+++ b/mercurial/localrepo.py	Sat Feb 09 23:42:03 2013 +0100
@@ -99,8 +99,9 @@
     def known(self, nodes):
         return self._repo.known(nodes)
 
-    def getbundle(self, source, heads=None, common=None):
-        return self._repo.getbundle(source, heads=heads, common=common)
+    def getbundle(self, source, heads=None, common=None, bundlecaps=None):
+        return self._repo.getbundle(source, heads=heads, common=common,
+                                    bundlecaps=None)
 
     # TODO We might want to move the next two calls into legacypeer and add
     # unbundle instead.
@@ -1674,6 +1675,7 @@
                     heads = rheads
 
                 if remote.capable('getbundle'):
+                    # TODO: get bundlecaps from remote
                     cg = remote.getbundle('pull', common=common,
                                           heads=heads or rheads)
                 elif heads is None:
@@ -1836,15 +1838,17 @@
                                              remoteheads, newbranch,
                                              bool(inc))
 
+                    # TODO: get bundlecaps from remote
+                    bundlecaps = None
                     # create a changegroup from local
                     if revs is None and not outgoing.excluded:
                         # push everything,
                         # use the fast path, no race possible on push
-                        bundler = changegroup.bundle10()
+                        bundler = changegroup.bundle10(bundlecaps)
                         cg = self._changegroup(outgoing.missing, bundler,
                                                'push')
                     else:
-                        cg = self.getlocalbundle('push', outgoing)
+                        cg = self.getlocalbundle('push', outgoing, bundlecaps)
 
                     # apply changegroup to remote
                     if unbundle:
@@ -1991,21 +1995,21 @@
         bundler = changegroup.bundle10()
         return self._changegroupsubset(common, csets, heads, bundler, source)
 
-    def getlocalbundle(self, source, outgoing):
+    def getlocalbundle(self, source, outgoing, bundlecaps=None):
         """Like getbundle, but taking a discovery.outgoing as an argument.
 
         This is only implemented for local repos and reuses potentially
         precomputed sets in outgoing."""
         if not outgoing.missing:
             return None
-        bundler = changegroup.bundle10()
+        bundler = changegroup.bundle10(bundlecaps)
         return self._changegroupsubset(outgoing.common,
                                        outgoing.missing,
                                        outgoing.missingheads,
                                        bundler,
                                        source)
 
-    def getbundle(self, source, heads=None, common=None):
+    def getbundle(self, source, heads=None, common=None, bundlecaps=None):
         """Like changegroupsubset, but returns the set difference between the
         ancestors of heads and the ancestors common.
 
@@ -2023,7 +2027,8 @@
         if not heads:
             heads = cl.heads()
         return self.getlocalbundle(source,
-                                   discovery.outgoing(cl, common, heads))
+                                   discovery.outgoing(cl, common, heads),
+                                   bundlecaps=bundlecaps)
 
     @unfilteredmethod
     def _changegroupsubset(self, commonrevs, csets, heads, bundler, source):
--- a/mercurial/wireproto.py	Fri May 10 21:03:01 2013 +0200
+++ b/mercurial/wireproto.py	Sat Feb 09 23:42:03 2013 +0100
@@ -281,13 +281,15 @@
                              bases=bases, heads=heads)
         return changegroupmod.unbundle10(self._decompress(f), 'UN')
 
-    def getbundle(self, source, heads=None, common=None):
+    def getbundle(self, source, heads=None, common=None, bundlecaps=None):
         self.requirecap('getbundle', _('look up remote changes'))
         opts = {}
         if heads is not None:
             opts['heads'] = encodelist(heads)
         if common is not None:
             opts['common'] = encodelist(common)
+        if bundlecaps is not None:
+            opts['bundlecaps'] = ','.join(bundlecaps)
         f = self._callstream("getbundle", **opts)
         return changegroupmod.unbundle10(self._decompress(f), 'UN')
 
@@ -449,9 +451,12 @@
     return repo.debugwireargs(one, two, **opts)
 
 def getbundle(repo, proto, others):
-    opts = options('getbundle', ['heads', 'common'], others)
+    opts = options('getbundle', ['heads', 'common', 'bundlecaps'], others)
     for k, v in opts.iteritems():
-        opts[k] = decodelist(v)
+        if k in ('heads', 'common'):
+            opts[k] = decodelist(v)
+        elif k == 'bundlecaps':
+            opts[k] = set(v.split(','))
     cg = repo.getbundle('serve', **opts)
     return streamres(proto.groupchunks(cg))