Rev 5830: (jelmer) Split WorkingTree3 out into a separate file. (Jelmer Vernooij) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu May 5 03:14:28 UTC 2011


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

------------------------------------------------------------
revno: 5830 [merge]
revision-id: pqm at pqm.ubuntu.com-20110505031425-f1pyxrpf6wu8jads
parent: pqm at pqm.ubuntu.com-20110505004149-54ffs4bzdy90dkh9
parent: jelmer at samba.org-20110505015800-89t3un3ha2ktdohp
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2011-05-05 03:14:25 +0000
message:
  (jelmer) Split WorkingTree3 out into a separate file. (Jelmer Vernooij)
added:
  bzrlib/workingtree_3.py        workingtree_3.py-20110503234428-nwa1nw7zfdd0hrw8-1
modified:
  bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
  bzrlib/plugins/weave_fmt/__init__.py __init__.py-20110111033945-rpdtstq3e5w484wd-2
  bzrlib/plugins/weave_fmt/bzrdir.py bzrdir_weave.py-20110310114200-ndz63gzqll03nf4z-1
  bzrlib/plugins/weave_fmt/workingtree.py workingtree_2.py-20110303111903-b6uksp28mf3oo3vp-1
  bzrlib/tests/per_intertree/__init__.py __init__.py-20060724101752-09ysswo1a92uqyoz-3
  bzrlib/tests/test_bzrdir.py    test_bzrdir.py-20060131065654-deba40eef51cf220
  bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
  bzrlib/tests/test_workingtree.py testworkingtree.py-20051004024258-b88d0fe8f101d468
  bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
  bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2011-05-03 23:16:56 +0000
+++ b/bzrlib/bzrdir.py	2011-05-04 14:54:13 +0000
@@ -49,7 +49,7 @@
     ui,
     urlutils,
     win32utils,
-    workingtree,
+    workingtree_3,
     workingtree_4,
     )
 from bzrlib.repofmt import knitpack_repo
@@ -1883,7 +1883,7 @@
         else:
             # TODO: conversions of Branch and Tree should be done by
             # InterXFormat lookups
-            if (isinstance(tree, workingtree.WorkingTree3) and
+            if (isinstance(tree, workingtree_3.WorkingTree3) and
                 not isinstance(tree, workingtree_4.DirStateWorkingTree) and
                 isinstance(self.target_format.workingtree_format,
                     workingtree_4.DirStateWorkingTreeFormat)):
@@ -2110,7 +2110,7 @@
     'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
     'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
     branch_format='bzrlib.branch.BzrBranchFormat5',
-    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
+    tree_format='bzrlib.workingtree_3.WorkingTreeFormat3',
     hidden=True,
     deprecated=True)
 register_metadir(controldir.format_registry, 'dirstate',

=== modified file 'bzrlib/plugins/weave_fmt/__init__.py'
--- a/bzrlib/plugins/weave_fmt/__init__.py	2011-03-13 00:08:28 +0000
+++ b/bzrlib/plugins/weave_fmt/__init__.py	2011-05-04 22:23:20 +0000
@@ -82,7 +82,7 @@
     'bzrlib.plugins.weave_fmt.repository.RepositoryFormat7',
     'Transitional format in 0.8.  Slower than knit.',
     branch_format='bzrlib.branch.BzrBranchFormat5',
-    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
+    tree_format='bzrlib.workingtree_3.WorkingTreeFormat3',
     hidden=True,
     deprecated=True)
 

=== modified file 'bzrlib/plugins/weave_fmt/bzrdir.py'
--- a/bzrlib/plugins/weave_fmt/bzrdir.py	2011-03-23 13:26:59 +0000
+++ b/bzrlib/plugins/weave_fmt/bzrdir.py	2011-05-04 22:23:20 +0000
@@ -599,7 +599,7 @@
                 if name in bzrcontents:
                     self.bzrdir.transport.delete(name)
         else:
-            from bzrlib.workingtree import WorkingTreeFormat3
+            from bzrlib.workingtree_3 import WorkingTreeFormat3
             self.step('Upgrading working tree')
             self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
             self.make_lock('checkout')

