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