Rev 6052: (jelmer) Allow other kinds of file "verifiers" than SHA1. (Jelmer Vernooij) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Fri Aug 5 16:51:08 UTC 2011


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

------------------------------------------------------------
revno: 6052 [merge]
revision-id: pqm at pqm.ubuntu.com-20110805165101-e89g9pgybm7db15a
parent: pqm at pqm.ubuntu.com-20110804144149-stscwftjwbxczpbi
parent: jelmer at samba.org-20110805133440-xuqxcqv52mrv98sq
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2011-08-05 16:51:01 +0000
message:
  (jelmer) Allow other kinds of file "verifiers" than SHA1. (Jelmer Vernooij)
added:
  bzrlib/tests/per_intertree/test_file_content_matches.py test_file_content_ma-20110804134917-fsf6w8x3h82s89gj-1
modified:
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/tests/per_intertree/__init__.py __init__.py-20060724101752-09ysswo1a92uqyoz-3
  bzrlib/tests/per_intertree/test_compare.py test_compare.py-20060724101752-09ysswo1a92uqyoz-2
  bzrlib/tests/per_tree/test_tree.py test_tree.py-20061215160206-usu7lwcj8aq2n3br-1
  bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
  bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
  bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
  doc/en/release-notes/bzr-2.5.txt bzr2.5.txt-20110708125756-587p0hpw7oke4h05-1
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2011-07-18 14:43:35 +0000
+++ b/bzrlib/branch.py	2011-08-04 13:30:30 +0000
@@ -66,11 +66,6 @@
 from bzrlib.trace import mutter, mutter_callsite, note, is_quiet
 
 
-BZR_BRANCH_FORMAT_4 = "Bazaar-NG branch, format 0.0.4\n"
-BZR_BRANCH_FORMAT_5 = "Bazaar-NG branch, format 5\n"
-BZR_BRANCH_FORMAT_6 = "Bazaar Branch Format 6 (bzr 0.15)\n"
-
-
 class Branch(controldir.ControlComponent):
     """Branch holding a history of revisions.
 
@@ -3165,7 +3160,7 @@
 
 
 class Converter7to8(object):
-    """Perform an in-place upgrade of format 6 to format 7"""
+    """Perform an in-place upgrade of format 7 to format 8"""
 
     def convert(self, branch):
         format = BzrBranchFormat8()

=== modified file 'bzrlib/tests/per_intertree/__init__.py'
--- a/bzrlib/tests/per_intertree/__init__.py	2011-05-03 23:54:46 +0000
+++ b/bzrlib/tests/per_intertree/__init__.py	2011-08-04 14:01:47 +0000
@@ -122,6 +122,7 @@
     default_tree_format = WorkingTreeFormat3()
     submod_tests = loader.loadTestsFromModuleNames([
         'bzrlib.tests.per_intertree.test_compare',
+        'bzrlib.tests.per_intertree.test_file_content_matches',
         ])
     test_intertree_permutations = [
         # test InterTree with two default-format working trees.

=== modified file 'bzrlib/tests/per_intertree/test_compare.py'
--- a/bzrlib/tests/per_intertree/test_compare.py	2011-06-14 01:26:41 +0000
+++ b/bzrlib/tests/per_intertree/test_compare.py	2011-08-04 14:01:47 +0000
@@ -23,12 +23,10 @@
     errors,
     mutabletree,
     tests,
-    workingtree_4,
     )
-from bzrlib.osutils import file_kind, has_symlinks
+from bzrlib.osutils import has_symlinks
 from bzrlib.tests.per_intertree import TestCaseWithTwoTrees
 from bzrlib.tests import (
-    TestNotApplicable,
     features,
     )
 

=== added file 'bzrlib/tests/per_intertree/test_file_content_matches.py'
--- a/bzrlib/tests/per_intertree/test_file_content_matches.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/per_intertree/test_file_content_matches.py	2011-08-04 14:01:47 +0000
@@ -0,0 +1,48 @@
+# Copyright (C) 2011 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Tests for the InterTree.file_content_matches() function."""
+
+from bzrlib.tests.per_intertree import TestCaseWithTwoTrees
+
+
+class TestFileContentMatches(TestCaseWithTwoTrees):
+
+    def test_same_contents_and_verifier(self):
+        tree1 = self.make_branch_and_tree('1')
+        tree2 = self.make_to_branch_and_tree('2')
+        self.build_tree_contents([
+            ('1/file', 'apples'),
+            ('2/file', 'apples'),
+            ])
+        tree1.add('file', 'file-id-1')
+        tree2.add('file', 'file-id-2')
+        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
+        inter = self.intertree_class(tree1, tree2)
+        self.assertTrue(inter.file_content_matches('file-id-1', 'file-id-2'))
+
+    def test_different_contents_and_same_verifier(self):
+        tree1 = self.make_branch_and_tree('1')
+        tree2 = self.make_to_branch_and_tree('2')
+        self.build_tree_contents([
+            ('1/file', 'apples'),
+            ('2/file', 'oranges'),
+            ])
+        tree1.add('file', 'file-id-1')
+        tree2.add('file', 'file-id-2')
+        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
+        inter = self.intertree_class(tree1, tree2)
+        self.assertFalse(inter.file_content_matches('file-id-1', 'file-id-2'))