=== modified file 'bzrlib/plugins/weave_fmt/workingtree.py'
--- a/bzrlib/plugins/weave_fmt/workingtree.py	2011-04-09 22:51:57 +0000
+++ b/bzrlib/plugins/weave_fmt/workingtree.py	2011-05-04 22:38:14 +0000
@@ -227,4 +227,8 @@
                              file_id=self.path2id(conflicted)))
         return conflicts
 
+    def set_conflicts(self, arg):
+        raise errors.UnsupportedOperation(self.set_conflicts, self)
 
+    def add_conflicts(self, arg):
+        raise errors.UnsupportedOperation(self.add_conflicts, self)

=== modified file 'bzrlib/tests/per_intertree/__init__.py'
--- a/bzrlib/tests/per_intertree/__init__.py	2010-11-22 03:35:24 +0000
+++ b/bzrlib/tests/per_intertree/__init__.py	2011-05-03 23:54:46 +0000
@@ -24,7 +24,6 @@
 
 import bzrlib
 from bzrlib import (
-    errors,
     revisiontree,
     tests,
     )
@@ -39,9 +38,7 @@
     TestCaseWithTree,
     )
 from bzrlib.tree import InterTree
-from bzrlib.workingtree import (
-    WorkingTreeFormat3,
-    )
+from bzrlib.workingtree_3 import WorkingTreeFormat3
 from bzrlib.workingtree_4 import WorkingTreeFormat4
 
 

=== modified file 'bzrlib/tests/test_bzrdir.py'
--- a/bzrlib/tests/test_bzrdir.py	2011-04-15 07:01:22 +0000
+++ b/bzrlib/tests/test_bzrdir.py	2011-05-05 01:58:00 +0000
@@ -38,7 +38,8 @@
     transport as _mod_transport,
     urlutils,
     win32utils,
-    workingtree,
+    workingtree_3,
+    workingtree_4,
     )
 import bzrlib.branch
 from bzrlib.errors import (
@@ -807,7 +808,7 @@
         branch = self.make_branch('branch', format='knit')
         format = branch.bzrdir.cloning_metadir()
         self.assertIsInstance(format.workingtree_format,
-            workingtree.WorkingTreeFormat3)
+            workingtree_4.WorkingTreeFormat6)
 
     def test_sprout_recursive_treeless(self):
         tree = self.make_branch_and_tree('tree1',
@@ -963,7 +964,7 @@
         checkout_base = t.clone('checkout').base
         self.assertEqual(checkout_base, dir.get_workingtree_transport(None).base)
         self.assertEqual(checkout_base,
-                         dir.get_workingtree_transport(workingtree.WorkingTreeFormat3()).base)
+                         dir.get_workingtree_transport(workingtree_3.WorkingTreeFormat3()).base)
 
     def test_meta1dir_uses_lockdir(self):
         """Meta1 format uses a LockDir to guard the whole directory, not a file."""
@@ -1057,7 +1058,7 @@
         my_bzrdir = bzrdir.BzrDir.open(self.get_url('branch-knit2'))
         checkout_format = my_bzrdir.checkout_metadir()
         self.assertIsInstance(checkout_format.workingtree_format,
-                              workingtree.WorkingTreeFormat3)
+                              workingtree_4.WorkingTreeFormat4)
 
 
 class TestHTTPRedirections(object):

=== modified file 'bzrlib/tests/test_selftest.py'
--- a/bzrlib/tests/test_selftest.py	2011-05-04 16:17:27 +0000
+++ b/bzrlib/tests/test_selftest.py	2011-05-05 01:58:00 +0000
@@ -52,6 +52,7 @@
     tests,
     transport,
     workingtree,
