Rev 2423: merge robert, debugging in http://sourcefrog.net/bzr/dirstate-plus-subtree

Martin Pool mbp at sourcefrog.net
Thu Mar 1 10:14:05 GMT 2007


At http://sourcefrog.net/bzr/dirstate-plus-subtree

------------------------------------------------------------
revno: 2423
revision-id: mbp at sourcefrog.net-20070301101403-v2ey2v53rhzprmds
parent: mbp at sourcefrog.net-20070301090216-vhh2444yosrvw6ll
parent: robertc at robertcollins.net-20070301085003-1k4kx7hxz8ce5x8p
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: dirstate-plus-subtree
timestamp: Thu 2007-03-01 21:14:03 +1100
message:
  merge robert, debugging
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/dirstate.py             dirstate.py-20060728012006-d6mvoihjb3je9peu-1
  bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
  bzrlib/mutabletree.py          mutabletree.py-20060906023413-4wlkalbdpsxi2r4y-2
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/blackbox/test_add.py test_add.py-20060518072250-857e4f86f54a30b2
  bzrlib/tests/blackbox/test_break_lock.py test_break_lock.py-20060303014503-a90e07d38d042d1d
  bzrlib/tests/blackbox/test_cat.py test_cat.py-20051201162916-f0937e4e19ea24b3
  bzrlib/tests/blackbox/test_status.py teststatus.py-20050712014354-508855eb9f29f7dc
  bzrlib/tests/blackbox/test_update.py test_update.py-20060212125639-c4dad1a5c56d5919
  bzrlib/tests/repository_implementations/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
  bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
  bzrlib/tests/test_dirstate.py  test_dirstate.py-20060728012006-d6mvoihjb3je9peu-2
  bzrlib/tests/test_inv.py       testinv.py-20050722220913-1dc326138d1a5892
  bzrlib/tests/test_smart_add.py test_smart_add.py-20050824235919-c60dcdb0c8e999ce
  bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
  bzrlib/tests/workingtree_implementations/test_workingtree.py test_workingtree.py-20060203003124-817757d3e31444fb
  bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
  bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
  bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
  bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
    ------------------------------------------------------------
    revno: 2406.1.70
    merged: robertc at robertcollins.net-20070301085003-1k4kx7hxz8ce5x8p
    parent: robertc at robertcollins.net-20070301084414-h302pw7vt7wllqb6
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 19:50:03 +1100
    message:
      Workaround WorkingTree4 not having a native remove() in test_cat.
    ------------------------------------------------------------
    revno: 2406.1.69
    merged: robertc at robertcollins.net-20070301084414-h302pw7vt7wllqb6
    parent: mbp at sourcefrog.net-20070301083325-e87nhnnpx3i18nea
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 19:44:14 +1100
    message:
      Fix all blackbox add tests, and the add --from-ids case in the UI.
    ------------------------------------------------------------
    revno: 2406.1.68
    merged: mbp at sourcefrog.net-20070301083325-e87nhnnpx3i18nea
    parent: robertc at robertcollins.net-20070301080114-dt6xpp7v0envbati
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: dirstate-robert
    timestamp: Thu 2007-03-01 19:33:25 +1100
    message:
      Add a test for setting the root id in a dirstate with parent trees
    ------------------------------------------------------------
    revno: 2406.1.67
    merged: robertc at robertcollins.net-20070301080114-dt6xpp7v0envbati
    parent: robertc at robertcollins.net-20070301074339-34mc7tfym7o4uugf
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 19:01:14 +1100
    message:
      Fix test_inv - make setting WorkingTree4._dirty use a helper to reduce code duplication, and reset the inventory when we dont manually update it, if it exists.
    ------------------------------------------------------------
    revno: 2406.1.66
    merged: robertc at robertcollins.net-20070301074339-34mc7tfym7o4uugf
    parent: robertc at robertcollins.net-20070301072736-dc00wtcb7py592re
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 18:43:39 +1100
    message:
      MutableTree.add only needs a tree write lock.
    ------------------------------------------------------------
    revno: 2406.1.65
    merged: robertc at robertcollins.net-20070301072736-dc00wtcb7py592re
    parent: robertc at robertcollins.net-20070301071122-yhy7vchlazynnb8y
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 18:27:36 +1100
    message:
      Split test_root_revision_entry into tree and repository portions.
    ------------------------------------------------------------
    revno: 2406.1.64
    merged: robertc at robertcollins.net-20070301071122-yhy7vchlazynnb8y
    parent: robertc at robertcollins.net-20070301065052-d08k4x37bchwo48e
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 18:11:22 +1100
    message:
      Disabled test_repository.test_create_basis_inventory, a test that tests tree behaviour in the wrong place - its future is being discussed.
    ------------------------------------------------------------
    revno: 2406.1.63
    merged: robertc at robertcollins.net-20070301065052-d08k4x37bchwo48e
    parent: robertc at robertcollins.net-20070301061944-y1jw05ufqdpw4yx5
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 17:50:52 +1100
    message:
      Fix cmd_renames to lock around inventory access.
    ------------------------------------------------------------
    revno: 2406.1.62
    merged: robertc at robertcollins.net-20070301061944-y1jw05ufqdpw4yx5
    parent: robertc at robertcollins.net-20070301054630-ff4zf6s3odxfic71
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 17:19:44 +1100
    message:
      Update the Tree.filter_unversioned_files docstring to reflect what the existing implementations actually do, and change the WorkingTree4 implementation to match a newly created test for it.
    ------------------------------------------------------------
    revno: 2406.1.61
    merged: robertc at robertcollins.net-20070301054630-ff4zf6s3odxfic71
    parent: robertc at robertcollins.net-20070301053439-rf8mkppoqutiy7fa
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 16:46:30 +1100
    message:
      Remove exploratory cruft.
    ------------------------------------------------------------
    revno: 2406.1.60
    merged: robertc at robertcollins.net-20070301053439-rf8mkppoqutiy7fa
    parent: robertc at robertcollins.net-20070301052802-zwbocbr7z5vyptad
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 16:34:39 +1100
    message:
      Make the assertStatus blackbox helper clearer.
    ------------------------------------------------------------
    revno: 2406.1.59
    merged: robertc at robertcollins.net-20070301052802-zwbocbr7z5vyptad
    parent: robertc at robertcollins.net-20070301052607-x77gnbfssigedky4
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 16:28:02 +1100
    message:
      Remove a break-lock test that was duplicating lower level testing without adding value.
    ------------------------------------------------------------
    revno: 2406.1.58
    merged: robertc at robertcollins.net-20070301052607-x77gnbfssigedky4
    parent: robertc at robertcollins.net-20070301052056-h3byz7nuk38la3os
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 16:26:07 +1100
    message:
      Fix a blackbox test to not use inventory to determine tree size.
    ------------------------------------------------------------
    revno: 2406.1.57
    merged: robertc at robertcollins.net-20070301052056-h3byz7nuk38la3os
    parent: robertc at robertcollins.net-20070301051807-3qz6wj0jtjsieyj2
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 16:20:56 +1100
    message:
      Fix test_smart_add tests for dirstate - mainly inventory outside locks issues.
    ------------------------------------------------------------
    revno: 2406.1.56
    merged: robertc at robertcollins.net-20070301051807-3qz6wj0jtjsieyj2
    parent: robertc at robertcollins.net-20070301050247-ufh99m2ze45d7mol
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 16:18:07 +1100
    message:
      Document behaviour of tree.path2id("path/").
    ------------------------------------------------------------
    revno: 2406.1.55
    merged: robertc at robertcollins.net-20070301050247-ufh99m2ze45d7mol
    parent: robertc at robertcollins.net-20070301050153-9wdn7gdori263v9e
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 16:02:47 +1100
    message:
      Whitespace fix.
    ------------------------------------------------------------
    revno: 2406.1.54
    merged: robertc at robertcollins.net-20070301050153-9wdn7gdori263v9e
    parent: robertc at robertcollins.net-20070301050053-u0ac7vavyzplbjz1
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 16:01:53 +1100
    message:
      in test_inv, stop abusing the inventory interface to get tree alterations to occur.
    ------------------------------------------------------------
    revno: 2406.1.53
    merged: robertc at robertcollins.net-20070301050053-u0ac7vavyzplbjz1
    parent: robertc at robertcollins.net-20070301042839-hgs5fy98vuws6iau
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 16:00:53 +1100
    message:
      Make the dirstate API changes be prominently documented for upgraders.
    ------------------------------------------------------------
    revno: 2406.1.52
    merged: robertc at robertcollins.net-20070301042839-hgs5fy98vuws6iau
    parent: robertc at robertcollins.net-20070301042042-vmcypp3mjnvuwft5
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 15:28:39 +1100
    message:
      Lock trees in Merge3Merger correctly.
    ------------------------------------------------------------
    revno: 2406.1.51
    merged: robertc at robertcollins.net-20070301042042-vmcypp3mjnvuwft5
    parent: robertc at robertcollins.net-20070301041307-yendz2ijpubqmfgq
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 15:20:42 +1100
    message:
      Lock build_tree trees in write-first order, to support older formats that dont do lock_tree_write nicely.
    ------------------------------------------------------------
    revno: 2406.1.50
    merged: robertc at robertcollins.net-20070301041307-yendz2ijpubqmfgq
    parent: robertc at robertcollins.net-20070301040645-1ky0urtukkb9gdxa
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 15:13:07 +1100
    message:
      Remove unguarded call to find_interesting in test_find_interesting - its tested by the actual code that does the work.
    ------------------------------------------------------------
    revno: 2406.1.49
    merged: robertc at robertcollins.net-20070301040645-1ky0urtukkb9gdxa
    parent: robertc at robertcollins.net-20070301035615-apsvyiyqk6pqext2
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 15:06:45 +1100
    message:
      Lock trees passed in to build_tree.
    ------------------------------------------------------------
    revno: 2406.1.48
    merged: robertc at robertcollins.net-20070301035615-apsvyiyqk6pqext2
    parent: robertc at robertcollins.net-20070301035205-lfdthhpjoudb07b8
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 14:56:15 +1100
    message:
      Deprecated and make work with DirState trees 'transform.find_interesting'.
    ------------------------------------------------------------
    revno: 2406.1.47
    merged: robertc at robertcollins.net-20070301035205-lfdthhpjoudb07b8
    parent: robertc at robertcollins.net-20070301032019-s9lbs2lv8xa6zqxk
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate
    timestamp: Thu 2007-03-01 14:52:05 +1100
    message:
      Improve applyDeprecated warning message.