=== modified file 'bzrlib/tests/per_tree/test_tree.py'
--- a/bzrlib/tests/per_tree/test_tree.py	2011-06-14 02:21:41 +0000
+++ b/bzrlib/tests/per_tree/test_tree.py	2011-08-05 13:34:40 +0000
@@ -303,3 +303,23 @@
         self.addCleanup(tree.unlock)
         expected = osutils.sha_strings('file content')
         self.assertEqual(expected, tree.get_file_sha1('file-id'))
+
+
+class TestGetFileVerifier(TestCaseWithTree):
+
+    def test_get_file_verifier(self):
+        work_tree = self.make_branch_and_tree('tree')
+        self.build_tree_contents([
+            ('tree/file1', 'file content'),
+            ('tree/file2', 'file content')])
+        work_tree.add(['file1', 'file2'], ['file-id-1', 'file-id-2'])
+        tree = self._convert_tree(work_tree)
+        tree.lock_read()
+        self.addCleanup(tree.unlock)
+        (kind, data) = tree.get_file_verifier('file-id-1')
+        self.assertEquals(
+            tree.get_file_verifier('file-id-1'),
+            tree.get_file_verifier('file-id-2'))
+        if kind == "SHA1":
+            expected = osutils.sha_strings('file content')
+            self.assertEqual(expected, data)

=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py	2011-07-13 15:21:48 +0000
+++ b/bzrlib/transform.py	2011-08-05 13:34:40 +0000
@@ -2258,6 +2258,18 @@
         else:
             return None
 
+    def get_file_verifier(self, file_id, path=None, stat_value=None):
+        trans_id = self._transform.trans_id_file_id(file_id)
+        kind = self._transform._new_contents.get(trans_id)
+        if kind is None:
+            return self._transform._tree.get_file_verifier(file_id)
+        if kind == 'file':
+            fileobj = self.get_file(file_id)
+            try:
+                return ("SHA1", sha_file(fileobj))
+            finally:
+                fileobj.close()
+
     def get_file_sha1(self, file_id, path=None, stat_value=None):
         trans_id = self._transform.trans_id_file_id(file_id)
         kind = self._transform._new_contents.get(trans_id)

=== modified file 'bzrlib/tree.py'
--- a/bzrlib/tree.py	2011-07-04 20:17:44 +0000
+++ b/bzrlib/tree.py	2011-08-05 13:34:40 +0000
@@ -300,9 +300,27 @@
         """
         return osutils.split_lines(self.get_file_text(file_id, path))
 
+    def get_file_verifier(self, file_id, path=None, stat_value=None):
+        """Return a verifier for a file.
+
+        The default implementation returns a sha1.
+
+        :param file_id: The handle for this file.
+        :param path: The path that this file can be found at.
+            These must point to the same object.
+        :param stat_value: Optional stat value for the object
+        :return: Tuple with verifier name and verifier data
+        """
+        return ("SHA1", self.get_file_sha1(file_id, path=path,
+            stat_value=stat_value))
+
     def get_file_sha1(self, file_id, path=None, stat_value=None):
         """Return the SHA1 file for a file.
 