+    workingtree_3,
     workingtree_4,
     )
 from bzrlib.repofmt import (
@@ -340,7 +341,7 @@
         server1 = "a"
         server2 = "b"
         formats = [workingtree_4.WorkingTreeFormat4(),
-                   workingtree.WorkingTreeFormat3(),]
+                   workingtree_3.WorkingTreeFormat3(),]
         scenarios = make_scenarios(server1, server2, formats)
         self.assertEqual([
             ('WorkingTreeFormat4',
@@ -377,7 +378,7 @@
         server1 = "a"
         server2 = "b"
         formats = [workingtree_4.WorkingTreeFormat4(),
-                   workingtree.WorkingTreeFormat3(),]
+                   workingtree_3.WorkingTreeFormat3(),]
         scenarios = make_scenarios(server1, server2, formats)
         self.assertEqual(7, len(scenarios))
         default_wt_format = workingtree.format_registry.get_default()
@@ -454,7 +455,7 @@
         from bzrlib.tests.per_intertree import (
             make_scenarios,
             )
-        from bzrlib.workingtree import WorkingTreeFormat3
+        from bzrlib.workingtree_3 import WorkingTreeFormat3
         from bzrlib.workingtree_4 import WorkingTreeFormat4
         input_test = TestInterTreeScenarios(
             "test_scenarios")

=== modified file 'bzrlib/tests/test_workingtree.py'
--- a/bzrlib/tests/test_workingtree.py	2011-05-03 23:16:56 +0000
+++ b/bzrlib/tests/test_workingtree.py	2011-05-05 01:58:00 +0000
@@ -22,6 +22,8 @@
     symbol_versioning,
     transport,
     workingtree,
+    workingtree_3,
+    workingtree_4,
     )
 from bzrlib.lockdir import LockDir
 from bzrlib.mutabletree import needs_tree_write_lock
@@ -62,8 +64,8 @@
 
     def test_get_set_default_format(self):
         old_format = workingtree.format_registry.get_default()
-        # default is 3
-        self.assertTrue(isinstance(old_format, workingtree.WorkingTreeFormat3))
+        # default is 6
+        self.assertTrue(isinstance(old_format, workingtree_4.WorkingTreeFormat6))
         workingtree.format_registry.set_default(SampleTreeFormat())
         try:
             # the default branch format is used by the meta dir format
@@ -79,11 +81,11 @@
 
     def test_get_set_default_format_by_key(self):
         old_format = workingtree.format_registry.get_default()
-        # default is 3
+        # default is 6
         format = SampleTreeFormat()
         workingtree.format_registry.register(format)
         self.addCleanup(workingtree.format_registry.remove, format)
-        self.assertTrue(isinstance(old_format, workingtree.WorkingTreeFormat3))
+        self.assertTrue(isinstance(old_format, workingtree_4.WorkingTreeFormat6))
         workingtree.format_registry.set_default_key(format.get_format_string())
         try:
             # the default branch format is used by the meta dir format
@@ -191,7 +193,7 @@
             t = transport.get_transport(url)
             found_format = workingtree.WorkingTreeFormat.find_format(dir)
             self.assertIsInstance(found_format, format.__class__)
-        check_format(workingtree.WorkingTreeFormat3(), "bar")
+        check_format(workingtree_3.WorkingTreeFormat3(), "bar")
 
     def test_find_format_no_tree(self):
         dir = bzrdir.BzrDirMetaFormat1().initialize('.')
@@ -275,7 +277,7 @@
         control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
         control.create_repository()
         control.create_branch()
-        tree = workingtree.WorkingTreeFormat3().initialize(control)
+        tree = workingtree_3.WorkingTreeFormat3().initialize(control)
         # we want:
         # format 'Bazaar-NG Working Tree format 3'
         # inventory = blank inventory
@@ -309,7 +311,7 @@
         repo = dir.create_repository()
         branch = dir.create_branch()
         try:
-            tree = workingtree.WorkingTreeFormat3().initialize(dir)
+            tree = workingtree_3.WorkingTreeFormat3().initialize(dir)
         except errors.NotLocalUrl:
             raise TestSkipped('Not a local URL')
         self.assertIsDirectory('.bzr', t)
@@ -326,7 +328,7 @@
         control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
         control.create_repository()
         control.create_branch()
-        tree = workingtree.WorkingTreeFormat3().initialize(control)
+        tree = workingtree_3.WorkingTreeFormat3().initialize(control)
         tree._transport.delete("pending-merges")
         self.assertEqual([], tree.get_parent_ids())
 

=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py	2011-05-04 16:17:27 +0000
+++ b/bzrlib/workingtree.py	2011-05-04 22:23:20 +0000
@@ -73,8 +73,6 @@
 from bzrlib import symbol_versioning
 from bzrlib.decorators import needs_read_lock, needs_write_lock
 from bzrlib.lock import LogicalLockResult
-from bzrlib.lockable_files import LockableFiles
-from bzrlib.lockdir import LockDir
 import bzrlib.mutabletree
 from bzrlib.mutabletree import needs_tree_write_lock
 from bzrlib import osutils
@@ -89,7 +87,6 @@
     supports_executable,
     )
 from bzrlib.trace import mutter, note
