Rev 5698: (jelmer) Move WorkingTreeFormat2 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 Mar 3 13:22:27 UTC 2011


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

------------------------------------------------------------
revno: 5698 [merge]
revision-id: pqm at pqm.ubuntu.com-20110303132224-mk3nc8youg86etw7
parent: pqm at pqm.ubuntu.com-20110303105625-rgq9al23mt151mzn
parent: jelmer at samba.org-20110303113203-vwsuztoorxn5dul8
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2011-03-03 13:22:24 +0000
message:
  (jelmer) Move WorkingTreeFormat2 into a separate file. (Jelmer Vernooij)
added:
  bzrlib/tests/test_workingtree_2.py test_workingtree_2.p-20110303111903-b6uksp28mf3oo3vp-2
  bzrlib/workingtree_2.py        workingtree_2.py-20110303111903-b6uksp28mf3oo3vp-1
modified:
  bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/test_conflicts.py test_conflicts.py-20051006031059-e2dad9bbeaa5891f
  bzrlib/tests/test_workingtree.py testworkingtree.py-20051004024258-b88d0fe8f101d468
  bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2011-03-03 10:56:25 +0000
+++ b/bzrlib/bzrdir.py	2011-03-03 11:32:03 +0000
@@ -1080,7 +1080,7 @@
         return result
 
     def _init_workingtree(self):
-        from bzrlib.workingtree import WorkingTreeFormat2
+        from bzrlib.workingtree_2 import WorkingTreeFormat2
         try:
             return WorkingTreeFormat2().initialize(self)
         except errors.NotLocalUrl:
@@ -1159,7 +1159,7 @@
         if not create_tree_if_local:
             raise errors.MustHaveWorkingTree(
                 self._format, self.root_transport.base)
-        from bzrlib.workingtree import WorkingTreeFormat2
+        from bzrlib.workingtree_2 import WorkingTreeFormat2
         self._make_tail(url)
         result = self._format._initialize_for_clone(url)
         try:
@@ -1216,7 +1216,7 @@
     def open_workingtree(self, _unsupported=False,
             recommend_upgrade=True):
         """See BzrDir.create_workingtree."""
-        from bzrlib.workingtree import WorkingTreeFormat2
+        from bzrlib.workingtree_2 import WorkingTreeFormat2
         wt_format = WorkingTreeFormat2()
         # we don't warn here about upgrades; that ought to be handled for the
         # bzrdir as a whole
@@ -1243,7 +1243,7 @@
         """See BzrDir.create_workingtree."""
         # we don't warn here about upgrades; that ought to be handled for the
         # bzrdir as a whole
-        from bzrlib.workingtree import WorkingTreeFormat2
+        from bzrlib.workingtree_2 import WorkingTreeFormat2
         return WorkingTreeFormat2().open(self, _found=True)
 
 

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2011-02-25 00:15:23 +0000
+++ b/bzrlib/tests/__init__.py	2011-03-03 11:32:03 +0000
@@ -3887,6 +3887,7 @@
         'bzrlib.tests.test_whitebox',
         'bzrlib.tests.test_win32utils',
         'bzrlib.tests.test_workingtree',
+        'bzrlib.tests.test_workingtree_2',
         'bzrlib.tests.test_workingtree_4',
         'bzrlib.tests.test_wsgi',
         'bzrlib.tests.test_xml',

=== modified file 'bzrlib/tests/test_conflicts.py'
--- a/bzrlib/tests/test_conflicts.py	2011-02-08 10:17:38 +0000
+++ b/bzrlib/tests/test_conflicts.py	2011-03-03 11:32:03 +0000
@@ -64,33 +64,6 @@
 
 class TestConflicts(tests.TestCaseWithTransport):
 
