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: |