-from bzrlib.transport.local import LocalTransport
 from bzrlib.revision import CURRENT_REVISION
 from bzrlib.symbol_versioning import (
     deprecated_passed,
@@ -2015,6 +2012,35 @@
         inventory.revision_id = revision_id
         return xml7.serializer_v7.write_inventory_to_string(inventory)
 
+    @needs_tree_write_lock
+    def set_conflicts(self, conflicts):
+        self._put_rio('conflicts', conflicts.to_stanzas(),
+                      CONFLICT_HEADER_1)
+
+    @needs_tree_write_lock
+    def add_conflicts(self, new_conflicts):
+        conflict_set = set(self.conflicts())
+        conflict_set.update(set(list(new_conflicts)))
+        self.set_conflicts(_mod_conflicts.ConflictList(sorted(conflict_set,
+                                       key=_mod_conflicts.Conflict.sort_key)))
+
+    @needs_read_lock
+    def conflicts(self):
+        try:
+            confile = self._transport.get('conflicts')
+        except errors.NoSuchFile:
+            return _mod_conflicts.ConflictList()
+        try:
+            try:
+                if confile.next() != CONFLICT_HEADER_1 + '\n':
+                    raise errors.ConflictFormatError()
+            except StopIteration:
+                raise errors.ConflictFormatError()
+            reader = _mod_rio.RioReader(confile)
+            return _mod_conflicts.ConflictList.from_stanzas(reader)
+        finally:
+            confile.close()
+
     def read_basis_inventory(self):
         """Read the cached basis inventory."""
         path = self._basis_inventory_name()
@@ -2883,85 +2909,6 @@
                     pending.append(dir)
 
 
-class WorkingTree3(InventoryWorkingTree):
-    """This is the Format 3 working tree.
-
-    This differs from the base WorkingTree by:
-     - having its own file lock
-     - having its own last-revision property.
-
-    This is new in bzr 0.8
-    """
-
-    @needs_read_lock
-    def _last_revision(self):
-        """See Mutable.last_revision."""
-        try:
-            return self._transport.get_bytes('last-revision')
-        except errors.NoSuchFile:
-            return _mod_revision.NULL_REVISION
-
-    def _change_last_revision(self, revision_id):
-        """See WorkingTree._change_last_revision."""
-        if revision_id is None or revision_id == _mod_revision.NULL_REVISION:
-            try:
-                self._transport.delete('last-revision')
-            except errors.NoSuchFile:
-                pass
-            return False
-        else:
-            self._transport.put_bytes('last-revision', revision_id,
-                mode=self.bzrdir._get_file_mode())
-            return True
-
-    def _get_check_refs(self):
-        """Return the references needed to perform a check of this tree."""
-        return [('trees', self.last_revision())]
-
-    @needs_tree_write_lock
-    def set_conflicts(self, conflicts):
-        self._put_rio('conflicts', conflicts.to_stanzas(),
-                      CONFLICT_HEADER_1)
-
-    @needs_tree_write_lock
-    def add_conflicts(self, new_conflicts):
-        conflict_set = set(self.conflicts())
-        conflict_set.update(set(list(new_conflicts)))
-        self.set_conflicts(_mod_conflicts.ConflictList(sorted(conflict_set,
-                                       key=_mod_conflicts.Conflict.sort_key)))
-
-    @needs_read_lock
-    def conflicts(self):
-        try:
-            confile = self._transport.get('conflicts')
-        except errors.NoSuchFile:
-            return _mod_conflicts.ConflictList()
-        try:
-            try:
-                if confile.next() != CONFLICT_HEADER_1 + '\n':
-                    raise errors.ConflictFormatError()
-            except StopIteration:
-                raise errors.ConflictFormatError()
-            reader = _mod_rio.RioReader(confile)
-            return _mod_conflicts.ConflictList.from_stanzas(reader)
-        finally:
-            confile.close()
-
-    def unlock(self):
-        # do non-implementation specific cleanup
-        self._cleanup()
-        if self._control_files._lock_count == 1:
-            # _inventory_is_modified is always False during a read lock.
-            if self._inventory_is_modified:
-                self.flush()
-            self._write_hashcache_if_dirty()
-        # reverse order of locking.
-        try:
-            return self._control_files.unlock()
-        finally:
-            self.branch.unlock()
-
-
 class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
     """Registry for working tree formats."""
 
@@ -3131,144 +3078,12 @@
         format_registry.remove(format)
 
 
-class WorkingTreeFormat3(WorkingTreeFormat):
-    """The second working tree format updated to record a format marker.
-
-    This format:
-        - exists within a metadir controlling .bzr
-        - includes an explicit version marker for the workingtree control
-          files, separate from the BzrDir format
-        - modifies the hash cache format
-        - is new in bzr 0.8
-        - uses a LockDir to guard access for writes.
-    """
-
-    upgrade_recommended = True
-
-    missing_parent_conflicts = True
-
-    def get_format_string(self):
-        """See WorkingTreeFormat.get_format_string()."""
-        return "Bazaar-NG Working Tree format 3"
-
-    def get_format_description(self):
-        """See WorkingTreeFormat.get_format_description()."""
-        return "Working tree format 3"
-
-    _lock_file_name = 'lock'
-    _lock_class = LockDir
-
-    _tree_class = WorkingTree3
-
-    def __get_matchingbzrdir(self):
-        return bzrdir.BzrDirMetaFormat1()
-
-    _matchingbzrdir = property(__get_matchingbzrdir)
-
-    def _open_control_files(self, a_bzrdir):
-        transport = a_bzrdir.get_workingtree_transport(None)
-        return LockableFiles(transport, self._lock_file_name,
-                             self._lock_class)
-
-    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
-                   accelerator_tree=None, hardlink=False):
-        """See WorkingTreeFormat.initialize().
-
-        :param revision_id: if supplied, create a working tree at a different
-            revision than the branch is at.
-        :param accelerator_tree: A tree which can be used for retrieving file
-            contents more quickly than the revision tree, i.e. a workingtree.
-            The revision tree will be used for cases where accelerator_tree's
-            content is different.
-        :param hardlink: If true, hard-link files from accelerator_tree,
-            where possible.
-        """
-        if not isinstance(a_bzrdir.transport, LocalTransport):
-            raise errors.NotLocalUrl(a_bzrdir.transport.base)
-        transport = a_bzrdir.get_workingtree_transport(self)
-        control_files = self._open_control_files(a_bzrdir)
-        control_files.create_lock()
-        control_files.lock_write()
-        transport.put_bytes('format', self.get_format_string(),
-            mode=a_bzrdir._get_file_mode())
-        if from_branch is not None:
-            branch = from_branch
-        else:
-            branch = a_bzrdir.open_branch()
-        if revision_id is None:
-            revision_id = _mod_revision.ensure_null(branch.last_revision())
-        # WorkingTree3 can handle an inventory which has a unique root id.
-        # as of bzr 0.12. However, bzr 0.11 and earlier fail to handle
-        # those trees. And because there isn't a format bump inbetween, we
-        # are maintaining compatibility with older clients.
-        # inv = Inventory(root_id=gen_root_id())
-        inv = self._initial_inventory()
-        wt = self._tree_class(a_bzrdir.root_transport.local_abspath('.'),
-                         branch,
-                         inv,
-                         _internal=True,
-                         _format=self,
-                         _bzrdir=a_bzrdir,
-                         _control_files=control_files)
-        wt.lock_tree_write()
-        try:
-            basis_tree = branch.repository.revision_tree(revision_id)
-            # only set an explicit root id if there is one to set.
-            if basis_tree.inventory.root is not None:
-                wt.set_root_id(basis_tree.get_root_id())
-            if revision_id == _mod_revision.NULL_REVISION:
-                wt.set_parent_trees([])
-            else:
-                wt.set_parent_trees([(revision_id, basis_tree)])
-            transform.build_tree(basis_tree, wt)
-        finally:
-            # Unlock in this order so that the unlock-triggers-flush in
-            # WorkingTree is given a chance to fire.
-            control_files.unlock()
-            wt.unlock()
-        return wt
-
-    def _initial_inventory(self):
-        return inventory.Inventory()
-
-    def __init__(self):
-        super(WorkingTreeFormat3, self).__init__()
-
-    def open(self, a_bzrdir, _found=False):
-        """Return the WorkingTree object for a_bzrdir
-
-        _found is a private parameter, do not use it. It is used to indicate
-               if format probing has already been done.
-        """
-        if not _found:
-            # we are being called directly and must probe.
-            raise NotImplementedError
-        if not isinstance(a_bzrdir.transport, LocalTransport):
-            raise errors.NotLocalUrl(a_bzrdir.transport.base)
-        wt = self._open(a_bzrdir, self._open_control_files(a_bzrdir))
-        return wt
-
-    def _open(self, a_bzrdir, control_files):
-        """Open the tree itself.
-
-        :param a_bzrdir: the dir for the tree.
-        :param control_files: the control files for the tree.
-        """
-        return self._tree_class(a_bzrdir.root_transport.local_abspath('.'),
-                                _internal=True,
-                                _format=self,
-                                _bzrdir=a_bzrdir,
-                                _control_files=control_files)
-
-    def __str__(self):
-        return self.get_format_string()
-
-
 format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
     "bzrlib.workingtree_4", "WorkingTreeFormat4")
 format_registry.register_lazy("Bazaar Working Tree Format 5 (bzr 1.11)\n",
     "bzrlib.workingtree_4", "WorkingTreeFormat5")
 format_registry.register_lazy("Bazaar Working Tree Format 6 (bzr 1.14)\n",
     "bzrlib.workingtree_4", "WorkingTreeFormat6")