+        :note: callers should use get_file_verifier instead
+            where possible, as the underlying repository implementation may
+            have quicker access to a non-sha1 verifier.
+
         :param file_id: The handle for this file.
         :param path: The path that this file can be found at.
             These must point to the same object.
@@ -955,8 +973,8 @@
         if source_kind != target_kind:
             changed_content = True
         elif source_kind == 'file':
-            if (self.source.get_file_sha1(file_id, source_path, source_stat) !=
-                self.target.get_file_sha1(file_id, target_path, target_stat)):
+            if not self.file_content_matches(file_id, file_id, source_path,
+                    target_path, source_stat, target_stat):
                 changed_content = True
         elif source_kind == 'symlink':
             if (self.source.get_symlink_target(file_id) !=
@@ -1275,6 +1293,40 @@
                     changed_file_ids.add(result[0])
                     yield result
 
+    @needs_read_lock
+    def file_content_matches(self, source_file_id, target_file_id,
+            source_path=None, target_path=None, source_stat=None, target_stat=None):
+        """Check if two files are the same in the source and target trees.
+
+        This only checks that the contents of the files are the same,
+        it does not touch anything else.
+
+        :param source_file_id: File id of the file in the source tree
+        :param target_file_id: File id of the file in the target tree
+        :param source_path: Path of the file in the source tree
+        :param target_path: Path of the file in the target tree
+        :param source_stat: Optional stat value of the file in the source tree
+        :param target_stat: Optional stat value of the file in the target tree
+        :return: Boolean indicating whether the files have the same contents
+        """
+        source_verifier_kind, source_verifier_data = self.source.get_file_verifier(
+            source_file_id, source_path, source_stat)
+        target_verifier_kind, target_verifier_data = self.target.get_file_verifier(
+            target_file_id, target_path, target_stat)
+        if source_verifier_kind == target_verifier_kind:
+            return (source_verifier_data == target_verifier_data)
+        # Fall back to SHA1 for now
+        if source_verifier_kind != "SHA1":
+            source_sha1 = self.source.get_file_sha1(source_file_id,
+                    source_path, source_stat)
+        else:
+            source_sha1 = source_verifier_data
+        if target_verifier_kind != "SHA1":
+            target_sha1 = self.target.get_file_sha1(target_file_id,
+                    target_path, target_stat)
+        else:
+            target_sha1 = target_verifier_data
+        return (source_sha1 == target_sha1)
 
 InterTree.register_optimiser(InterTree)
 

=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py	2011-06-28 17:25:26 +0000
+++ b/bzrlib/workingtree.py	2011-08-04 13:30:30 +0000
@@ -595,10 +595,6 @@
             else:
                 return None
 
-    def get_file_sha1(self, file_id, path=None, stat_value=None):
-        # FIXME: Shouldn't this be in Tree?
-        raise NotImplementedError(self.get_file_sha1)
-
     @needs_tree_write_lock
     def _gather_kinds(self, files, kinds):
         """See MutableTree._gather_kinds."""

=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt	2011-08-04 14:41:49 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt	2011-08-05 16:51:01 +0000
@@ -97,6 +97,14 @@
   have been added that only support opening from a path or a URL,
   unlike ``get_transport``. (Jelmer Vernooij)
 
+* New method ``Tree.get_file_verifier`` which allows tree implementations
+  to return non-sha1 checksums to verify files.
+  (Jelmer Vernooij, #720831)
+
+* New method ``InterTree.file_content_matches`` which checks that
+  two files in different trees have the same contents.
+  (Jelmer Vernooij)
+
 * Remove ``AtomicFile.closed`` which has been deprecated in bzr 0.10.
   (Vincent Ladeuil)
 




More information about the bazaar-commits mailing list