Rev 4490: (abentley) fetch warns instead of failing with unnecessary in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Mon Jun 29 17:33:15 BST 2009


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

------------------------------------------------------------
revno: 4490 [merge]
revision-id: pqm at pqm.ubuntu.com-20090629163313-qaehowmd2u5mxlvw
parent: pqm at pqm.ubuntu.com-20090629131656-3wzeg6my3orfni5b
parent: aaron at aaronbentley.com-20090629152508-3beydztiq5me07om
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2009-06-29 17:33:13 +0100
message:
  (abentley) fetch warns instead of failing with unnecessary
  	inconsistent data.
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/groupcompress.py        groupcompress.py-20080705181503-ccbxd6xuy1bdnrpu-8
  bzrlib/repofmt/groupcompress_repo.py repofmt.py-20080715094215-wp1qfvoo7093c8qr-1
  bzrlib/tests/test_groupcompress.py test_groupcompress.p-20080705181503-ccbxd6xuy1bdnrpu-13
  bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
=== modified file 'NEWS'
--- a/NEWS	2009-06-26 23:28:46 +0000
+++ b/NEWS	2009-06-29 15:10:47 +0000
@@ -50,6 +50,9 @@
 * ``bzr ls DIR --from-root`` now shows only things in DIR, not everything.
   (Ian Clatworthy)
 