-format_registry.register(WorkingTreeFormat3())
+format_registry.register_lazy("Bazaar-NG Working Tree format 3",
+    "bzrlib.workingtree_3", "WorkingTreeFormat3")
 format_registry.set_default_key("Bazaar Working Tree Format 6 (bzr 1.14)\n")

=== added file 'bzrlib/workingtree_3.py'
--- a/bzrlib/workingtree_3.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/workingtree_3.py	2011-05-03 23:54:46 +0000
@@ -0,0 +1,212 @@
+# 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
+# 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
+
+"""WorkingTree3 format and implementation.
+
+"""
+
+from bzrlib import (
+    bzrdir,
+    errors,
+    inventory,
+    revision as _mod_revision,
+    transform,
+    )
+from bzrlib.decorators import (
+    needs_read_lock,
+    )
+from bzrlib.lockable_files import LockableFiles
+from bzrlib.lockdir import LockDir
+from bzrlib.transport.local import LocalTransport
+from bzrlib.workingtree import (
+    InventoryWorkingTree,
+    WorkingTreeFormat,
+    )
+
+class WorkingTree3(InventoryWorkingTree):
+    """This is the Format 3 working tree.
+
+    This differs from the base WorkingTree by:
+     - having its own file lock
+     - having its own last-revision property.
+
+    This is new in bzr 0.8
+    """
+
+    @needs_read_lock
+    def _last_revision(self):
+        """See Mutable.last_revision."""
+        try:
+            return self._transport.get_bytes('last-revision')
+        except errors.NoSuchFile:
+            return _mod_revision.NULL_REVISION
+
+    def _change_last_revision(self, revision_id):
+        """See WorkingTree._change_last_revision."""
+        if revision_id is None or revision_id == _mod_revision.NULL_REVISION:
+            try:
+                self._transport.delete('last-revision')
+            except errors.NoSuchFile:
+                pass
+            return False
+        else:
+            self._transport.put_bytes('last-revision', revision_id,
+                mode=self.bzrdir._get_file_mode())
+            return True
+
+    def _get_check_refs(self):
+        """Return the references needed to perform a check of this tree."""
+        return [('trees', self.last_revision())]
+
+    def unlock(self):
+        # do non-implementation specific cleanup
+        self._cleanup()
+        if self._control_files._lock_count == 1:
+            # _inventory_is_modified is always False during a read lock.
+            if self._inventory_is_modified:
+                self.flush()
+            self._write_hashcache_if_dirty()
+        # reverse order of locking.
+        try:
+            return self._control_files.unlock()
+        finally:
+            self.branch.unlock()
+
+
+class WorkingTreeFormat3(WorkingTreeFormat):
+    """The second working tree format updated to record a format marker.
+
+    This format:
+        - exists within a metadir controlling .bzr
+        - includes an explicit version marker for the workingtree control
+          files, separate from the BzrDir format
+        - modifies the hash cache format
+        - is new in bzr 0.8
+        - uses a LockDir to guard access for writes.
+    """
+
+    upgrade_recommended = True
+
+    missing_parent_conflicts = True
+
+    def get_format_string(self):
+        """See WorkingTreeFormat.get_format_string()."""
+        return "Bazaar-NG Working Tree format 3"
+
+    def get_format_description(self):
+        """See WorkingTreeFormat.get_format_description()."""
+        return "Working tree format 3"
+
+    _tree_class = WorkingTree3
+
+    def __get_matchingbzrdir(self):
+        return bzrdir.BzrDirMetaFormat1()
+
+    _matchingbzrdir = property(__get_matchingbzrdir)
+
+    def _open_control_files(self, a_bzrdir):
+        transport = a_bzrdir.get_workingtree_transport(None)
+        return LockableFiles(transport, 'lock', LockDir)
+
+    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
+                   accelerator_tree=None, hardlink=False):
+        """See WorkingTreeFormat.initialize().
+
+        :param revision_id: if supplied, create a working tree at a different
+            revision than the branch is at.
+        :param accelerator_tree: A tree which can be used for retrieving file
+            contents more quickly than the revision tree, i.e. a workingtree.
+            The revision tree will be used for cases where accelerator_tree's
+            content is different.
+        :param hardlink: If true, hard-link files from accelerator_tree,
+            where possible.
+        """
+        if not isinstance(a_bzrdir.transport, LocalTransport):
+            raise errors.NotLocalUrl(a_bzrdir.transport.base)
+        transport = a_bzrdir.get_workingtree_transport(self)
+        control_files = self._open_control_files(a_bzrdir)
+        control_files.create_lock()
+        control_files.lock_write()
+        transport.put_bytes('format', self.get_format_string(),
+            mode=a_bzrdir._get_file_mode())
+        if from_branch is not None:
+            branch = from_branch
+        else:
+            branch = a_bzrdir.open_branch()
+        if revision_id is None:
+            revision_id = _mod_revision.ensure_null(branch.last_revision())
+        # WorkingTree3 can handle an inventory which has a unique root id.
+        # as of bzr 0.12. However, bzr 0.11 and earlier fail to handle
+        # those trees. And because there isn't a format bump inbetween, we
+        # are maintaining compatibility with older clients.
+        # inv = Inventory(root_id=gen_root_id())
+        inv = self._initial_inventory()
+        wt = self._tree_class(a_bzrdir.root_transport.local_abspath('.'),
+                         branch,
+                         inv,
+                         _internal=True,
+                         _format=self,
+                         _bzrdir=a_bzrdir,
+                         _control_files=control_files)
+        wt.lock_tree_write()
+        try:
+            basis_tree = branch.repository.revision_tree(revision_id)
+            # only set an explicit root id if there is one to set.
+            if basis_tree.inventory.root is not None:
+                wt.set_root_id(basis_tree.get_root_id())
+            if revision_id == _mod_revision.NULL_REVISION:
+                wt.set_parent_trees([])
+            else:
+                wt.set_parent_trees([(revision_id, basis_tree)])
+            transform.build_tree(basis_tree, wt)
+        finally:
+            # Unlock in this order so that the unlock-triggers-flush in
+            # WorkingTree is given a chance to fire.
+            control_files.unlock()
+            wt.unlock()
+        return wt
+
+    def _initial_inventory(self):
+        return inventory.Inventory()
+
+    def open(self, a_bzrdir, _found=False):
+        """Return the WorkingTree object for a_bzrdir
+
+        _found is a private parameter, do not use it. It is used to indicate
+               if format probing has already been done.
+        """
+        if not _found:
+            # we are being called directly and must probe.
+            raise NotImplementedError
+        if not isinstance(a_bzrdir.transport, LocalTransport):
+            raise errors.NotLocalUrl(a_bzrdir.transport.base)
+        wt = self._open(a_bzrdir, self._open_control_files(a_bzrdir))
+        return wt
+
+    def _open(self, a_bzrdir, control_files):
+        """Open the tree itself.
+
+        :param a_bzrdir: the dir for the tree.
+        :param control_files: the control files for the tree.
+        """
+        return self._tree_class(a_bzrdir.root_transport.local_abspath('.'),
+                                _internal=True,
+                                _format=self,
+                                _bzrdir=a_bzrdir,
+                                _control_files=control_files)
+
+    def __str__(self):
+        return self.get_format_string()

