Rev 3588: (mbp) Better message about incompatible repositories in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Jul 29 10:33:04 BST 2008


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3588
revision-id:pqm at pqm.ubuntu.com-20080729093250-b1g7zu2k1pj0mswe
parent: pqm at pqm.ubuntu.com-20080729084005-ohq1fb6mheyeaqr6
parent: mbp at sourcefrog.net-20080729090037-ydaypne9ewtd0v3p
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2008-07-29 10:32:50 +0100
message:
  (mbp) Better message about incompatible repositories
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/tests/test_fetch.py     testfetch.py-20050825090644-f73e07e7dfb1765a
  doc/developers/HACKING.txt     HACKING-20050805200004-2a5dc975d870f78c
    ------------------------------------------------------------
    revno: 3582.1.6
    revision-id:mbp at sourcefrog.net-20080729090037-ydaypne9ewtd0v3p
    parent: mbp at sourcefrog.net-20080729085014-xioadu8uav3guezw
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: check_compatible
    timestamp: Tue 2008-07-29 19:00:37 +1000
    message:
      developer guide ReST syntax fix
    modified:
      doc/developers/HACKING.txt     HACKING-20050805200004-2a5dc975d870f78c
    ------------------------------------------------------------
    revno: 3582.1.5
    revision-id:mbp at sourcefrog.net-20080729085014-xioadu8uav3guezw
    parent: mbp at sourcefrog.net-20080729084112-4s93r8ujfwd0a8sq
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: check_compatible
    timestamp: Tue 2008-07-29 18:50:14 +1000
    message:
      style tweak
    modified:
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
    ------------------------------------------------------------
    revno: 3582.1.4
    revision-id:mbp at sourcefrog.net-20080729084112-4s93r8ujfwd0a8sq
    parent: mbp at sourcefrog.net-20080729025456-5iazhviapqgg77hq
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: check_compatible
    timestamp: Tue 2008-07-29 18:41:12 +1000
    message:
      Mention in NEWS that #206258 is now fixed
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 3582.1.3
    revision-id:mbp at sourcefrog.net-20080729025456-5iazhviapqgg77hq
    parent: mbp at sourcefrog.net-20080728084303-rjroyiv5oe2jto26
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: check_compatible
    timestamp: Tue 2008-07-29 12:54:56 +1000
    message:
      Repository.fetch no longer needs to translate NotImplementedErro to IncompatibleRepositories
    modified:
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
    ------------------------------------------------------------
    revno: 3582.1.2
    revision-id:mbp at sourcefrog.net-20080728084303-rjroyiv5oe2jto26
    parent: mbp at sourcefrog.net-20080728072006-5irnysoosat1eq0k
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: check_compatible
    timestamp: Mon 2008-07-28 18:43:03 +1000
    message:
      Default InterRepository.fetch raises IncompatibleRepositories
    modified:
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/tests/test_fetch.py     testfetch.py-20050825090644-f73e07e7dfb1765a
    ------------------------------------------------------------
    revno: 3582.1.1
    revision-id:mbp at sourcefrog.net-20080728072006-5irnysoosat1eq0k
    parent: pqm at pqm.ubuntu.com-20080728024856-nbikndmfq06firuo
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: check_compatible
    timestamp: Mon 2008-07-28 17:20:06 +1000
    message:
      Document InterObject
    modified:
      doc/developers/HACKING.txt     HACKING-20050805200004-2a5dc975d870f78c
=== modified file 'NEWS'
--- a/NEWS	2008-07-29 05:09:29 +0000
+++ b/NEWS	2008-07-29 09:32:50 +0000
@@ -37,6 +37,9 @@
 
   BUG FIXES:
 
+    * Better message about incompatible repositories.
+      (Martin Pool, #206258)
+
     * ``bzr branch --stacked`` ensures the destination branch format can
       support stacking, even if the origin does not.
       (Martin Pool)

=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py	2008-07-25 09:39:26 +0000
+++ b/bzrlib/errors.py	2008-07-29 08:50:14 +0000
@@ -774,11 +774,15 @@
 
 class IncompatibleRepositories(BzrError):
 
-    _fmt = "Repository %(target)s is not compatible with repository"\
-        " %(source)s"
+    _fmt = "%(target)s\n" \
+            "is not compatible with\n" \
+            "%(source)s\n" \
+            "%(details)s"
 
-    def __init__(self, source, target):
-        BzrError.__init__(self, target=target, source=source)
+    def __init__(self, source, target, details=None):
+        if details is None:
+            details = "(no details)"
+        BzrError.__init__(self, target=target, source=source, details=details)
 
 
 class IncompatibleRevision(BzrError):

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2008-07-28 09:12:28 +0000
+++ b/bzrlib/repository.py	2008-07-29 09:32:50 +0000
@@ -967,11 +967,12 @@
                 not _mod_revision.is_null(revision_id)):
                 self.get_revision(revision_id)
             return 0, []