+* Fetch between repositories does not error if they have inconsistent data
+  that should be irrelevant to the fetch operation. (Aaron Bentley)
+
 * Progress bars are now suppressed again when the environment variable
   ``BZR_PROGRESS_BAR`` is set to ``none``.
   (Martin Pool, #339385)

=== modified file 'bzrlib/groupcompress.py'
--- a/bzrlib/groupcompress.py	2009-06-23 15:27:50 +0000
+++ b/bzrlib/groupcompress.py	2009-06-29 14:51:13 +0000
@@ -942,7 +942,7 @@
         self.endpoint = endpoint
 
 
-def make_pack_factory(graph, delta, keylength):
+def make_pack_factory(graph, delta, keylength, inconsistency_fatal=True):
     """Create a factory for creating a pack based groupcompress.
 
     This is only functional enough to run interface tests, it doesn't try to
@@ -963,7 +963,8 @@
         writer = pack.ContainerWriter(stream.write)
         writer.begin()
         index = _GCGraphIndex(graph_index, lambda:True, parents=parents,
-            add_callback=graph_index.add_nodes)
+            add_callback=graph_index.add_nodes,
+            inconsistency_fatal=inconsistency_fatal)
         access = knit._DirectPackAccess({})
         access.set_writer(writer, graph_index, (transport, 'newpack'))
         result = GroupCompressVersionedFiles(index, access, delta)
@@ -1610,7 +1611,8 @@
     """Mapper from GroupCompressVersionedFiles needs into GraphIndex storage."""
 
     def __init__(self, graph_index, is_locked, parents=True,
-        add_callback=None, track_external_parent_refs=False):
+        add_callback=None, track_external_parent_refs=False,
+        inconsistency_fatal=True):
         """Construct a _GCGraphIndex on a graph_index.
 
         :param graph_index: An implementation of bzrlib.index.GraphIndex.
@@ -1624,12 +1626,17 @@
         :param track_external_parent_refs: As keys are added, keep track of the
             keys they reference, so that we can query get_missing_parents(),
             etc.
+        :param inconsistency_fatal: When asked to add records that are already
+            present, and the details are inconsistent with the existing
+            record, raise an exception instead of warning (and skipping the
+            record).
         """
         self._add_callback = add_callback
         self._graph_index = graph_index
         self._parents = parents
         self.has_graph = parents
         self._is_locked = is_locked
+        self._inconsistency_fatal = inconsistency_fatal
         if track_external_parent_refs:
             self._key_dependencies = knit._KeyRefs()
         else:
@@ -1671,8 +1678,14 @@
             present_nodes = self._get_entries(keys)
             for (index, key, value, node_refs) in present_nodes:
                 if node_refs != keys[key][1]:
-                    raise errors.KnitCorrupt(self, "inconsistent details in add_records"
-                        ": %s %s" % ((value, node_refs), keys[key]))
+                    details = '%s %s %s' % (key, (value, node_refs), keys[key])
+                    if self._inconsistency_fatal:
+                        raise errors.KnitCorrupt(self, "inconsistent details"
+                                                 " in add_records: %s" %
+                                                 details)
+                    else:
+                        trace.warning("inconsistent details in skipped"
+                                      " record: %s", details)
                 del keys[key]
                 changed = True
         if changed:

=== modified file 'bzrlib/repofmt/groupcompress_repo.py'
--- a/bzrlib/repofmt/groupcompress_repo.py	2009-06-26 09:24:34 +0000
+++ b/bzrlib/repofmt/groupcompress_repo.py	2009-06-29 14:51:13 +0000
@@ -622,7 +622,8 @@
         self.inventories = GroupCompressVersionedFiles(
             _GCGraphIndex(self._pack_collection.inventory_index.combined_index,
                 add_callback=self._pack_collection.inventory_index.add_callback,
-                parents=True, is_locked=self.is_locked),
+                parents=True, is_locked=self.is_locked,
+                inconsistency_fatal=False),
             access=self._pack_collection.inventory_index.data_access)
         self.revisions = GroupCompressVersionedFiles(
             _GCGraphIndex(self._pack_collection.revision_index.combined_index,
@@ -634,19 +635,22 @@
         self.signatures = GroupCompressVersionedFiles(
             _GCGraphIndex(self._pack_collection.signature_index.combined_index,
                 add_callback=self._pack_collection.signature_index.add_callback,
-                parents=False, is_locked=self.is_locked),
+                parents=False, is_locked=self.is_locked,
+                inconsistency_fatal=False),
             access=self._pack_collection.signature_index.data_access,
             delta=False)
         self.texts = GroupCompressVersionedFiles(
             _GCGraphIndex(self._pack_collection.text_index.combined_index,
                 add_callback=self._pack_collection.text_index.add_callback,
-                parents=True, is_locked=self.is_locked),
+                parents=True, is_locked=self.is_locked,
+                inconsistency_fatal=False),
             access=self._pack_collection.text_index.data_access)
         # No parents, individual CHK pages don't have specific ancestry
         self.chk_bytes = GroupCompressVersionedFiles(
             _GCGraphIndex(self._pack_collection.chk_index.combined_index,
                 add_callback=self._pack_collection.chk_index.add_callback,
-                parents=False, is_locked=self.is_locked),
+                parents=False, is_locked=self.is_locked,
+                inconsistency_fatal=False),
             access=self._pack_collection.chk_index.data_access)
         # True when the repository object is 'write locked' (as opposed to the
         # physical lock only taken out around changes to the pack-names list.)

=== modified file 'bzrlib/tests/test_groupcompress.py'
--- a/bzrlib/tests/test_groupcompress.py	2009-06-22 18:30:08 +0000
+++ b/bzrlib/tests/test_groupcompress.py	2009-06-29 14:51:13 +0000
@@ -25,6 +25,7 @@
     index as _mod_index,
     osutils,
     tests,
+    trace,
     versionedfile,
     )
 from bzrlib.osutils import sha_string
@@ -474,11 +475,12 @@
 class TestCaseWithGroupCompressVersionedFiles(tests.TestCaseWithTransport):
 
     def make_test_vf(self, create_graph, keylength=1, do_cleanup=True,
-                     dir='.'):
+                     dir='.', inconsistency_fatal=True):
         t = self.get_transport(dir)
         t.ensure_base()
         vf = groupcompress.make_pack_factory(graph=create_graph,
-            delta=False, keylength=keylength)(t)
+            delta=False, keylength=keylength,
+            inconsistency_fatal=inconsistency_fatal)(t)
         if do_cleanup:
             self.addCleanup(groupcompress.cleanup_pack_group, vf)
         return vf
@@ -658,6 +660,47 @@
             frozenset([('parent-1',), ('parent-2',)]),
             index.get_missing_parents())
 
+    def make_source_with_b(self, a_parent, path):
+        source = self.make_test_vf(True, dir=path)
+        source.add_lines(('a',), (), ['lines\n'])
+        if a_parent:
+            b_parents = (('a',),)
+        else:
+            b_parents = ()
+        source.add_lines(('b',), b_parents, ['lines\n'])
+        return source
+
+    def do_inconsistent_inserts(self, inconsistency_fatal):
+        target = self.make_test_vf(True, dir='target',
+                                   inconsistency_fatal=inconsistency_fatal)
+        for x in range(2):
+            source = self.make_source_with_b(x==1, 'source%s' % x)
+            target.insert_record_stream(source.get_record_stream(
+                [('b',)], 'unordered', False))
+
+    def test_inconsistent_redundant_inserts_warn(self):
+        """Should not insert a record that is already present."""
+        warnings = []
+        def warning(template, args):
+            warnings.append(template % args)
+        _trace_warning = trace.warning
+        trace.warning = warning
+        try:
+            self.do_inconsistent_inserts(inconsistency_fatal=False)
+        finally:
+            trace.warning = _trace_warning
+        self.assertEqual(["inconsistent details in skipped record: ('b',)"
+                          " ('42 32 0 8', ((),)) ('74 32 0 8', ((('a',),),))"],
+                         warnings)
+
+    def test_inconsistent_redundant_inserts_raises(self):
+        e = self.assertRaises(errors.KnitCorrupt, self.do_inconsistent_inserts,
+                              inconsistency_fatal=True)
+        self.assertContainsRe(str(e), "Knit.* corrupt: inconsistent details"
+                              " in add_records:"
+                              " \('b',\) \('42 32 0 8', \(\(\),\)\) \('74 32"
+                              " 0 8', \(\(\('a',\),\),\)\)")
+
 
 class TestLazyGroupCompress(tests.TestCaseWithTransport):
 

=== modified file 'bzrlib/tests/test_repository.py'
--- a/bzrlib/tests/test_repository.py	2009-06-26 09:24:34 +0000
+++ b/bzrlib/tests/test_repository.py	2009-06-29 15:07:51 +0000
@@ -797,6 +797,14 @@
         self.assertEqual(257, len(full_chk_records))
         self.assertSubset(simple_chk_records, full_chk_records)
 
+    def test_inconsistency_fatal(self):
+        repo = self.make_repository('repo', format='2a')
+        self.assertTrue(repo.revisions._index._inconsistency_fatal)
+        self.assertFalse(repo.texts._index._inconsistency_fatal)
+        self.assertFalse(repo.inventories._index._inconsistency_fatal)
+        self.assertFalse(repo.signatures._index._inconsistency_fatal)
+        self.assertFalse(repo.chk_bytes._index._inconsistency_fatal)
+
 
 class TestKnitPackStreamSource(tests.TestCaseWithMemoryTransport):
 




More information about the bazaar-commits mailing list