=== modified file 'NEWS'
--- a/NEWS	2007-02-22 15:04:35 +0000
+++ b/NEWS	2007-03-01 05:00:53 +0000
@@ -1,5 +1,23 @@
 IN DEVELOPMENT
 
+  SURPRISES:
+
+    * For users of bzrlib: Two major changes have been made to the working tree
+      api in bzrlib. The first is that many methods and attributes, including
+      the inventory attribute, are no longer valid for use until one of
+      lock_read/lock_write/lock_tree_write has been called, and become invalid
+      again after unlock is called. This has been done to improve performance
+      and correctness as part of the dirstate development. (Robert Collins,
+      John A Meinel, Martin Pool, and others).
+    * For users of bzrlib: The attribute 'tree.inventory' should be considered
+      readonly. Previously it was possible to directly alter this attribute, or
+      its contents, and have the tree notice this. This has been made
+      unsupported - it may work in some tree formats, but in the newer dirstate
+      format such actions will have no effect and will be ignored, or even
+      cause assertions. All operations possible can still be carried out by a
+      combination of the tree API, and the bzrlib.transform API. (Robert
+      Collins, John A Meinel, Martin Pool, and others).
+
   IMPROVEMENTS:
 
     * Support for OS Windows 98. Also .bzr.log on any windows system

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2007-03-01 04:07:42 +0000
+++ b/bzrlib/builtins.py	2007-03-01 10:14:03 +0000
@@ -342,6 +342,7 @@
             file_ids_from=None):
         import bzrlib.add
 