+        # if there is no specific appropriate InterRepository, this will get
+        # the InterRepository base class, which raises an
+        # IncompatibleRepositories when asked to fetch.
         inter = InterRepository.get(source, self)
-        try:
-            return inter.fetch(revision_id=revision_id, pb=pb, find_ghosts=find_ghosts)
-        except NotImplementedError:
-            raise errors.IncompatibleRepositories(source, self)
+        return inter.fetch(revision_id=revision_id, pb=pb,
+            find_ghosts=find_ghosts)
 
     def create_bundle(self, target, base, fileobj, format=None):
         return serializer.write_bundle(self, target, base, fileobj, format)
@@ -2362,10 +2363,16 @@
         :param pb: optional progress bar to use for progress reports. If not
                    provided a default one will be created.
 
-        Returns the copied revision count and the failed revisions in a tuple:
-        (copied, failures).
+        :returns: (copied_revision_count, failures).
         """
-        raise NotImplementedError(self.fetch)
+        # Normally we should find a specific InterRepository subclass to do
+        # the fetch; if nothing else then at least InterSameDataRepository.
+        # If none of them is suitable it looks like fetching is not possible;
+        # we try to give a good message why.  _assert_same_model will probably
+        # give a helpful message; otherwise a generic one.
+        self._assert_same_model(self.source, self.target)
+        raise errors.IncompatibleRepositories(self.source, self.target,
+            "no suitableInterRepository found")
 
     def _walk_to_common_revisions(self, revision_ids):
         """Walk out from revision_ids in source to revisions target has.
@@ -2445,12 +2452,27 @@
 
     @staticmethod
     def _same_model(source, target):
-        """True if source and target have the same data representation."""
+        """True if source and target have the same data representation.
+        
+        Note: this is always called on the base class; overriding it in a
+        subclass will have no effect.
+        """
+        try:
+            InterRepository._assert_same_model(source, target)
+            return True
+        except errors.IncompatibleRepositories, e:
+            return False
+
+    @staticmethod
+    def _assert_same_model(source, target):
+        """Raise an exception if two repositories do not use the same model.
+        """
         if source.supports_rich_root() != target.supports_rich_root():
-            return False
+            raise errors.IncompatibleRepositories(source, target,
+                "different rich-root support")
         if source._serializer != target._serializer:
-            return False
-        return True
+            raise errors.IncompatibleRepositories(source, target,
+                "different serializers")
 
 
 class InterSameDataRepository(InterRepository):

=== modified file 'bzrlib/tests/test_fetch.py'
--- a/bzrlib/tests/test_fetch.py	2008-06-11 04:20:16 +0000
+++ b/bzrlib/tests/test_fetch.py	2008-07-28 08:43:03 +0000
@@ -170,8 +170,11 @@
         knit3_tree = self.make_branch_and_tree('knit3',
             format='dirstate-with-subtree')
         knit3_tree.commit('blah')
-        self.assertRaises(errors.IncompatibleRepositories,
-                          knit_tree.branch.fetch, knit3_tree.branch)
+        e = self.assertRaises(errors.IncompatibleRepositories,
+                              knit_tree.branch.fetch, knit3_tree.branch)
+        self.assertContainsRe(str(e),
+            r"(?m).*/knit.*\nis not compatible with\n.*/knit3/.*\n"
+            r"different rich-root support")
 
 
 class TestMergeFetch(TestCaseWithTransport):

=== modified file 'doc/developers/HACKING.txt'
--- a/doc/developers/HACKING.txt	2008-07-15 05:06:13 +0000
+++ b/doc/developers/HACKING.txt	2008-07-29 09:00:37 +0000
@@ -895,6 +895,29 @@
 associated information such as a help string or description.
 
 
+InterObject and multiple dispatch
+=================================
+
+The ``InterObject`` provides for two-way `multiple dispatch`__: matching
+up for example a source and destination repository to find the right way
+to transfer data between them. 
+
+.. __: http://en.wikipedia.org/wiki/Multiple_dispatch
+
+There is a subclass ``InterObject`` classes for each type of object that is
+dispatched this way, e.g. ``InterRepository``.  Calling ``.get()`` on this
+class will return an ``InterObject`` instance providing the best match for 
+those parameters, and this instance then has methods for operations
+between the objects.
+
+  inter = InterRepository.get(source_repo, target_repo)
+  inter.fetch(revision_id)
+
+``InterRepository`` also acts as a registry-like object for its
+subclasses, and they can be added through ``.register_optimizer``.  The
+right one to run is selected by asking each class, in reverse order of
+registration, whether it ``.is_compatible`` with the relevant objects.
+
 Lazy Imports
 ============
 




More information about the bazaar-commits mailing list