Rev 5766: (jameinel) TreeTransform.create_file and new_file can be passed sha1, in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Thu Apr 7 12:04:10 UTC 2011
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 5766 [merge]
revision-id: pqm at pqm.ubuntu.com-20110407120406-74kdkstr862qm9cv
parent: pqm at pqm.ubuntu.com-20110407111546-99kqi96vnk9u8qvc
parent: john at arbash-meinel.com-20110407103624-n76g6tjeqmznwdcd
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2011-04-07 12:04:06 +0000
message:
(jameinel) TreeTransform.create_file and new_file can be passed sha1,
which will trigger a call to Tree._observed_sha1,
caching the sha and stat information. (John A Meinel)
modified:
Makefile Makefile-20050805140406-d96e3498bb61c5bb
bzrlib/api.py api.py-20070626082640-35lspz7j0ys7a8ld-1
bzrlib/btree_index.py index.py-20080624222253-p0x5f92uyh5hw734-7
bzrlib/bundle/apply_bundle.py apply_changeset.py-20050620044656-dba4eb8021a36f95
bzrlib/bundle/commands.py __init__.py-20050617152058-1b6530d9ab85c11c
bzrlib/chk_map.py chk_map.py-20081001014447-ue6kkuhofvdecvxa-1
bzrlib/cmd_version_info.py __init__.py-20051228204928-697d01fdca29c99b
bzrlib/diff.py diff.py-20050309040759-26944fbbf2ebbf36
bzrlib/directory_service.py directory_service.py-20080305221044-vr2mkvlsk8jypa2y-1
bzrlib/filters/__init__.py __init__.py-20080416080515-mkxl29amuwrf6uir-2
bzrlib/foreign.py foreign.py-20081112170002-olsxmandkk8qyfuq-1
bzrlib/generate_ids.py generate_ids.py-20061102205935-z3do15ipw6m7v26u-1
bzrlib/hooks.py hooks.py-20070325015548-ix4np2q0kd8452au-1
bzrlib/ignores.py ignores.py-20060712153832-2von9l0t7p43ixsv-1
bzrlib/index.py index.py-20070712131115-lolkarso50vjr64s-1
bzrlib/lockable_files.py control_files.py-20051111201905-bb88546e799d669f
bzrlib/log.py log.py-20050505065812-c40ce11702fe5fb1
bzrlib/merge.py merge.py-20050513021216-953b65a438527106
bzrlib/merge_directive.py merge_directive.py-20070228184838-ja62280spt1g7f4x-1
bzrlib/plugins/launchpad/lp_propose.py lp_submit.py-20100120065117-penrmqruf596pui6-1
bzrlib/plugins/netrc_credential_store/__init__.py __init__.py-20081006090402-hd75m8kcrrm0vlz1-1
bzrlib/repofmt/pack_repo.py pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
bzrlib/revision.py revision.py-20050309040759-e77802c08f3999d5
bzrlib/sign_my_commits.py sign_my_commits.py-20060215152201-5a6363365180e671
bzrlib/smart/medium.py medium.py-20061103051856-rgu2huy59fkz902q-1
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
bzrlib/tests/test_workingtree_4.py test_workingtree_4.p-20070223025758-531n3tznl3zacv2o-1
bzrlib/trace.py trace.py-20050309040759-c8ed824bdcd4748a
bzrlib/transform.py transform.py-20060105172343-dd99e54394d91687
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
bzrlib/transport/local.py local_transport.py-20050711165921-9b1f142bfe480c24
bzrlib/tree.py tree.py-20050309040759-9d5f2496be663e77
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
=== modified file 'Makefile'
--- a/Makefile 2011-04-05 13:36:20 +0000
+++ b/Makefile 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/api.py'
--- a/bzrlib/api.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/api.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Canonical Ltd
+# Copyright (C) 2007, 2008, 2009, 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
=== modified file 'bzrlib/btree_index.py'
--- a/bzrlib/btree_index.py 2011-04-05 11:31:58 +0000
+++ b/bzrlib/btree_index.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2008, 2009, 2010 Canonical Ltd
+# Copyright (C) 2008-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
=== modified file 'bzrlib/bundle/apply_bundle.py'
--- a/bzrlib/bundle/apply_bundle.py 2011-04-04 23:45:23 +0000
+++ b/bzrlib/bundle/apply_bundle.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2006, 2007, 2009, 2010 Canonical Ltd
+# Copyright (C) 2005, 2006, 2007, 2009, 2010, 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
=== modified file 'bzrlib/bundle/commands.py'
--- a/bzrlib/bundle/commands.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/bundle/commands.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/chk_map.py'
--- a/bzrlib/chk_map.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/chk_map.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2008, 2009, 2010 Canonical Ltd
+# Copyright (C) 2008-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
=== modified file 'bzrlib/cmd_version_info.py'
--- a/bzrlib/cmd_version_info.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/cmd_version_info.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/diff.py'
--- a/bzrlib/diff.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/diff.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd.
+# Copyright (C) 2005-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
=== modified file 'bzrlib/directory_service.py'
--- a/bzrlib/directory_service.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/directory_service.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 Canonical Ltd
+# Copyright (C) 2008, 2009, 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
=== modified file 'bzrlib/filters/__init__.py'
--- a/bzrlib/filters/__init__.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/filters/__init__.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 Canonical Ltd
+# Copyright (C) 2008, 2009, 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
=== modified file 'bzrlib/foreign.py'
--- a/bzrlib/foreign.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/foreign.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2008, 2009, 2010 Canonical Ltd
+# Copyright (C) 2008-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
=== modified file 'bzrlib/generate_ids.py'
--- a/bzrlib/generate_ids.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/generate_ids.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
+# Copyright (C) 2006, 2007, 2009, 2010, 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
=== modified file 'bzrlib/hooks.py'
--- a/bzrlib/hooks.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/hooks.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2010 Canonical Ltd
+# Copyright (C) 2007-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
=== modified file 'bzrlib/ignores.py'
--- a/bzrlib/ignores.py 2011-03-31 15:20:57 +0000
+++ b/bzrlib/ignores.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006-2010 Canonical Ltd
+# Copyright (C) 2006-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
=== modified file 'bzrlib/index.py'
--- a/bzrlib/index.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/index.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2010 Canonical Ltd
+# Copyright (C) 2007-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
=== modified file 'bzrlib/lockable_files.py'
--- a/bzrlib/lockable_files.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/lockable_files.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2006, 2008, 2009 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/log.py'
--- a/bzrlib/log.py 2011-04-06 04:04:54 +0000
+++ b/bzrlib/log.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/merge.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/merge_directive.py'
--- a/bzrlib/merge_directive.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/merge_directive.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2010 Canonical Ltd
+# Copyright (C) 2007-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
=== modified file 'bzrlib/plugins/launchpad/lp_propose.py'
--- a/bzrlib/plugins/launchpad/lp_propose.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/plugins/launchpad/lp_propose.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Canonical Ltd
+# Copyright (C) 2010, 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
=== modified file 'bzrlib/plugins/netrc_credential_store/__init__.py'
--- a/bzrlib/plugins/netrc_credential_store/__init__.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/plugins/netrc_credential_store/__init__.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2008, 2009, 2010 Canonical Ltd
+# Copyright (C) 2008-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
=== modified file 'bzrlib/repofmt/pack_repo.py'
--- a/bzrlib/repofmt/pack_repo.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/repofmt/pack_repo.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2010 Canonical Ltd
+# Copyright (C) 2007-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
=== modified file 'bzrlib/revision.py'
--- a/bzrlib/revision.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/revision.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/sign_my_commits.py'
--- a/bzrlib/sign_my_commits.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/sign_my_commits.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
+# Copyright (C) 2006, 2007, 2009, 2010, 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
=== modified file 'bzrlib/smart/medium.py'
--- a/bzrlib/smart/medium.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/smart/medium.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006-2010 Canonical Ltd
+# Copyright (C) 2006-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
=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py 2011-04-05 11:10:25 +0000
+++ b/bzrlib/tests/test_transform.py 2011-04-05 13:25:50 +0000
@@ -93,6 +93,16 @@
self.addCleanup(transform.finalize)
return transform, transform.root
+ def get_transform_for_sha1_test(self):
+ trans, root = self.get_transform()
+ self.wt.lock_tree_write()
+ self.addCleanup(self.wt.unlock)
+ contents = ['just some content\n']
+ sha1 = osutils.sha_strings(contents)
+ # Roll back the clock
+ trans._creation_mtime = time.time() - 20.0
+ return trans, root, contents, sha1
+
def test_existing_limbo(self):
transform, root = self.get_transform()
limbo_name = transform._limbodir
@@ -161,6 +171,67 @@
transform.finalize()
transform.finalize()
+ def test_apply_informs_tree_of_observed_sha1(self):
+ trans, root, contents, sha1 = self.get_transform_for_sha1_test()
+ trans_id = trans.new_file('file1', root, contents, file_id='file1-id',
+ sha1=sha1)
+ calls = []
+ orig = self.wt._observed_sha1
+ def _observed_sha1(*args):
+ calls.append(args)
+ orig(*args)
+ self.wt._observed_sha1 = _observed_sha1
+ trans.apply()
+ self.assertEqual([(None, 'file1', trans._observed_sha1s[trans_id])],
+ calls)
+
+ def test_create_file_caches_sha1(self):
+ trans, root, contents, sha1 = self.get_transform_for_sha1_test()
+ trans_id = trans.create_path('file1', root)
+ trans.create_file(contents, trans_id, sha1=sha1)
+ st_val = osutils.lstat(trans._limbo_name(trans_id))
+ o_sha1, o_st_val = trans._observed_sha1s[trans_id]
+ self.assertEqual(o_sha1, sha1)
+ self.assertEqualStat(o_st_val, st_val)
+
+ def test__apply_insertions_updates_sha1(self):
+ trans, root, contents, sha1 = self.get_transform_for_sha1_test()
+ trans_id = trans.create_path('file1', root)
+ trans.create_file(contents, trans_id, sha1=sha1)
+ st_val = osutils.lstat(trans._limbo_name(trans_id))
+ o_sha1, o_st_val = trans._observed_sha1s[trans_id]
+ self.assertEqual(o_sha1, sha1)
+ self.assertEqualStat(o_st_val, st_val)
+ creation_mtime = trans._creation_mtime + 10.0
+ # We fake a time difference from when the file was created until now it
+ # is being renamed by using os.utime. Note that the change we actually
+ # want to see is the real ctime change from 'os.rename()', but as long
+ # as we observe a new stat value, we should be fine.
+ os.utime(trans._limbo_name(trans_id), (creation_mtime, creation_mtime))
+ trans.apply()
+ new_st_val = osutils.lstat(self.wt.abspath('file1'))
+ o_sha1, o_st_val = trans._observed_sha1s[trans_id]
+ self.assertEqual(o_sha1, sha1)
+ self.assertEqualStat(o_st_val, new_st_val)
+ self.assertNotEqual(st_val.st_mtime, new_st_val.st_mtime)
+
+ def test_new_file_caches_sha1(self):
+ trans, root, contents, sha1 = self.get_transform_for_sha1_test()
+ trans_id = trans.new_file('file1', root, contents, file_id='file1-id',
+ sha1=sha1)
+ st_val = osutils.lstat(trans._limbo_name(trans_id))
+ o_sha1, o_st_val = trans._observed_sha1s[trans_id]
+ self.assertEqual(o_sha1, sha1)
+ self.assertEqualStat(o_st_val, st_val)
+
+ def test_cancel_creation_removes_observed_sha1(self):
+ trans, root, contents, sha1 = self.get_transform_for_sha1_test()
+ trans_id = trans.new_file('file1', root, contents, file_id='file1-id',
+ sha1=sha1)
+ self.assertTrue(trans_id in trans._observed_sha1s)
+ trans.cancel_creation(trans_id)
+ self.assertFalse(trans_id in trans._observed_sha1s)
+
def test_create_files_same_timestamp(self):
transform, root = self.get_transform()
self.wt.lock_tree_write()
=== modified file 'bzrlib/tests/test_workingtree_4.py'
--- a/bzrlib/tests/test_workingtree_4.py 2011-04-05 14:00:26 +0000
+++ b/bzrlib/tests/test_workingtree_4.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2010 Canonical Ltd
+# Copyright (C) 2007-2011 Canonical Ltd
# Authors: Robert Collins <robert.collins at canonical.com>
#
# This program is free software; you can redistribute it and/or modify
=== modified file 'bzrlib/trace.py'
--- a/bzrlib/trace.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/trace.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py 2011-04-05 14:47:26 +0000
+++ b/bzrlib/transform.py 2011-04-07 10:36:24 +0000
@@ -102,6 +102,8 @@
self._new_parent = {}
# mapping of trans_id with new contents -> new file_kind
self._new_contents = {}
+ # mapping of trans_id => (sha1 of content, stat_value)
+ self._observed_sha1s = {}
# Set of trans_ids whose contents will be removed
self._removed_contents = set()
# Mapping of trans_id -> new execute-bit value
@@ -751,7 +753,7 @@
return trans_id
def new_file(self, name, parent_id, contents, file_id=None,
- executable=None):
+ executable=None, sha1=None):
"""Convenience method to create files.
name is the name of the file to create.
@@ -764,7 +766,7 @@
trans_id = self._new_entry(name, parent_id, file_id)
# TODO: rather than scheduling a set_executable call,
# have create_file create the file with the right mode.
- self.create_file(contents, trans_id)
+ self.create_file(contents, trans_id, sha1=sha1)
if executable is not None:
self.set_executability(executable, trans_id)
return trans_id
@@ -1246,16 +1248,19 @@
descendants.update(self._limbo_descendants(descendant))
return descendants
- def create_file(self, contents, trans_id, mode_id=None):
+ def create_file(self, contents, trans_id, mode_id=None, sha1=None):
"""Schedule creation of a new file.
- See also new_file.
-
- Contents is an iterator of strings, all of which will be written
- to the target destination.
-
- New file takes the permissions of any existing file with that id,
- unless mode_id is specified.
+ :seealso: new_file.
+
+ :param contents: an iterator of strings, all of which will be written
+ to the target destination.
+ :param trans_id: TreeTransform handle
+ :param mode_id: If not None, force the mode of the target file to match
+ the mode of the object referenced by mode_id.
+ Otherwise, we will try to preserve mode bits of an existing file.
+ :param sha1: If the sha1 of this content is already known, pass it in.
+ We can use it to prevent future sha1 computations.
"""
name = self._limbo_name(trans_id)
f = open(name, 'wb')
@@ -1268,12 +1273,16 @@
f.close()
os.unlink(name)
raise
-
f.writelines(contents)
finally:
f.close()
self._set_mtime(name)
self._set_mode(trans_id, mode_id, S_ISREG)
+ # It is unfortunate we have to use lstat instead of fstat, but we just
+ # used utime and chmod on the file, so we need the accurate final
+ # details.
+ if sha1 is not None:
+ self._observed_sha1s[trans_id] = (sha1, osutils.lstat(name))
def _read_file_chunks(self, trans_id):
cur_file = open(self._limbo_name(trans_id), 'rb')
@@ -1338,6 +1347,8 @@
def cancel_creation(self, trans_id):
"""Cancel the creation of new file contents."""
del self._new_contents[trans_id]
+ if trans_id in self._observed_sha1s:
+ del self._observed_sha1s[trans_id]
children = self._limbo_children.get(trans_id)
# if this is a limbo directory with children, move them before removing
# the directory
@@ -1699,6 +1710,7 @@
finally:
child_pb.finished()
self._tree.apply_inventory_delta(inventory_delta)
+ self._apply_observed_sha1s()
self._done = True
self.finalize()
return _TransformResults(modified_paths, self.rename_count)
@@ -1824,17 +1836,47 @@
raise
else:
self.rename_count += 1
+ # TODO: if trans_id in self._observed_sha1s, we should
+ # re-stat the final target, since ctime will be
+ # updated by the change.
if (trans_id in self._new_contents or
self.path_changed(trans_id)):
if trans_id in self._new_contents:
modified_paths.append(full_path)
if trans_id in self._new_executability:
self._set_executability(path, trans_id)
+ if trans_id in self._observed_sha1s:
+ o_sha1, o_st_val = self._observed_sha1s[trans_id]
+ st = osutils.lstat(full_path)
+ self._observed_sha1s[trans_id] = (o_sha1, st)
finally:
child_pb.finished()
self._new_contents.clear()
return modified_paths
+ def _apply_observed_sha1s(self):
+ """After we have finished renaming everything, update observed sha1s
+
+ This has to be done after self._tree.apply_inventory_delta, otherwise
+ it doesn't know anything about the files we are updating. Also, we want
+ to do this as late as possible, so that most entries end up cached.
+ """
+ # TODO: this doesn't update the stat information for directories. So
+ # the first 'bzr status' will still need to rewrite
+ # .bzr/checkout/dirstate. However, we at least don't need to
+ # re-read all of the files.
+ # TODO: If the operation took a while, we could do a time.sleep(3) here
+ # to allow the clock to tick over and ensure we won't have any
+ # problems. (we could observe start time, and finish time, and if
+ # it is less than eg 10% overhead, add a sleep call.)
+ paths = FinalPaths(self)
+ for trans_id, observed in self._observed_sha1s.iteritems():
+ path = paths.get_path(trans_id)
+ # We could get the file_id, but dirstate prefers to use the path
+ # anyway, and it is 'cheaper' to determine.
+ # file_id = self._new_id[trans_id]
+ self._tree._observed_sha1(None, path, observed)
+
class TransformPreview(DiskTreeTransform):
"""A TreeTransform for generating preview trees.
=== modified file 'bzrlib/transport/__init__.py'
--- a/bzrlib/transport/__init__.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/transport/__init__.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/transport/local.py'
--- a/bzrlib/transport/local.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/transport/local.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/tree.py'
--- a/bzrlib/tree.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/tree.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/ui/__init__.py'
--- a/bzrlib/ui/__init__.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/ui/__init__.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'bzrlib/ui/text.py'
--- a/bzrlib/ui/text.py 2011-04-05 01:12:15 +0000
+++ b/bzrlib/ui/text.py 2011-04-07 10:36:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-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
=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt 2011-04-06 04:04:54 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt 2011-04-07 10:36:24 +0000
@@ -42,18 +42,24 @@
.. Fixes for situations where bzr would previously crash or give incorrect
or undesirable results.
- * ``bzrlib.log._DEFAULT_REQUEST_PARAMS`` is no longer accidentally
- mutated by ``bzrlib.log._apply_log_request_defaults``. In practice
- these default values aren't relied on very often so this probably
- wasn't causing any trouble. (Andrew Bennetts)
+* ``bzrlib.log._DEFAULT_REQUEST_PARAMS`` is no longer accidentally
+ mutated by ``bzrlib.log._apply_log_request_defaults``. In practice
+ these default values aren't relied on very often so this probably
+ wasn't causing any trouble. (Andrew Bennetts)
- * Lazy hooks are now reset between test runs. (Jelmer Vernooij, #745566)
+* Lazy hooks are now reset between test runs. (Jelmer Vernooij, #745566)
* Standalone bzr.exe installation on Windows: user can put additional python
libraries into ``site-packages`` subdirectory of the installation directory,
this might be required for "installing" extra dependencies for some plugins.
(Alexander Belchenko, #743256)
+* ``TreeTransform.create_file/new_file`` can now take an optional ``sha1``
+ parameter. If supplied, when the transform is applied, it will then call
+ ``self._tree._observed_sha1`` for those files. This lets us update the
+ hash-cache for content that we create, preventing us from re-reading the
+ content in the next ``bzr status``. (John Arbash Meinel, #740932)
+
Documentation
*************
More information about the bazaar-commits
mailing list