mercurial/exchange.py
changeset 26759 c0f475ac997e
parent 26756 9e272a96f764
child 26760 a18ee7da38c2
equal deleted inserted replaced
26758:bde7ef23340d 26759:c0f475ac997e
    37     order to ensure that bundles produced by a newer version of Mercurial are
    37     order to ensure that bundles produced by a newer version of Mercurial are
    38     readable from an older version.
    38     readable from an older version.
    39 
    39 
    40     The string currently has the form:
    40     The string currently has the form:
    41 
    41 
    42        <compression>-<type>
    42        <compression>-<type>[;<parameter0>[;<parameter1>]]
    43 
    43 
    44     Where <compression> is one of the supported compression formats
    44     Where <compression> is one of the supported compression formats
    45     and <type> is (currently) a version string.
    45     and <type> is (currently) a version string. A ";" can follow the type and
       
    46     all text afterwards is interpretted as URI encoded, ";" delimited key=value
       
    47     pairs.
    46 
    48 
    47     If ``strict`` is True (the default) <compression> is required. Otherwise,
    49     If ``strict`` is True (the default) <compression> is required. Otherwise,
    48     it is optional.
    50     it is optional.
    49 
    51 
    50     If ``externalnames`` is False (the default), the human-centric names will
    52     If ``externalnames`` is False (the default), the human-centric names will
    51     be converted to their internal representation.
    53     be converted to their internal representation.
    52 
    54 
    53     Returns a 2-tuple of (compression, version). Compression will be ``None``
    55     Returns a 3-tuple of (compression, version, parameters). Compression will
    54     if not in strict mode and a compression isn't defined.
    56     be ``None`` if not in strict mode and a compression isn't defined.
    55 
    57 
    56     An ``InvalidBundleSpecification`` is raised when the specification is
    58     An ``InvalidBundleSpecification`` is raised when the specification is
    57     not syntactically well formed.
    59     not syntactically well formed.
    58 
    60 
    59     An ``UnsupportedBundleSpecification`` is raised when the compression or
    61     An ``UnsupportedBundleSpecification`` is raised when the compression or
    60     bundle type/version is not recognized.
    62     bundle type/version is not recognized.
    61 
    63 
    62     Note: this function will likely eventually return a more complex data
    64     Note: this function will likely eventually return a more complex data
    63     structure, including bundle2 part information.
    65     structure, including bundle2 part information.
    64     """
    66     """
       
    67     def parseparams(s):
       
    68         if ';' not in s:
       
    69             return s, {}
       
    70 
       
    71         params = {}
       
    72         version, paramstr = s.split(';', 1)
       
    73 
       
    74         for p in paramstr.split(';'):
       
    75             if '=' not in p:
       
    76                 raise error.InvalidBundleSpecification(
       
    77                     _('invalid bundle specification: '
       
    78                       'missing "=" in parameter: %s') % p)
       
    79 
       
    80             key, value = p.split('=', 1)
       
    81             key = urllib.unquote(key)
       
    82             value = urllib.unquote(value)
       
    83             params[key] = value
       
    84 
       
    85         return version, params
       
    86 
       
    87 
    65     if strict and '-' not in spec:
    88     if strict and '-' not in spec:
    66         raise error.InvalidBundleSpecification(
    89         raise error.InvalidBundleSpecification(
    67                 _('invalid bundle specification; '
    90                 _('invalid bundle specification; '
    68                   'must be prefixed with compression: %s') % spec)
    91                   'must be prefixed with compression: %s') % spec)
    69 
    92 
    71         compression, version = spec.split('-', 1)
    94         compression, version = spec.split('-', 1)
    72 
    95 
    73         if compression not in _bundlespeccompressions:
    96         if compression not in _bundlespeccompressions:
    74             raise error.UnsupportedBundleSpecification(
    97             raise error.UnsupportedBundleSpecification(
    75                     _('%s compression is not supported') % compression)
    98                     _('%s compression is not supported') % compression)
       
    99 
       
   100         version, params = parseparams(version)
    76 
   101 
    77         if version not in _bundlespeccgversions:
   102         if version not in _bundlespeccgversions:
    78             raise error.UnsupportedBundleSpecification(
   103             raise error.UnsupportedBundleSpecification(
    79                     _('%s is not a recognized bundle version') % version)
   104                     _('%s is not a recognized bundle version') % version)
    80     else:
   105     else:
    81         # Value could be just the compression or just the version, in which
   106         # Value could be just the compression or just the version, in which
    82         # case some defaults are assumed (but only when not in strict mode).
   107         # case some defaults are assumed (but only when not in strict mode).
    83         assert not strict
   108         assert not strict
       
   109 
       
   110         spec, params = parseparams(spec)
    84 
   111 
    85         if spec in _bundlespeccompressions:
   112         if spec in _bundlespeccompressions:
    86             compression = spec
   113             compression = spec
    87             version = 'v1'
   114             version = 'v1'
    88             if 'generaldelta' in repo.requirements:
   115             if 'generaldelta' in repo.requirements:
    98                     _('%s is not a recognized bundle specification') % spec)
   125                     _('%s is not a recognized bundle specification') % spec)
    99 
   126 
   100     if not externalnames:
   127     if not externalnames:
   101         compression = _bundlespeccompressions[compression]
   128         compression = _bundlespeccompressions[compression]
   102         version = _bundlespeccgversions[version]
   129         version = _bundlespeccgversions[version]
   103     return compression, version
   130     return compression, version, params
   104 
   131 
   105 def readbundle(ui, fh, fname, vfs=None):
   132 def readbundle(ui, fh, fname, vfs=None):
   106     header = changegroup.readexactly(fh, 4)
   133     header = changegroup.readexactly(fh, 4)
   107 
   134 
   108     alg = None
   135     alg = None
  1689             # Parse BUNDLESPEC into components. This makes client-side
  1716             # Parse BUNDLESPEC into components. This makes client-side
  1690             # preferences easier to specify since you can prefer a single
  1717             # preferences easier to specify since you can prefer a single
  1691             # component of the BUNDLESPEC.
  1718             # component of the BUNDLESPEC.
  1692             if key == 'BUNDLESPEC':
  1719             if key == 'BUNDLESPEC':
  1693                 try:
  1720                 try:
  1694                     comp, version = parsebundlespec(repo, value,
  1721                     comp, version, params = parsebundlespec(repo, value,
  1695                                                     externalnames=True)
  1722                                                             externalnames=True)
  1696                     attrs['COMPRESSION'] = comp
  1723                     attrs['COMPRESSION'] = comp
  1697                     attrs['VERSION'] = version
  1724                     attrs['VERSION'] = version
  1698                 except error.InvalidBundleSpecification:
  1725                 except error.InvalidBundleSpecification:
  1699                     pass
  1726                     pass
  1700                 except error.UnsupportedBundleSpecification:
  1727                 except error.UnsupportedBundleSpecification: