Patchwork [6,of,8,stream,clone,bundles,V2] exchange: parse requirements from stream clone specification string

login
register
mail settings
Submitter Gregory Szorc
Date Oct. 17, 2015, 6:45 p.m.
Message ID <85a8854e4f52539cde2a.1445107502@126.1.168.192.in-addr.arpa>
Download mbox | patch
Permalink /patch/11166/
State Accepted
Headers show

Comments

Gregory Szorc - Oct. 17, 2015, 6:45 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1445102794 25200
#      Sat Oct 17 10:26:34 2015 -0700
# Node ID 85a8854e4f52539cde2a15a0edc9bb423e53003d
# Parent  b749836c17b547ff75d04cba6630d144c4433591
exchange: parse requirements from stream clone specification string

Stream clone bundles can only be consumed if the consumer supports the
exact format requirements that were present on the producer.

This patch adds support for encoding and verifying the format
requirements on the bundle specification string for a stream clone
bundle are supported by the local repository. If they aren't, we raise
an UnsupportedBundleSpecification, just like we do when an unknown
compression or bundle type is encountered.

The impetus for this patch is so the clone bundles manifest can
advertise stream clone bundles and so clients can filter out stream
clones with unsupported format requirements. e.g. a stream clone
produced with the not-yet-invented "revlogv2" format will be ignored by
clients that only support "revlogv1."

Patch

diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -123,8 +123,19 @@  def parsebundlespec(repo, spec, strict=T
         else:
             raise error.UnsupportedBundleSpecification(
                     _('%s is not a recognized bundle specification') % spec)
 
+    # The specification for packed1 can optionally declare the data formats
+    # required to apply it. If we see this metadata, compare against what the
+    # repo supports and error if the bundle isn't compatible.
+    if version == 'packed1' and 'requirements' in params:
+        requirements = set(params['requirements'].split(','))
+        missingreqs = requirements - repo.supportedformats
+        if missingreqs:
+            raise error.UnsupportedBundleSpecification(
+                    _('missing support for repository features: %s') %
+                      ', '.join(sorted(missingreqs)))
+
     if not externalnames:
         compression = _bundlespeccompressions[compression]
         version = _bundlespeccgversions[version]
     return compression, version, params