+        base_tree = None
         if file_ids_from is not None:
             try:
                 base_tree, base_path = WorkingTree.open_containing(
@@ -357,8 +358,14 @@
             action = bzrlib.add.AddAction(to_file=self.outf,
                 should_print=(not is_quiet()))
 
-        added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
-                                              action=action, save=not dry_run)
+        if base_tree:
+            base_tree.lock_read()
+        try:
+            added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
+                action=action, save=not dry_run)
+        finally:
+            if base_tree is not None:
+                base_tree.unlock()
         if len(ignored) > 0:
             if verbose:
                 for glob in sorted(ignored.keys()):
@@ -977,12 +984,21 @@
     @display_command
     def run(self, dir=u'.'):
         tree = WorkingTree.open_containing(dir)[0]
-        old_inv = tree.basis_tree().inventory
-        new_inv = tree.read_working_inventory()
-        renames = list(_mod_tree.find_renames(old_inv, new_inv))
-        renames.sort()
-        for old_name, new_name in renames:
-            self.outf.write("%s => %s\n" % (old_name, new_name))
+        tree.lock_read()
+        try:
+            new_inv = tree.inventory
+            old_tree = tree.basis_tree()
+            old_tree.lock_read()
+            try:
+                old_inv = old_tree.inventory
+                renames = list(_mod_tree.find_renames(old_inv, new_inv))
+                renames.sort()
+                for old_name, new_name in renames:
+                    self.outf.write("%s => %s\n" % (old_name, new_name))
+            finally:
+                old_tree.unlock()
+        finally:
+            tree.unlock()
 
 
 class cmd_update(Command):
@@ -1467,17 +1483,26 @@
     @display_command
     def run(self):
         wt = WorkingTree.open_containing(u'.')[0]
-        basis_inv = wt.basis_tree().inventory
-        inv = wt.inventory
-        for file_id in inv:
-            if file_id in basis_inv:
-                continue
-            if inv.is_root(file_id) and len(basis_inv) == 0:
-                continue
-            path = inv.id2path(file_id)
-            if not os.access(osutils.abspath(path), os.F_OK):
-                continue
-            self.outf.write(path + '\n')
+        wt.lock_read()
+        try:
+            basis = wt.basis_tree()
+            basis.lock_read()
+            try:
+                basis_inv = basis.inventory
+                inv = wt.inventory
+                for file_id in inv:
+                    if file_id in basis_inv:
+                        continue
+                    if inv.is_root(file_id) and len(basis_inv) == 0:
+                        continue
+                    path = inv.id2path(file_id)
+                    if not os.access(osutils.abspath(path), os.F_OK):
+                        continue
+                    self.outf.write(path + '\n')
+            finally:
+                basis.unlock()
+        finally:
+            wt.unlock()
 
 
 class cmd_root(Command):

=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py	2007-03-01 07:56:56 +0000
+++ b/bzrlib/dirstate.py	2007-03-01 10:14:03 +0000
@@ -1963,6 +1963,31 @@
 
         self._dirblock_state = DirState.IN_MEMORY_MODIFIED
 
+    def _validate(self):
+        """Check that invariants on the dirblock are correct.
+
+        This can be useful in debugging; it shouldn't be necessary in 
+        normal code.
+        """
+        from pprint import pformat
+        if len(self._dirblocks) > 0:
+            assert self._dirblocks[0][0] == '', \
+                    "dirblocks don't start with root block:\n" + \
+                    pformat(dirblocks)
+        if len(self._dirblocks) > 1:
+            assert self._dirblocks[1][0] == '', \
+                    "dirblocks missing root directory:\n" + \
+                    pformat(dirblocks)
+        assert self._dirblocks[0][0] == '', \
+                "dirblocks don't start with root block:\n" + \
+                pformat(dirblocks)
+        assert self._dirblocks[1:] == sorted(self._dirblocks[1:]), \
+                "dirblocks are not in sorted order:\n" + \
+                pformat(self._dirblocks)
+        for dirblock in self._dirblocks:
+            assert dirblock[1] == sorted(dirblock[1]), \
+                "dirblock for %r is not sorted:\n%s" % \
+                (dirblock[0], pformat(dirblock))
 
     def _wipe_state(self):
         """Forget all state information about the dirstate."""

=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py	2007-02-27 05:51:36 +0000
+++ b/bzrlib/merge.py	2007-03-01 10:14:03 +0000
@@ -415,8 +415,11 @@
         """Initialize the merger object and perform the merge."""
         object.__init__(self)
         self.this_tree = working_tree
+        self.this_tree.lock_tree_write()
         self.base_tree = base_tree
+        self.base_tree.lock_read()
         self.other_tree = other_tree
+        self.other_tree.lock_read()
         self._raw_conflicts = []
         self.cooked_conflicts = []
         self.reprocess = reprocess
@@ -432,7 +435,6 @@
         else:
             all_ids = set(base_tree)
             all_ids.update(other_tree)
-        working_tree.lock_tree_write()
         self.tt = TreeTransform(working_tree, self.pb)
         try:
             self.pp.next_phase()
@@ -467,7 +469,9 @@
                 pass
         finally:
             self.tt.finalize()
-            working_tree.unlock()
+            self.other_tree.unlock()
+            self.base_tree.unlock()
+            self.this_tree.unlock()
             self.pb.clear()
 
     def fix_root(self):

=== modified file 'bzrlib/mutabletree.py'
--- a/bzrlib/mutabletree.py	2007-02-26 14:24:46 +0000
+++ b/bzrlib/mutabletree.py	2007-03-01 10:14:03 +0000
@@ -62,7 +62,7 @@
     branch and bzrdir attributes.
     """
 
-    @needs_write_lock
+    @needs_tree_write_lock
     def add(self, files, ids=None, kinds=None):
         """Add paths to the set of versioned paths.
 

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2007-02-23 05:47:26 +0000
+++ b/bzrlib/tests/__init__.py	2007-03-01 10:14:03 +0000
@@ -741,7 +741,7 @@
         expected_first_warning = symbol_versioning.deprecation_string(
             a_callable, deprecation_format)
         if len(call_warnings) == 0:
-            self.fail("No assertion generated by call to %s" %
+            self.fail("No deprecation warning generated by call to %s" %
                 a_callable)
         self.assertEqual(expected_first_warning, call_warnings[0])
         return result

=== modified file 'bzrlib/tests/blackbox/test_add.py'
--- a/bzrlib/tests/blackbox/test_add.py	2007-02-15 22:24:48 +0000
+++ b/bzrlib/tests/blackbox/test_add.py	2007-03-01 08:44:14 +0000
@@ -115,7 +115,7 @@
         self.run_bzr('add')
         
         self.assertEquals(self.capture('unknowns'), 'README\n')
-        eq(len(t.read_working_inventory()), 3)
+        eq(len(list(t)), 3)
                 
         chdir('..')
         self.run_bzr('add')
@@ -144,7 +144,6 @@
                              'added b/c w/ file id from b/c\n',
                              out)
 
-        new_tree.read_working_inventory()
         self.assertEqual(base_tree.path2id('a'), new_tree.path2id('a'))
         self.assertEqual(base_tree.path2id('b'), new_tree.path2id('b'))
         self.assertEqual(base_tree.path2id('b/c'), new_tree.path2id('b/c'))
@@ -165,7 +164,6 @@
                              'added d w/ file id from b/d\n',
                              out)
 
-        new_tree.read_working_inventory()
         self.assertEqual(base_tree.path2id('b/c'), new_tree.path2id('c'))
         self.assertEqual(base_tree.path2id('b/d'), new_tree.path2id('d'))
 

=== modified file 'bzrlib/tests/blackbox/test_break_lock.py'
--- a/bzrlib/tests/blackbox/test_break_lock.py	2007-02-25 21:52:19 +0000
+++ b/bzrlib/tests/blackbox/test_break_lock.py	2007-03-01 05:28:02 +0000
@@ -92,37 +92,6 @@
         self.assertRaises(errors.LockBroken, self.wt.unlock)
         self.assertRaises(errors.LockBroken, self.master_branch.unlock)
 
-    def test_saying_no_leaves_it_locked(self):
-        ### if 'no' is answered, objects should remain locked.
-        self.wt.lock_write()
-        try:
-            self.master_branch.lock_write()
-            try:
-                # run the break-lock
-                # we need 5 yes's - wt, branch, repo, bound branch, bound repo.
-                self.run_bzr('break-lock', 'checkout', stdin="n\nn\nn\nn\nn\n")
-
-                # The default timeout to wait for LockContention is 5 minutes.
-                # we need to override this temporarily.
-                # TODO: jam 20060927 When we have per repository/branch/tree
-                #       timeouts set the value of the repository,
-                #       rather than setting the global default.
-                orig_default = lockdir._DEFAULT_TIMEOUT_SECONDS
-                try:
-                    lockdir._DEFAULT_TIMEOUT_SECONDS = 1
-                    # a new tree instance should not be lockable
-                    wt = bzrlib.workingtree.WorkingTree.open('checkout')
-                    self.assertRaises(errors.LockContention, wt.lock_write)
-                    # and a new instance of the master branch 
-                    mb = wt.branch.get_master_branch()
-                    self.assertRaises(errors.LockContention, mb.lock_write)
-                finally:
-                    lockdir._DEFAULT_TIMEOUT_SECONDS = orig_default
-                # unlock our branches normally.
-            finally:
-                self.master_branch.unlock()
-        finally:
-            self.wt.unlock()
 
 class TestBreakLockOldBranch(ExternalBase):
 

=== modified file 'bzrlib/tests/blackbox/test_cat.py'
--- a/bzrlib/tests/blackbox/test_cat.py	2006-12-13 08:15:54 +0000
+++ b/bzrlib/tests/blackbox/test_cat.py	2007-03-01 08:50:03 +0000
@@ -73,6 +73,9 @@
         try:
             tree.add(['a-rev-tree', 'c-rev', 'd-rev'])
             tree.commit('add test files')
+            # remove currently uses self._write_inventory - 
+            # work around that for now.
+            tree.flush()
             tree.remove(['d-rev'])
             tree.rename_one('a-rev-tree', 'b-tree')
             tree.rename_one('c-rev', 'a-rev-tree')

=== modified file 'bzrlib/tests/blackbox/test_status.py'
--- a/bzrlib/tests/blackbox/test_status.py	2007-02-21 07:59:17 +0000
+++ b/bzrlib/tests/blackbox/test_status.py	2007-03-01 05:34:39 +0000
@@ -40,15 +40,15 @@
 
 class BranchStatus(TestCaseWithTransport):
     
