Rev 3461: * Inserting a bundle which changes the contents of a file with no trailing in http://people.ubuntu.com/~robertc/baz2.0/mpdiff

Robert Collins robertc at robertcollins.net
Fri May 30 07:01:15 BST 2008


At http://people.ubuntu.com/~robertc/baz2.0/mpdiff

------------------------------------------------------------
revno: 3461
revision-id: robertc at robertcollins.net-20080530060052-31grufsbxx24vj0j
parent: pqm at pqm.ubuntu.com-20080529210000-bycgfufmrqq63tki
committer: Robert Collins <robertc at robertcollins.net>
branch nick: mpdiff
timestamp: Fri 2008-05-30 16:00:52 +1000
message:
   * Inserting a bundle which changes the contents of a file with no trailing
     end of line, causing a knit snapshot in a 'knits' repository will no longer
     cause KnitCorrupt. (Robert Collins)
  
   * Knit record serialisation is now stricter on what it will accept, to
     guard against potential internal bugs, or broken input. (Robert Collins)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
  bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
=== modified file 'NEWS'
--- a/NEWS	2008-05-29 21:00:00 +0000
+++ b/NEWS	2008-05-30 06:00:52 +0000
@@ -77,6 +77,10 @@
     * Handle old merge directives correctly in Merger.from_mergeable.  Stricter
       get_parent_map requirements exposed a latent bug here.  (Aaron Bentley)
 
+    * Inserting a bundle which changes the contents of a file with no trailing
+      end of line, causing a knit snapshot in a 'knits' repository will no longer
+      cause KnitCorrupt. (Robert Collins)
+
     * Issue a warning and ignore passwords declared in authentication.conf when
       used for an ssh scheme (sftp or bzr+ssh).
       (Vincent Ladeuil, #203186)
@@ -115,6 +119,9 @@
 
   INTERNALS:
 
+    * Knit record serialisation is now stricter on what it will accept, to
+      guard against potential internal bugs, or broken input. (Robert Collins)
+
   API CHANGES:
 
     * ``Branch.abspath`` is deprecated; use the Tree or Transport 

=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py	2008-05-12 02:40:40 +0000
+++ b/bzrlib/knit.py	2008-05-30 06:00:52 +0000
@@ -1193,10 +1193,16 @@
                 for i, j, n in seq.get_matching_blocks():
                     if n == 0:
                         continue
-                    # this appears to copy (origin, text) pairs across to the
-                    # new content for any line that matches the last-checked
+                    # this copies (origin, text) pairs across to the new
+                    # content for any line that matches the last-checked
                     # parent.
                     content._lines[j:j+n] = merge_content._lines[i:i+n]
+            if content._lines and content._lines[-1][1][-1] != '\n':
+                # The copied annotation was from a line without a trailing EOL,
+                # reinstate one for the content object, to ensure correct
+                # serialization.
+                line = content._lines[-1][1] + '\n'
+                content._lines[-1] = (content._lines[-1][0], line)
         if delta:
             if delta_seq is None:
                 reference_content = self._get_content(parents[0], parent_texts)
@@ -1339,6 +1345,10 @@
             delta = self._check_should_delta(present_parents)
 
         content = self.factory.make(lines, version_id)
+        if 'no-eol' in options:
+            # Hint to the content object that its text() call should strip the
+            # EOL.
+            content._should_strip_eol = True
         if delta or (self.factory.annotated and len(present_parents) > 0):
             # Merge annotations from parent texts if needed.
             delta_hunks = self._merge_annotations(content, present_parents,
@@ -2697,6 +2707,8 @@
                                      digest)],
             dense_lines or lines,
             ["end %s\n" % version_id]))
+        if lines and lines[-1][-1] != '\n':
+            raise ValueError('corrupt lines value %r' % lines)
         compressed_bytes = bytes_to_gzip(bytes)
         return len(compressed_bytes), compressed_bytes
 

=== modified file 'bzrlib/tests/test_versionedfile.py'
--- a/bzrlib/tests/test_versionedfile.py	2008-05-12 02:40:40 +0000
+++ b/bzrlib/tests/test_versionedfile.py	2008-05-30 06:00:52 +0000
@@ -530,6 +530,28 @@
         self.assertRaises(errors.ReservedId, vf.get_lines, 'b:')
         self.assertRaises(errors.ReservedId, vf.get_text, 'b:')
 
+    def test_add_lines_with_matching_blocks_noeol_last_line(self):
+        """Add a text with an unchanged last line with no eol should work."""
+        from bzrlib import multiparent
+        # Hand verified sha1 of the text we're adding.
+        sha1 = '6a1d115ec7b60afb664dc14890b5af5ce3c827a4'
+        # Create a mpdiff which adds a new line before the trailing line, and
+        # reuse the last line unaltered (which can cause annotation reuse).
+        # Test adding this in two situations:
+        # On top of a new insertion
+        vf = self.get_file('fulltext')
+        vf.add_lines('noeol', [], ['line'])
+        vf.add_lines('noeol2', ['noeol'], ['newline\n', 'line'],
+            left_matching_blocks=[(0, 1, 1)])
+        self.assertEqualDiff('newline\nline', vf.get_text('noeol2'))
+        # On top of a delta
+        vf = self.get_file('delta')
+        vf.add_lines('base', [], ['line'])
+        vf.add_lines('noeol', ['base'], ['prelude\n', 'line'])
+        vf.add_lines('noeol2', ['noeol'], ['newline\n', 'line'],
+            left_matching_blocks=[(1, 1, 1)])
+        self.assertEqualDiff('newline\nline', vf.get_text('noeol2'))
+
     def test_make_mpdiffs(self):
         from bzrlib import multiparent
         vf = self.get_file('foo')




More information about the bazaar-commits mailing list