=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py	2011-04-21 00:41:42 +0000
+++ b/bzrlib/workingtree_4.py	2011-05-03 23:54:46 +0000
@@ -34,6 +34,7 @@
 from bzrlib import (
     bzrdir,
     cache_utf8,
+    conflicts as _mod_conflicts,
     debug,
     dirstate,
     errors,
@@ -51,6 +52,8 @@
 from bzrlib.decorators import needs_read_lock, needs_write_lock
 from bzrlib.inventory import Inventory, ROOT_ID, entry_factory
 from bzrlib.lock import LogicalLockResult
+from bzrlib.lockable_files import LockableFiles
+from bzrlib.lockdir import LockDir
 from bzrlib.mutabletree import needs_tree_write_lock
 from bzrlib.osutils import (
     file_kind,
@@ -65,13 +68,13 @@
     InventoryTree,
     )
 from bzrlib.workingtree import (
+    InventoryWorkingTree,
     WorkingTree,
-    WorkingTree3,
-    WorkingTreeFormat3,
+    WorkingTreeFormat,
     )
 
 
-class DirStateWorkingTree(WorkingTree3):
+class DirStateWorkingTree(InventoryWorkingTree):
 
     def __init__(self, basedir,
                  branch,
@@ -128,6 +131,10 @@
             state.add(f, file_id, kind, None, '')
         self._make_dirty(reset_inventory=True)
 
+    def _get_check_refs(self):
+        """Return the references needed to perform a check of this tree."""
+        return [('trees', self.last_revision())]
+
     def _make_dirty(self, reset_inventory):
         """Make the tree state dirty.
 
@@ -185,7 +192,7 @@
 
     def _comparison_data(self, entry, path):
         kind, executable, stat_value = \
-            WorkingTree3._comparison_data(self, entry, path)
+            WorkingTree._comparison_data(self, entry, path)
         # it looks like a plain directory, but it's really a reference -- see
         # also kind()
         if (self._repo_supports_tree_reference and kind == 'directory'
@@ -197,7 +204,7 @@
     def commit(self, message=None, revprops=None, *args, **kwargs):
         # mark the tree as dirty post commit - commit
         # can change the current versioned list by doing deletes.
-        result = WorkingTree3.commit(self, message, revprops, *args, **kwargs)
+        result = WorkingTree.commit(self, message, revprops, *args, **kwargs)
         self._make_dirty(reset_inventory=True)
         return result
 
@@ -1373,7 +1380,7 @@
 class WorkingTree4(DirStateWorkingTree):
     """This is the Format 4 working tree.
 
-    This differs from WorkingTree3 by:
+    This differs from WorkingTree by:
      - Having a consolidated internal dirstate, stored in a
        randomly-accessible sorted file on disk.
      - Not having a regular inventory attribute.  One can be synthesized
@@ -1407,10 +1414,18 @@
         return views.PathBasedViews(self)
 
 
-class DirStateWorkingTreeFormat(WorkingTreeFormat3):
+class DirStateWorkingTreeFormat(WorkingTreeFormat):
 
     missing_parent_conflicts = True
 
+    _lock_class = LockDir
+    _lock_file_name = 'lock'
+
+    def _open_control_files(self, a_bzrdir):
+        transport = a_bzrdir.get_workingtree_transport(None)
+        return LockableFiles(transport, self._lock_file_name,
+                             self._lock_class)
+
     def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
                    accelerator_tree=None, hardlink=False):
         """See WorkingTreeFormat.initialize().
@@ -1515,6 +1530,20 @@
         :param wt: the WorkingTree object
         """
 
+    def open(self, a_bzrdir, _found=False):
+        """Return the WorkingTree object for a_bzrdir
+
+        _found is a private parameter, do not use it. It is used to indicate
+               if format probing has already been done.
+        """
+        if not _found:
+            # we are being called directly and must probe.
+            raise NotImplementedError
+        if not isinstance(a_bzrdir.transport, LocalTransport):
+            raise errors.NotLocalUrl(a_bzrdir.transport.base)
+        wt = self._open(a_bzrdir, self._open_control_files(a_bzrdir))
+        return wt
+
     def _open(self, a_bzrdir, control_files):
         """Open the tree itself.
 




More information about the bazaar-commits mailing list