-    def assertStatus(self, output_lines, working_tree,
+    def assertStatus(self, expected_lines, working_tree,
         revision=None, short=False):
         """Run status in working_tree and look for output.
         
-        :param output_lines: The lines to look for.
+        :param expected_lines: The lines to look for.
         :param working_tree: The tree to run status in.
         """
         output_string = self.status_string(working_tree, revision, short)
-        self.assertEqual(output_lines, output_string.splitlines(True))
+        self.assertEqual(expected_lines, output_string.splitlines(True))
     
     def status_string(self, wt, revision=None, short=False):
         # use a real file rather than StringIO because it doesn't handle

=== modified file 'bzrlib/tests/blackbox/test_update.py'
--- a/bzrlib/tests/blackbox/test_update.py	2006-10-18 02:26:35 +0000
+++ b/bzrlib/tests/blackbox/test_update.py	2007-03-01 05:02:47 +0000
@@ -202,7 +202,7 @@
         """Update a light checkout of a readonly branch"""
         tree = self.make_branch_and_tree('branch')
         readonly_branch = branch.Branch.open(self.get_readonly_url('branch'))
-        checkout = readonly_branch.create_checkout('checkout', 
+        checkout = readonly_branch.create_checkout('checkout',
                                                    lightweight=True)
         tree.commit('empty commit')
         self.runbzr(['update', 'checkout'])

=== modified file 'bzrlib/tests/repository_implementations/test_commit_builder.py'
--- a/bzrlib/tests/repository_implementations/test_commit_builder.py	2007-02-26 15:27:17 +0000
+++ b/bzrlib/tests/repository_implementations/test_commit_builder.py	2007-03-01 07:27:36 +0000
@@ -126,3 +126,14 @@
         # the RevisionTree api.
         self.assertEqual(rev_id, rev_tree.get_revision_id())
         self.assertEqual([], rev_tree.get_parent_ids())
+
+    def test_root_entry_has_revision(self):
+        # test the root revision created and put in the basis
+        # has the right rev id.
+        tree = self.make_branch_and_tree('.')
+        rev_id = tree.commit('message')
+        basis_tree = tree.basis_tree()
+        basis_tree.lock_read()
+        self.addCleanup(basis_tree.unlock)
+        self.assertEqual(rev_id, basis_tree.inventory.root.revision)
+

=== modified file 'bzrlib/tests/repository_implementations/test_repository.py'
--- a/bzrlib/tests/repository_implementations/test_repository.py	2007-02-16 07:02:19 +0000
+++ b/bzrlib/tests/repository_implementations/test_repository.py	2007-03-01 10:14:03 +0000
@@ -365,11 +365,10 @@
     def test_root_entry_has_revision(self):
         tree = self.make_branch_and_tree('.')
         tree.commit('message', rev_id='rev_id')
-        self.assertEqual('rev_id', tree.basis_tree().inventory.root.revision)
-        rev_tree = tree.branch.repository.revision_tree(tree.get_parent_ids()[0])
+        rev_tree = tree.branch.repository.revision_tree(tree.last_revision())
         self.assertEqual('rev_id', rev_tree.inventory.root.revision)
 
-    def test_create_basis_inventory(self):
+    def DISABLED_DELETE_OR_FIX_BEFORE_MERGE_test_create_basis_inventory(self):
         # Needs testing here because differences between repo and working tree
         # basis inventory formats can lead to bugs.
         t = self.make_branch_and_tree('.')

=== modified file 'bzrlib/tests/test_dirstate.py'
--- a/bzrlib/tests/test_dirstate.py	2007-02-27 21:32:16 +0000
+++ b/bzrlib/tests/test_dirstate.py	2007-03-01 08:33:25 +0000
@@ -424,6 +424,41 @@
         finally:
             state.unlock()
 
+    def test_set_path_id_with_parents(self):
+        """Set the root file id in a dirstate with parents"""
+        mt = self.make_branch_and_tree('mt')
+        # may need to set the root when the default format is one where it's
+        # not TREE_ROOT
+        mt.commit('foo', rev_id='parent-revid')
+        rt = mt.branch.repository.revision_tree('parent-revid')
+        state = dirstate.DirState.initialize('dirstate')
+        try:
+            state.set_parent_trees([('parent-revid', rt)], ghosts=[])
+            state.set_path_id('', 'foobarbaz')
+            # now see that it is what we expected
+            expected_rows = [
+                (('', '', 'TREE_ROOT'),
+                    [('a', '', 0, False, ''),
+                     ('d', '', 0, False, 'parent-revid'),
+                     ]),
+                (('', '', 'foobarbaz'),
+                    [('d', '', 0, False, ''),
+                     ('a', '', 0, False, ''),
+                     ]),
+                ]
+            self.assertEqual(expected_rows, list(state._iter_entries()))
+            # should work across save too
+            state.save()
+        finally:
+            state.unlock()
+        # now flush & check we get the same
+        state = dirstate.DirState.on_file('dirstate')
+        state.lock_read()
+        try:
+            self.assertEqual(expected_rows, list(state._iter_entries()))
+        finally:
+            state.unlock()
+
     def test_set_parent_trees_no_content(self):
         # set_parent_trees is a slow but important api to support.
         tree1 = self.make_branch_and_memory_tree('tree1')

=== modified file 'bzrlib/tests/test_inv.py'
--- a/bzrlib/tests/test_inv.py	2007-02-22 05:51:57 +0000
+++ b/bzrlib/tests/test_inv.py	2007-03-01 10:14:03 +0000
@@ -312,6 +312,8 @@
         self.file_1 = self.inv_1['fileid']
         self.file_1b = self.inv_1['binfileid']
         self.tree_2 = self.wt
+        self.tree_2.lock_read()
+        self.addCleanup(self.tree_2.unlock)
         self.inv_2 = self.tree_2.read_working_inventory()
         self.file_2 = self.inv_2['fileid']
         self.file_2b = self.inv_2['binfileid']
@@ -419,6 +421,8 @@
         self.tree_1 = self.branch.repository.revision_tree('1')
         self.inv_1 = self.branch.repository.get_inventory('1')
         self.file_1 = self.inv_1['fileid']
+        self.wt.lock_write()
+        self.addCleanup(self.wt.unlock)
         self.file_active = self.wt.inventory['fileid']
         self.builder = self.branch.get_commit_builder([], timestamp=time.time(), revision_id='2')
 
@@ -473,8 +477,8 @@
     def test_snapshot_changed(self):
         # This tests that a commit with one different parent results in a new
         # revision id in the entry.
-        self.file_active.name='newname'
-        rename('subdir/file', 'subdir/newname')
+        self.wt.rename_one('subdir/file', 'subdir/newname')
+        self.file_active = self.wt.inventory['fileid']
         self.file_active.snapshot('2', 'subdir/newname', {'1':self.file_1}, 
                                   self.wt, self.builder)
         # expected outcome - file_1 has a revision id of '2'
@@ -508,6 +512,8 @@
         self.wt.add_parent_tree_id('B')
         self.wt.commit('merge in B', rev_id='D')
         self.inv_D = self.branch.repository.get_inventory('D')
+        self.wt.lock_read()
+        self.addCleanup(self.wt.unlock)
         self.file_active = self.wt.inventory['fileid']
         self.weave = self.branch.repository.weave_store.get_weave('fileid',
             self.branch.repository.get_transaction())
@@ -608,10 +614,13 @@
 
     def test_dangling_id(self):
         wt = self.make_branch_and_tree('b1')
+        wt.lock_tree_write()
+        self.addCleanup(wt.unlock)
         self.assertEqual(len(wt.inventory), 1)
         open('b1/a', 'wb').write('a test\n')
         wt.add('a')
         self.assertEqual(len(wt.inventory), 2)
+        wt.flush() # workaround revert doing wt._write_inventory for now.
         os.unlink('b1/a')
         wt.revert([])
         self.assertEqual(len(wt.inventory), 1)

=== modified file 'bzrlib/tests/test_smart_add.py'
--- a/bzrlib/tests/test_smart_add.py	2006-09-10 19:04:48 +0000
+++ b/bzrlib/tests/test_smart_add.py	2007-03-01 05:20:56 +0000
@@ -114,8 +114,6 @@
         wt = self.make_branch_and_tree('.')
         self.build_tree(['file'])
         smart_add_tree(wt, ['file'], save=False)
-        self.assertNotEqual(wt.path2id('file'), None, "No id added for 'file'")
-        wt.read_working_inventory()
         self.assertEqual(wt.path2id('file'), None)
 
     def test_add_dry_run(self):
@@ -258,7 +256,9 @@
                               'added dir1/file2 with id file-dir1%file2\n',
                               'added file1 with id file-file1\n',
                              ], lines)