-    def test_conflicts(self):
-        """Conflicts are detected properly"""
-        # Use BzrDirFormat6 so we can fake conflicts
-        tree = self.make_branch_and_tree('.', format=bzrdir.BzrDirFormat6())
-        self.build_tree_contents([('hello', 'hello world4'),
-                                  ('hello.THIS', 'hello world2'),
-                                  ('hello.BASE', 'hello world1'),
-                                  ('hello.OTHER', 'hello world3'),
-                                  ('hello.sploo.BASE', 'yellowworld'),
-                                  ('hello.sploo.OTHER', 'yellowworld2'),
-                                  ])
-        tree.lock_read()
-        self.assertLength(6, list(tree.list_files()))
-        tree.unlock()
-        tree_conflicts = tree.conflicts()
-        self.assertLength(2, tree_conflicts)
-        self.assertTrue('hello' in tree_conflicts[0].path)
-        self.assertTrue('hello.sploo' in tree_conflicts[1].path)
-        conflicts.restore('hello')
-        conflicts.restore('hello.sploo')
-        self.assertLength(0, tree.conflicts())
-        self.assertFileEqual('hello world2', 'hello')
-        self.assertFalse(os.path.lexists('hello.sploo'))
-        self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')
-        self.assertRaises(errors.NotConflicted,
-                          conflicts.restore, 'hello.sploo')
-
     def test_resolve_conflict_dir(self):
         tree = self.make_branch_and_tree('.')
         self.build_tree_contents([('hello', 'hello world4'),

=== modified file 'bzrlib/tests/test_workingtree.py'
--- a/bzrlib/tests/test_workingtree.py	2011-02-24 16:13:39 +0000
+++ b/bzrlib/tests/test_workingtree.py	2011-03-03 11:32:03 +0000
@@ -15,8 +15,6 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-import os
-
 from bzrlib import (
     bzrdir,
     conflicts,
@@ -299,36 +297,6 @@
         self.assertEqual([], tree.get_parent_ids())
 
 
-class TestFormat2WorkingTree(TestCaseWithTransport):
-    """Tests that are specific to format 2 trees."""
-
-    def create_format2_tree(self, url):
-        return self.make_branch_and_tree(
-            url, format=bzrdir.BzrDirFormat6())
-
-    def test_conflicts(self):
-        # test backwards compatability
-        tree = self.create_format2_tree('.')
-        self.assertRaises(errors.UnsupportedOperation, tree.set_conflicts,
-                          None)
-        file('lala.BASE', 'wb').write('labase')
-        expected = conflicts.ContentsConflict('lala')
-        self.assertEqual(list(tree.conflicts()), [expected])
-        file('lala', 'wb').write('la')
-        tree.add('lala', 'lala-id')
-        expected = conflicts.ContentsConflict('lala', file_id='lala-id')
-        self.assertEqual(list(tree.conflicts()), [expected])
-        file('lala.THIS', 'wb').write('lathis')
-        file('lala.OTHER', 'wb').write('laother')
-        # When "text conflict"s happen, stem, THIS and OTHER are text
-        expected = conflicts.TextConflict('lala', file_id='lala-id')
-        self.assertEqual(list(tree.conflicts()), [expected])
-        os.unlink('lala.OTHER')
-        os.mkdir('lala.OTHER')
-        expected = conflicts.ContentsConflict('lala', file_id='lala-id')
-        self.assertEqual(list(tree.conflicts()), [expected])
-
-
 class InstrumentedTree(object):
     """A instrumented tree to check the needs_tree_write_lock decorator."""
 

=== added file 'bzrlib/tests/test_workingtree_2.py'
--- a/bzrlib/tests/test_workingtree_2.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test_workingtree_2.py	2011-03-03 11:32:03 +0000
@@ -0,0 +1,87 @@
+# Copyright (C) 2005-2011 Canonical Ltd
+# Authors:  Robert Collins <robert.collins at canonical.com>
+#
+# 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 weave-era working tree formats."""
+
+import os
+
+from bzrlib import (
+    conflicts,
+    errors,
+    )
+
+from bzrlib.tests import (
+    TestCaseWithTransport,
+    )
+
+from bzrlib.bzrdir import BzrDirFormat6
+
+
+class TestFormat2WorkingTree(TestCaseWithTransport):
+    """Tests that are specific to format 2 trees."""
+
+    def create_format2_tree(self, url):
+        return self.make_branch_and_tree(
+            url, format=BzrDirFormat6())
+
+    def test_conflicts(self):
+        # test backwards compatability
+        tree = self.create_format2_tree('.')
+        self.assertRaises(errors.UnsupportedOperation, tree.set_conflicts,
+                          None)
+        file('lala.BASE', 'wb').write('labase')
+        expected = conflicts.ContentsConflict('lala')
+        self.assertEqual(list(tree.conflicts()), [expected])
+        file('lala', 'wb').write('la')
+        tree.add('lala', 'lala-id')
+        expected = conflicts.ContentsConflict('lala', file_id='lala-id')
+        self.assertEqual(list(tree.conflicts()), [expected])
+        file('lala.THIS', 'wb').write('lathis')
+        file('lala.OTHER', 'wb').write('laother')
+        # When "text conflict"s happen, stem, THIS and OTHER are text
+        expected = conflicts.TextConflict('lala', file_id='lala-id')
+        self.assertEqual(list(tree.conflicts()), [expected])
+        os.unlink('lala.OTHER')
+        os.mkdir('lala.OTHER')
+        expected = conflicts.ContentsConflict('lala', file_id='lala-id')
+        self.assertEqual(list(tree.conflicts()), [expected])
+
+    def test_detect_conflicts(self):
+        """Conflicts are detected properly"""
+        tree = self.create_format2_tree('.')
+        self.build_tree_contents([('hello', 'hello world4'),
+                                  ('hello.THIS', 'hello world2'),
+                                  ('hello.BASE', 'hello world1'),
+                                  ('hello.OTHER', 'hello world3'),
+                                  ('hello.sploo.BASE', 'yellowworld'),
+                                  ('hello.sploo.OTHER', 'yellowworld2'),
+                                  ])
+        tree.lock_read()
+        self.assertLength(6, list(tree.list_files()))
+        tree.unlock()
+        tree_conflicts = tree.conflicts()
+        self.assertLength(2, tree_conflicts)
+        self.assertTrue('hello' in tree_conflicts[0].path)
+        self.assertTrue('hello.sploo' in tree_conflicts[1].path)
+        conflicts.restore('hello')
+        conflicts.restore('hello.sploo')
+        self.assertLength(0, tree.conflicts())
+        self.assertFileEqual('hello world2', 'hello')
+        self.assertFalse(os.path.lexists('hello.sploo'))
+        self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')
+        self.assertRaises(errors.NotConflicted,
+                          conflicts.restore, 'hello.sploo')

=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py	2011-02-25 02:01:51 +0000
+++ b/bzrlib/workingtree.py	2011-03-03 11:32:03 +0000
@@ -1653,17 +1653,6 @@
             # - RBC 20060907
             self._write_inventory(self._inventory)
 
-    def _iter_conflicts(self):
-        conflicted = set()
-        for info in self.list_files():
-            path = info[0]
-            stem = get_conflicted_stem(path)
-            if stem is None:
-                continue
-            if stem not in conflicted:
-                conflicted.add(stem)
-                yield stem
-
     @needs_write_lock
     def pull(self, source, overwrite=False, stop_revision=None,
              change_reporter=None, possible_transports=None, local=False,
@@ -2428,31 +2417,8 @@
     def add_conflicts(self, arg):
         raise errors.UnsupportedOperation(self.add_conflicts, self)
 
-    @needs_read_lock
     def conflicts(self):
-        conflicts = _mod_conflicts.ConflictList()
-        for conflicted in self._iter_conflicts():
-            text = True
-            try:
-                if file_kind(self.abspath(conflicted)) != "file":
-                    text = False
-            except errors.NoSuchFile:
-                text = False
-            if text is True:
-                for suffix in ('.THIS', '.OTHER'):
-                    try:
-                        kind = file_kind(self.abspath(conflicted+suffix))
-                        if kind != "file":
-                            text = False
-                    except errors.NoSuchFile:
-                        text = False
-                    if text == False:
-                        break
-            ctype = {True: 'text conflict', False: 'contents conflict'}[text]
-            conflicts.append(_mod_conflicts.Conflict.factory(ctype,
-                             path=conflicted,
-                             file_id=self.path2id(conflicted)))
-        return conflicts
+        raise NotImplementedError(self.conflicts)
 
     def walkdirs(self, prefix=""):
         """Walk the directories of this tree.
@@ -2717,64 +2683,6 @@
         return ShelfManager(self, self._transport)
 
 
-class WorkingTree2(WorkingTree):
-    """This is the Format 2 working tree.
-
-    This was the first weave based working tree.
-     - uses os locks for locking.
-     - uses the branch last-revision.
-    """
-
-    def __init__(self, *args, **kwargs):
-        super(WorkingTree2, self).__init__(*args, **kwargs)
-        # WorkingTree2 has more of a constraint that self._inventory must
-        # exist. Because this is an older format, we don't mind the overhead
-        # caused by the extra computation here.
-
-        # Newer WorkingTree's should only have self._inventory set when they
-        # have a read lock.
-        if self._inventory is None:
-            self.read_working_inventory()
-
-    def _get_check_refs(self):
-        """Return the references needed to perform a check of this tree."""
-        return [('trees', self.last_revision())]
-
-    def lock_tree_write(self):
-        """See WorkingTree.lock_tree_write().
-
-        In Format2 WorkingTrees we have a single lock for the branch and tree
-        so lock_tree_write() degrades to lock_write().
-
-        :return: An object with an unlock method which will release the lock
-            obtained.
-        """
-        self.branch.lock_write()
-        try:
-            self._control_files.lock_write()
-            return self
-        except:
-            self.branch.unlock()
-            raise
-
-    def unlock(self):
-        # do non-implementation specific cleanup
-        self._cleanup()
-
-        # we share control files:
-        if self._control_files._lock_count == 3:
-            # _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 WorkingTree3(WorkingTree):
     """This is the Format 3 working tree.
 
@@ -2853,12 +2761,6 @@
             self.branch.unlock()
 
 
-def get_conflicted_stem(path):
-    for suffix in _mod_conflicts.CONFLICT_SUFFIXES:
-        if path.endswith(suffix):
-            return path[:-len(suffix)]
-
-
 class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
     """Registry for working tree formats."""
 
@@ -3011,96 +2913,6 @@
         format_registry.remove(format)
 
 
-class WorkingTreeFormat2(WorkingTreeFormat):
-    """The second working tree format.
-
-    This format modified the hash cache from the format 1 hash cache.
-    """
-
-    upgrade_recommended = True
-
-    requires_normalized_unicode_filenames = True
-
-    case_sensitive_filename = "Branch-FoRMaT"
-
-    missing_parent_conflicts = False
-
-    def get_format_description(self):
-        """See WorkingTreeFormat.get_format_description()."""
-        return "Working tree format 2"
-
-    def _stub_initialize_on_transport(self, transport, file_mode):
-        """Workaround: create control files for a remote working tree.
-
-        This ensures that it can later be updated and dealt with locally,
-        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
-        no working tree.  (See bug #43064).
-        """
-        sio = StringIO()
-        inv = inventory.Inventory()
-        xml5.serializer_v5.write_inventory(inv, sio, working=True)
-        sio.seek(0)
-        transport.put_file('inventory', sio, file_mode)
-        transport.put_bytes('pending-merges', '', file_mode)
-
-    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
-                   accelerator_tree=None, hardlink=False):
-        """See WorkingTreeFormat.initialize()."""
-        if not isinstance(a_bzrdir.transport, LocalTransport):
-            raise errors.NotLocalUrl(a_bzrdir.transport.base)
-        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())
-        branch.lock_write()
-        try:
-            branch.generate_revision_history(revision_id)
-        finally:
-            branch.unlock()
-        inv = inventory.Inventory()
-        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
-                         branch,
-                         inv,
-                         _internal=True,
-                         _format=self,
-                         _bzrdir=a_bzrdir,
-                         _control_files=branch.control_files)
-        basis_tree = branch.repository.revision_tree(revision_id)
-        if basis_tree.inventory.root is not None:
-            wt.set_root_id(basis_tree.get_root_id())
-        # set the parent list and cache the basis tree.
-        if _mod_revision.is_null(revision_id):
-            parent_trees = []
-        else:
-            parent_trees = [(revision_id, basis_tree)]
-        wt.set_parent_trees(parent_trees)
-        transform.build_tree(basis_tree, wt)
-        return wt
-
-    def __init__(self):
-        super(WorkingTreeFormat2, self).__init__()
-        self._matchingbzrdir = bzrdir.BzrDirFormat6()
-
-    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 = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
-                           _internal=True,
-                           _format=self,
-                           _bzrdir=a_bzrdir,
-                           _control_files=a_bzrdir.open_branch().control_files)
-        return wt
-
 class WorkingTreeFormat3(WorkingTreeFormat):
     """The second working tree format updated to record a format marker.
 
@@ -3246,4 +3058,5 @@
 # Register extra formats which have no format string are not discoverable
 # and not independently creatable. They are implicitly created as part of
 # e.g. older Bazaar formats or foreign formats.
-format_registry.register_extra(WorkingTreeFormat2())
+format_registry.register_extra_lazy("bzrlib.workingtree_2",
+    "WorkingTreeFormat2")

=== added file 'bzrlib/workingtree_2.py'
--- a/bzrlib/workingtree_2.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/workingtree_2.py	2011-03-03 11:32:03 +0000
@@ -0,0 +1,230 @@
+# Copyright (C) 2005-2010 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
+
+"""Weave-era working tree objects."""
+
+from cStringIO import StringIO
+
+from bzrlib import (
+    conflicts as _mod_conflicts,
+    errors,
+    inventory,
+    osutils,
+    revision as _mod_revision,
+    transform,
+    xml5,
+    )
+from bzrlib.decorators import needs_read_lock
+from bzrlib.transport.local import LocalTransport
+from bzrlib.workingtree import (
+    WorkingTreeFormat,
+    WorkingTree,
+    )
+
+
+def get_conflicted_stem(path):
+    for suffix in _mod_conflicts.CONFLICT_SUFFIXES:
+        if path.endswith(suffix):
+            return path[:-len(suffix)]
+
+
+class WorkingTreeFormat2(WorkingTreeFormat):
+    """The second working tree format.
+
+    This format modified the hash cache from the format 1 hash cache.
+    """
+
+    upgrade_recommended = True
+
+    requires_normalized_unicode_filenames = True
+
+    case_sensitive_filename = "Branch-FoRMaT"
+
+    missing_parent_conflicts = False
+
+    def get_format_description(self):
+        """See WorkingTreeFormat.get_format_description()."""
+        return "Working tree format 2"
+
+    def _stub_initialize_on_transport(self, transport, file_mode):
+        """Workaround: create control files for a remote working tree.
+
+        This ensures that it can later be updated and dealt with locally,
+        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
+        no working tree.  (See bug #43064).
+        """
+        sio = StringIO()
+        inv = inventory.Inventory()
+        xml5.serializer_v5.write_inventory(inv, sio, working=True)
+        sio.seek(0)
+        transport.put_file('inventory', sio, file_mode)
+        transport.put_bytes('pending-merges', '', file_mode)
+
+    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
+                   accelerator_tree=None, hardlink=False):
+        """See WorkingTreeFormat.initialize()."""
+        if not isinstance(a_bzrdir.transport, LocalTransport):
+            raise errors.NotLocalUrl(a_bzrdir.transport.base)
+        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())
+        branch.lock_write()
+        try:
+            branch.generate_revision_history(revision_id)
+        finally:
+            branch.unlock()
+        inv = inventory.Inventory()
+        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
+                         branch,
+                         inv,
+                         _internal=True,
+                         _format=self,
+                         _bzrdir=a_bzrdir,
+                         _control_files=branch.control_files)
+        basis_tree = branch.repository.revision_tree(revision_id)
+        if basis_tree.inventory.root is not None:
+            wt.set_root_id(basis_tree.get_root_id())
+        # set the parent list and cache the basis tree.
+        if _mod_revision.is_null(revision_id):
+            parent_trees = []
+        else:
+            parent_trees = [(revision_id, basis_tree)]
+        wt.set_parent_trees(parent_trees)
+        transform.build_tree(basis_tree, wt)
+        return wt
+
+    def __init__(self):
+        super(WorkingTreeFormat2, self).__init__()
+        from bzrlib.bzrdir import BzrDirFormat6
+        self._matchingbzrdir = BzrDirFormat6()
+
+    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 = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
+                           _internal=True,
+                           _format=self,
+                           _bzrdir=a_bzrdir,
+                           _control_files=a_bzrdir.open_branch().control_files)
+        return wt
+
+
+class WorkingTree2(WorkingTree):
+    """This is the Format 2 working tree.
+
+    This was the first weave based working tree.
+     - uses os locks for locking.
+     - uses the branch last-revision.
+    """
+
+    def __init__(self, *args, **kwargs):
+        super(WorkingTree2, self).__init__(*args, **kwargs)
+        # WorkingTree2 has more of a constraint that self._inventory must
+        # exist. Because this is an older format, we don't mind the overhead
+        # caused by the extra computation here.
+
+        # Newer WorkingTree's should only have self._inventory set when they
+        # have a read lock.
+        if self._inventory is None:
+            self.read_working_inventory()
+
+    def _get_check_refs(self):
+        """Return the references needed to perform a check of this tree."""
+        return [('trees', self.last_revision())]
+
+    def lock_tree_write(self):
+        """See WorkingTree.lock_tree_write().
+
+        In Format2 WorkingTrees we have a single lock for the branch and tree
+        so lock_tree_write() degrades to lock_write().
+
+        :return: An object with an unlock method which will release the lock
+            obtained.
+        """
+        self.branch.lock_write()
+        try:
+            self._control_files.lock_write()
+            return self
+        except:
+            self.branch.unlock()
+            raise
+
+    def unlock(self):
+        # do non-implementation specific cleanup
+        self._cleanup()
+
+        # we share control files:
+        if self._control_files._lock_count == 3:
+            # _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()
+
+    def _iter_conflicts(self):
+        conflicted = set()
+        for info in self.list_files():
+            path = info[0]
+            stem = get_conflicted_stem(path)
+            if stem is None:
+                continue
+            if stem not in conflicted:
+                conflicted.add(stem)
+                yield stem
+
+    @needs_read_lock
+    def conflicts(self):
+        conflicts = _mod_conflicts.ConflictList()
+        for conflicted in self._iter_conflicts():
+            text = True
+            try:
+                if osutils.file_kind(self.abspath(conflicted)) != "file":
+                    text = False
+            except errors.NoSuchFile:
+                text = False
+            if text is True:
+                for suffix in ('.THIS', '.OTHER'):
+                    try:
+                        kind = osutils.file_kind(self.abspath(conflicted+suffix))
+                        if kind != "file":
+                            text = False
+                    except errors.NoSuchFile:
+                        text = False
+                    if text == False:
+                        break
+            ctype = {True: 'text conflict', False: 'contents conflict'}[text]
+            conflicts.append(_mod_conflicts.Conflict.factory(ctype,
+                             path=conflicted,
+                             file_id=self.path2id(conflicted)))
+        return conflicts
+
+




More information about the bazaar-commits mailing list