-        self.assertEqual([('', wt.inventory.root.file_id),
+        wt.lock_read()
+        self.addCleanup(wt.unlock)
+        self.assertEqual([('', wt.path2id('')),
                           ('dir1', 'directory-dir1'),
                           ('dir1/file2', 'file-dir1%file2'),
                           ('file1', 'file-file1'),
@@ -341,6 +341,8 @@
         # These should get newly generated ids
         c_id = new_tree.path2id('c')
         self.assertNotEqual(None, c_id)
+        self.base_tree.lock_read()
+        self.addCleanup(self.base_tree.unlock)
         self.failIf(c_id in self.base_tree)
 
         d_id = new_tree.path2id('subdir/d')
@@ -364,6 +366,8 @@
         # matching path or child of 'subby'.
         a_id = new_tree.path2id('subby/a')
         self.assertNotEqual(None, a_id)
+        self.base_tree.lock_read()
+        self.addCleanup(self.base_tree.unlock)
         self.failIf(a_id in self.base_tree)
 
 
@@ -383,6 +387,8 @@
         osutils.normalized_filename = osutils._accessible_normalized_filename
         try:
             smart_add_tree(self.wt, [u'a\u030a'])
+            self.wt.lock_read()
+            self.addCleanup(self.wt.unlock)
             self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
                     [(path, ie.kind) for path,ie in 
                         self.wt.inventory.iter_entries()])
@@ -395,6 +401,8 @@
         osutils.normalized_filename = osutils._accessible_normalized_filename
         try:
             smart_add_tree(self.wt, [])
+            self.wt.lock_read()
+            self.addCleanup(self.wt.unlock)
             self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
                     [(path, ie.kind) for path,ie in 
                         self.wt.inventory.iter_entries()])

=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py	2007-02-17 20:21:42 +0000
+++ b/bzrlib/tests/test_transform.py	2007-03-01 10:14:03 +0000
@@ -21,6 +21,7 @@
 from bzrlib import (
     errors,
     generate_ids,
+    symbol_versioning,
     tests,
     urlutils,
     )
@@ -525,10 +526,9 @@
         create.new_file('vfile', root, 'myfile-text', 'myfile-id')
         create.new_file('uvfile', root, 'othertext')
         create.apply()
-        self.assertEqual(find_interesting(wt, wt, ['vfile']),
-                         set(['myfile-id']))
-        self.assertRaises(PathsNotVersionedError, find_interesting, wt, wt,
-                          ['uvfile'])
+        result = self.applyDeprecated(symbol_versioning.zero_fifteen,
+            find_interesting, wt, wt, ['vfile'])
+        self.assertEqual(result, set(['myfile-id']))
 
     def test_set_executability_order(self):
         """Ensure that executability behaves the same, no matter what order.

=== modified file 'bzrlib/tests/workingtree_implementations/test_workingtree.py'
--- a/bzrlib/tests/workingtree_implementations/test_workingtree.py	2007-02-26 04:44:45 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_workingtree.py	2007-03-01 10:14:03 +0000
@@ -758,3 +758,28 @@
             self.assertEqual(expected_results, list(tree.walkdirs()))
         finally:
             tree.unlock()
+
+    def test_path2id(self):
+        # smoke test for path2id
+        tree = self.make_branch_and_tree('.')
+        self.build_tree(['foo'])
+        tree.add(['foo'], ['foo-id'])
+        self.assertEqual('foo-id', tree.path2id('foo'))
+        # the next assertion is for backwards compatability with WorkingTree3,
+        # though its probably a bad idea, it makes things work. Perhaps
+        # it should raise a deprecation warning?
+        self.assertEqual('foo-id', tree.path2id('foo/'))
+
+    def test_filter_unversioned_files(self):
+        # smoke test for filter_unversioned_files
+        tree = self.make_branch_and_tree('.')
+        paths = ['here-and-versioned', 'here-and-not-versioned',
+            'not-here-and-versioned', 'not-here-and-not-versioned']
+        tree.add(['here-and-versioned', 'not-here-and-versioned'],
+            kinds=['file', 'file'])
+        self.build_tree(['here-and-versioned', 'here-and-not-versioned'])
+        tree.lock_read()
+        self.addCleanup(tree.unlock)
+        self.assertEqual(
+            set(['not-here-and-not-versioned', 'here-and-not-versioned']),
+            tree.filter_unversioned_files(paths))

=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py	2007-02-26 02:56:24 +0000
+++ b/bzrlib/transform.py	2007-03-01 10:14:03 +0000
@@ -34,6 +34,7 @@
 from bzrlib.osutils import (file_kind, supports_executable, pathjoin, lexists,
                             delete_any)
 from bzrlib.progress import DummyProgress, ProgressPhase
+from bzrlib.symbol_versioning import deprecated_function, zero_fifteen
 from bzrlib.trace import mutter, warning
 from bzrlib import tree
 import bzrlib.ui
@@ -1112,6 +1113,18 @@
       it is silently replaced.
     - Otherwise, conflict resolution will move the old file to 'oldname.moved'.
     """
+    wt.lock_tree_write()
+    try:
+        tree.lock_read()
+        try:
+            return _build_tree(tree, wt)
+        finally:
+            tree.unlock()
+    finally:
+        wt.unlock()
+
+def _build_tree(tree, wt):
+    """See build_tree."""
     if len(wt.inventory) > 1:  # more than just a root
         raise errors.WorkingTreeAlreadyPopulated(base=wt.basedir)
     file_trans_id = {}
@@ -1266,10 +1279,21 @@
         tt.set_executability(entry.executable, trans_id)
 
 
+ at deprecated_function(zero_fifteen)
 def find_interesting(working_tree, target_tree, filenames):
-    """Find the ids corresponding to specified filenames."""
-    trees = (working_tree, target_tree)
-    return tree.find_ids_across_trees(filenames, trees)
+    """Find the ids corresponding to specified filenames.
+    
+    Deprecated: Please use tree1.paths2ids(filenames, [tree2]).
+    """
+    working_tree.lock_read()
+    try:
+        target_tree.lock_read()
+        try:
+            return working_tree.paths2ids(filenames, [target_tree])
+        finally:
+            target_tree.unlock()
+    finally:
+        working_tree.unlock()
 
 
 def change_entry(tt, file_id, working_tree, target_tree, 

=== modified file 'bzrlib/tree.py'
--- a/bzrlib/tree.py	2007-03-01 04:07:42 +0000
+++ b/bzrlib/tree.py	2007-03-01 10:14:03 +0000
@@ -304,7 +304,7 @@
         pass
 
     def filter_unversioned_files(self, paths):
-        """Filter out paths that are not versioned.
+        """Filter out paths that are versioned.
 
         :return: set of paths.
         """
@@ -464,58 +464,6 @@
     specified_path_ids = _find_ids_across_trees(filenames, trees,
         require_versioned)
     return _find_children_across_trees(specified_path_ids, trees)
-#    specified_ids = [id for path, id in _find_path_ids_across_trees(filenames, trees, require_versioned)]
-#    return _find_children_across_trees(specified_ids, trees)
-
-def find_path_ids_across_trees(filenames, trees, require_versioned=True):
-    """Find the paths and ids corresponding to specified filenames.
-    
-    All matches in all trees will be used, and all children of matched
-    directories will be included
-
-    :param filenames: The filenames to find file_ids for
-    :param trees: The trees to find file_ids within
-    :param require_versioned: if true, all specified filenames must occur in
-        at least one tree.
-    :return: a set of (path, file ids) for the specified filenames and their
-        children. The returned path is the path of the id in the first tree
-        that contains it. This matters when files have been moved 
-    """
-    if not filenames:
-        return set()
-    # This function needs to know the ids for filenames in all trees, then
-    # search for those same files and children in all the other trees.
-    # it is complicated by the same path in two trees being able to have
-    # different ids, which might both be present in both trees.
-    # consider two trees, which have had 'mv foo bar' and 'mv baz foo' done
-    # in this case, a diff of 'foo' should should changes to both the current
-    # 'bar' and the current 'foo' which was baz. Its arguable that if 
-    # the situation is 'mv parent/foo bar' and 'mv baz parent/foo', that 
-    # we should return the current bar and the current parent/foo' - at the 
-    # moment we do, but we loop around all ids and all trees: I*T checks.
-    
-    # Updating this algorithm to be fast in the common case:
-    # nothing has moved, all files have the same id in parent, child and there
-    # are only two trees (or one is working tree and the others are parents).
-    # walk the dirstate. as we find each path, gather the paths of that
-    # id in all trees. add a mapping from the id to the path in those trees.
-    # now lookup children by id, again in all trees; for these trees that
-    # nothing has moved in, the id->path mapping will allow us to find the
-    # parent trivially. To answer 'has anything been moved' in one of the
-    # dirstate parent trees though, we will need to stare harder at it.
-
-    #  Now, given a path index, that is trivial for any one tree, and given
-    #  that we can ask for additional data from a dirstate tree, its a single
-    #  pass, though it will require scanning the entire tree to find paths
-    #  that were at the current location.
-    # ideal results?: There are three things: tree, path, id. Pathologically
-    # we can have completely disjoint ids for each tree; but we cannot have 
-    # disjoin paths for each tree, except if we scan each tree for the 
-    # different ids from other trees.
-
-    specified_path_ids = _find_ids_across_trees(filenames, trees,
-        require_versioned)
-    return _find_path_id_children_across_trees(specified_path_ids, trees)
 
 
 def _find_ids_across_trees(filenames, trees, require_versioned):

=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py	2007-03-01 04:07:42 +0000
+++ b/bzrlib/workingtree.py	2007-03-01 10:14:03 +0000
@@ -620,7 +620,7 @@
             mode = os.lstat(self.abspath(path)).st_mode
             return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
 
-    @needs_write_lock
+    @needs_tree_write_lock
     def _add(self, files, ids, kinds):
         """See MutableTree._add."""
         # TODO: Re-adding a file that is removed in the working copy
@@ -2706,9 +2706,11 @@
 # formats which have no format string are not discoverable
 # and not independently creatable, so are not registered.
 __default_format = WorkingTreeFormat3()
+## __default_format = WorkingTreeFormat4()
 WorkingTreeFormat.register_format(__default_format)
 WorkingTreeFormat.register_format(WorkingTreeFormat4())
 WorkingTreeFormat.register_format(WorkingTreeFormatAB1())
+## WorkingTreeFormat.register_format(WorkingTreeFormat3())
 WorkingTreeFormat.set_default_format(__default_format)
 # formats which have no format string are not discoverable
 # and not independently creatable, so are not registered.

=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py	2007-03-01 09:02:16 +0000
+++ b/bzrlib/workingtree_4.py	2007-03-01 10:14:03 +0000
@@ -174,7 +174,17 @@
             # - on the first access it will be gathered, and we can
             # always change this once tests are all passing.
             state.add(f, file_id, kind, None, '')
+        self._make_dirty(reset_inventory=True)
+
+    def _make_dirty(self, reset_inventory):
+        """Make the tree state dirty.
+
+        :param reset_inventory: True if the cached inventory should be removed
+            (presuming there is one).
+        """
         self._dirty = True
+        if reset_inventory and self._inventory is not None:
+            self._inventory = None
 
     @needs_tree_write_lock
     def add_reference(self, sub_tree):
@@ -253,7 +263,7 @@
         return self._dirstate
 
     def filter_unversioned_files(self, paths):
-        """Filter out paths that are not versioned.
+        """Filter out paths that are versioned.
 
         :return: set of paths.
         """
@@ -262,13 +272,13 @@
         # results of each bisect in further still
         paths = sorted(paths)
         result = set()
-        state = self.current_dirstate()
+        STate = self.current_dirstate()
         # TODO we want a paths_to_dirblocks helper I think
         for path in paths:
             dirname, basename = os.path.split(path.encode('utf8'))
             _, _, _, path_is_versioned = state._get_block_entry_index(
                 dirname, basename, 0)
-            if path_is_versioned:
+            if not path_is_versioned:
                 result.add(path)
         return result
 
@@ -692,7 +702,7 @@
                 raise
             result.append((from_rel, to_rel))
             state._dirblock_state = dirstate.DirState.IN_MEMORY_MODIFIED
-            self._dirty = True
+            self._make_dirty(reset_inventory=False)
 
         return result
 
@@ -707,6 +717,7 @@
     @needs_read_lock
     def path2id(self, path):
         """Return the id for path in this tree."""
+        path = path.strip('/')
         entry = self._get_entry(path=path)
         if entry == (None, None):
             return None
@@ -946,13 +957,14 @@
                     self.branch.repository.revision_tree(None)))
                 ghosts.append(rev_id)
         dirstate.set_parent_trees(real_trees, ghosts=ghosts)
-        self._dirty = True
+        self._make_dirty(reset_inventory=False)
 
     def _set_root_id(self, file_id):
         """See WorkingTree.set_root_id."""
         state = self.current_dirstate()
         state.set_path_id('', file_id)
-        self._dirty = state._dirblock_state == dirstate.DirState.IN_MEMORY_MODIFIED
+        if state._dirblock_state == dirstate.DirState.IN_MEMORY_MODIFIED:
+            self._make_dirty(reset_inventory=True)
 
     def unlock(self):
         """Unlock in format 4 trees needs to write the entire dirstate."""
@@ -1048,7 +1060,7 @@
             block_index += 1
         if ids_to_unversion:
             raise errors.NoSuchId(self, iter(ids_to_unversion).next())
-        self._dirty = True
+        self._make_dirty(reset_inventory=False)
         # have to change the legacy inventory too.
         if self._inventory is not None:
             for file_id in file_ids:
@@ -1059,10 +1071,13 @@
         """Write inventory as the current inventory."""
         assert not self._dirty, "attempting to write an inventory when the dirstate is dirty will cause data loss"
         self.current_dirstate().set_state_from_inventory(inv)
-        self._dirty = True
+        self._make_dirty(reset_inventory=False)
+        if self._inventory is not None:
+            self._inventory = inv
         self.flush()
 
 
+
 class WorkingTreeFormat4(WorkingTreeFormat3):
     """The first consolidated dirstate working tree format.
 
@@ -1115,20 +1130,24 @@
                          _control_files=control_files)
         wt._new_tree()
         wt.lock_tree_write()
+        state._validate()
         try:
             if revision_id in (None, NULL_REVISION):
                 wt._set_root_id(generate_ids.gen_root_id())
                 wt.flush()
+                wt.current_dirstate()._validate()
             else:
                 wt.set_last_revision(revision_id)
                 wt.flush()
                 basis = wt.basis_tree()
                 basis.lock_read()
                 state = wt.current_dirstate()
+                state._validate()
                 # if the basis has a root id we have to use that; otherwise we use
                 # a new random one
                 basis_root_id = basis.get_root_id()
                 if basis_root_id is not None:
+                    state._validate()
                     wt._set_root_id(basis_root_id)
                     wt.flush()
                 transform.build_tree(basis, wt)
@@ -1566,7 +1585,7 @@
                     all_versioned = False
                     break
             if not all_versioned:
-                raise errors.PathsNotVersionedError(paths)
+                raise errors.PathsNotVersionedError(specific_files)
         # -- remove redundancy in supplied specific_files to prevent over-scanning --
         search_specific_files = set()
         for path in specific_files:
@@ -1943,12 +1962,15 @@
                         new_executable = bool(
                             stat.S_ISREG(current_path_info[3].st_mode)
                             and stat.S_IEXEC & current_path_info[3].st_mode)
-                        yield (None, current_path_info[0], True,
-                               (False, False),
-                               (None, None),
-                               (None, current_path_info[1]),
-                               (None, current_path_info[2]),
-                               (None, new_executable))
+                        pass # unversioned file support not added to the
+                        # _iter_changes api yet - breaks status amongst other
+                        # things.
+#                        yield (None, current_path_info[0], True,
+#                               (False, False),
+#                               (None, None),
+#                               (None, current_path_info[1]),
+#                               (None, current_path_info[2]),
+#                               (None, new_executable))
                     elif current_path_info is None:
                         # no path is fine: the per entry code will handle it.
                         for result in _process_entry(current_entry, current_path_info):




More information about the bazaar-commits mailing list