Rev 2424: (broken) merge dirstate branch in http://sourcefrog.net/bzr/dirstate-plus-subtree

Martin Pool mbp at sourcefrog.net
Thu Mar 1 12:28:42 GMT 2007


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

------------------------------------------------------------
revno: 2424
revision-id: mbp at sourcefrog.net-20070301122840-6exf6ilcew2mcn1g
parent: mbp at sourcefrog.net-20070301101403-v2ey2v53rhzprmds
parent: mbp at sourcefrog.net-20070301112142-blqdo0tmp0loms7y
parent: mbp at sourcefrog.net-20070301120450-umm5g6q0xqqt7296
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: dirstate-plus-subtree
timestamp: Thu 2007-03-01 23:28:40 +1100
message:
  (broken) merge dirstate branch
modified:
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/dirstate.py             dirstate.py-20060728012006-d6mvoihjb3je9peu-1
  bzrlib/tests/blackbox/test_info.py test_info.py-20060215045507-bbdd2d34efab9e0a
  bzrlib/tests/blackbox/test_mv.py test_mv.py-20060705114902-33tkxz0o9cdshemo-1
  bzrlib/tests/repository_implementations/test_iter_reverse_revision_history.py test_iter_reverse_re-20070217015036-spu7j5ggch7pbpyd-1
  bzrlib/tests/test_dirstate.py  test_dirstate.py-20060728012006-d6mvoihjb3je9peu-2
  bzrlib/tests/workingtree_implementations/test_add.py test_add.py-20070226165239-4vo178spkrnhavc7-1
  bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
    ------------------------------------------------------------
    revno: 2406.1.78
    merged: mbp at sourcefrog.net-20070301120450-umm5g6q0xqqt7296
    parent: robertc at robertcollins.net-20070301115646-t40d51cvqsrok6b5
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: dirstate-robert
    timestamp: Thu 2007-03-01 23:04:50 +1100
    message:
      Add DirState._validate and call from the tests
    ------------------------------------------------------------
    revno: 2406.1.77
    merged: robertc at robertcollins.net-20070301115646-t40d51cvqsrok6b5
    parent: robertc at robertcollins.net-20070301115027-7ch3pnc922va6fr5
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate.dogfood
    timestamp: Thu 2007-03-01 22:56:46 +1100
    message:
      Make test_iter_reverse_revision_history flush the working tree after commit before merging, as merge still does _write_inventory.
    ------------------------------------------------------------
    revno: 2406.1.76
    merged: robertc at robertcollins.net-20070301115027-7ch3pnc922va6fr5
    parent: mbp at sourcefrog.net-20070301112142-blqdo0tmp0loms7y
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate.dogfood
    timestamp: Thu 2007-03-01 22:50:27 +1100
    message:
      Fix _get_entry, which got broken at some point, this fixes tests now, so it should not be breakable in future.
    ------------------------------------------------------------
    revno: 2406.1.75
    merged: mbp at sourcefrog.net-20070301112142-blqdo0tmp0loms7y
    parent: robertc at robertcollins.net-20070301111653-xz97hibpktk2y5co
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: dirstate-robert
    timestamp: Thu 2007-03-01 22:21:42 +1100
    message:
      WorkingTree._add only needs to lock the tree - avoids lock reentry error
    ------------------------------------------------------------
    revno: 2406.1.74
    merged: robertc at robertcollins.net-20070301111653-xz97hibpktk2y5co
    parent: robertc at robertcollins.net-20070301095035-qq2jbr6p4ggdlu1t
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate.dogfood
    timestamp: Thu 2007-03-01 22:16:53 +1100
    message:
      Test adding of roots to trees, it was broken on WorkingTree4.
    ------------------------------------------------------------
    revno: 2406.1.73
    merged: robertc at robertcollins.net-20070301095035-qq2jbr6p4ggdlu1t
    parent: robertc at robertcollins.net-20070301094642-jjtzsx00wz14j110
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate.dogfood
    timestamp: Thu 2007-03-01 20:50:35 +1100
    message:
      Fix info for the new default format - these tests really need refactoring.
    ------------------------------------------------------------
    revno: 2406.1.72
    merged: robertc at robertcollins.net-20070301094642-jjtzsx00wz14j110
    parent: robertc at robertcollins.net-20070301093426-yavn95x00rpc5nyb
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate.dogfood
    timestamp: Thu 2007-03-01 20:46:42 +1100
    message:
      Update cmd_deleted to lock around inventory access.
    ------------------------------------------------------------
    revno: 2406.1.71
    merged: robertc at robertcollins.net-20070301093426-yavn95x00rpc5nyb
    parent: robertc at robertcollins.net-20070301085003-1k4kx7hxz8ce5x8p
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: dirstate.dogfood
    timestamp: Thu 2007-03-01 20:34:26 +1100
    message:
      Fix blackbox test_mv usage of inventory, and the errors raised by workingtree4.move - though that should be made into a workingtree conformance test.
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2007-03-01 10:14:03 +0000
+++ b/bzrlib/builtins.py	2007-03-01 12:28:40 +0000
@@ -1446,14 +1446,22 @@
     @display_command
     def run(self, show_ids=False):
         tree = WorkingTree.open_containing(u'.')[0]
-        old = tree.basis_tree()
-        for path, ie in old.inventory.iter_entries():
-            if not tree.has_id(ie.file_id):
-                self.outf.write(path)
-                if show_ids:
-                    self.outf.write(' ')
-                    self.outf.write(ie.file_id)
-                self.outf.write('\n')
+        tree.lock_read()
+        try:
+            old = tree.basis_tree()
+            old.lock_read()
+            try:
+                for path, ie in old.inventory.iter_entries():
+                    if not tree.has_id(ie.file_id):
+                        self.outf.write(path)
+                        if show_ids:
+                            self.outf.write(' ')
+                            self.outf.write(ie.file_id)
+                        self.outf.write('\n')
+            finally:
+                old.unlock()
+        finally:
+            tree.unlock()
 
 
 class cmd_modified(Command):

=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py	2007-03-01 10:14:03 +0000
+++ b/bzrlib/dirstate.py	2007-03-01 12:28:40 +0000
@@ -228,7 +228,11 @@
     specific, and if it is how we detect/parameterise that.
     """
 
-    _kind_to_minikind = {'absent':'a', 'file':'f', 'directory':'d', 'relocated':'r',
+    _kind_to_minikind = {
+            'absent':'a',
+            'file':'f',
+            'directory':'d',
+            'relocated':'r',
             'symlink': 'l',
             'tree-reference': 't',
         }
@@ -342,10 +346,19 @@
             kind = DirState._minikind_to_kind[file_id_entry[1][0][0]]
             info = '%s:%s' % (kind, path)
             raise errors.DuplicateFileId(file_id, info)
-        entry_key = (dirname, basename, file_id)
-        self._read_dirblocks_if_needed()
-        block_index, present = self._find_block_index_from_key(entry_key)
-        if not present:
+        first_key = (dirname, basename, '')
+        block_index, present = self._find_block_index_from_key(first_key)
+        if present:
+            # check the path is not in the tree
+            block = self._dirblocks[block_index][1]
+            entry_index, _ = self._find_entry_index(first_key, block)
+            while (entry_index < len(block) and 
+                block[entry_index][0][0:2] == first_key[0:2]):
+                if block[entry_index][1][0][0] not in 'ar':
+                    # this path is in the dirstate in the current tree.
+                    raise Exception, "adding already added path!"
+                entry_index += 1
+        else:
             # The block where we want to put the file is not present. But it
             # might be because the directory was empty, or not loaded yet. Look
             # for a parent entry, if not found, raise NotVersionedError
@@ -356,6 +369,7 @@
                 raise errors.NotVersionedError(path, str(self))
             self._ensure_block(parent_block_idx, parent_entry_idx, dirname)
         block = self._dirblocks[block_index][1]
+        entry_key = (dirname, basename, file_id)
         if stat is None:
             size = 0
             packed_stat = DirState.NULLSTAT
@@ -1205,27 +1219,30 @@
             if not possible_keys:
                 return None, None
             for key in possible_keys:
-                (block_index, entry_index, dir_present,
-                 file_present) = self._get_block_entry_index(key[0], key[1],
-                                                             tree_index)
-                if file_present:
+                block_index, present = \
+                    self._find_block_index_from_key(key)
+                # strange, probably indicates an out of date
+                # id index - for now, allow this.
+                if not present:
+                    continue
+                # WARNING: DO not change this code to use _get_block_entry_index
+                # as that function is not suitable: it does not use the key
+                # to lookup, and thus the wront coordinates are returned.
+                block = self._dirblocks[block_index][1]
+                entry_index, present = self._find_entry_index(key, block)
+                if present:
                     entry = self._dirblocks[block_index][1][entry_index]
-                    # _get_block_entry_index only returns entries that are not
-                    # absent in the current tree. _get_id_index will return
-                    # both locations for a renamed file.  It is possible that a
-                    # new file was added at the same location that the old file
-                    # was renamed away. So _get_block_entry_index will actually
-                    # match the new file, skipping the fact that the real entry
-                    # we want is the rename. By just continuing here, we should
-                    # find the record at the target location, because
-                    # _get_id_index should return all locations.
-                    if entry[0][2] != fileid_utf8:
-                        continue
-                    assert entry[1][tree_index][0] not in ('a', 'r')
-                    assert key == entry[0], ('We were told that %s would be at'
-                            ' %s, %s, but we found %s' % (key, block_index,
-                                                          entry_index, entry))
-                    return entry
+                    if entry[1][tree_index][0] in 'fdl':
+                        # this is the result we are looking for: the  
+                        # real home of this file_id in this tree.
+                        return entry
+                    if entry[1][tree_index][0] == 'a':
+                        # there is no home for this entry in this tree
+                        return None, None
+                    assert entry[1][tree_index][0] == 'r'
+                    real_path = entry[1][tree_index][1]
+                    return self._get_entry(tree_index, fileid_utf8=fileid_utf8,
+                        path_utf8=real_path)
             return None, None
 
     @staticmethod
@@ -1824,8 +1841,6 @@
             # Remove it, its meaningless.
             block = self._find_block(current_old[0])
             entry_index, present = self._find_entry_index(current_old[0], block[1])
-            if not present:
-                import pdb;pdb.set_trace()
             assert present, 'could not find entry for %s' % (current_old,)
             block[1].pop(entry_index)
             # if we have an id_index in use, remove this key from it for this id.
@@ -1978,9 +1993,6 @@
             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)

=== modified file 'bzrlib/tests/blackbox/test_info.py'
--- a/bzrlib/tests/blackbox/test_info.py	2007-02-15 14:08:23 +0000
+++ b/bzrlib/tests/blackbox/test_info.py	2007-03-01 09:50:35 +0000
@@ -199,7 +199,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: Branch format 5
     repository: %s
 
@@ -245,7 +245,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: Branch format 4
     repository: Weave repository format 6
 
@@ -381,7 +381,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: Branch format 5
     repository: %s
 
@@ -426,7 +426,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: Branch format 4
     repository: Weave repository format 6
 
@@ -565,7 +565,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: %s
     repository: %s
 
@@ -609,7 +609,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: %s
     repository: %s
 
@@ -650,7 +650,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: %s
     repository: %s
 
@@ -697,7 +697,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: %s
     repository: %s
 
@@ -828,7 +828,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: %s
     repository: %s
 
@@ -870,7 +870,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: %s
     repository: %s
 
@@ -915,7 +915,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: %s
     repository: %s
 
@@ -960,7 +960,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: %s
     repository: %s
 
@@ -1056,7 +1056,7 @@
 
 Format:
        control: Meta directory format 1
-  working tree: Working tree format 3
+  working tree: Working tree format 4
         branch: %s
     repository: %s
 

=== modified file 'bzrlib/tests/blackbox/test_mv.py'
--- a/bzrlib/tests/blackbox/test_mv.py	2007-01-20 01:44:46 +0000
+++ b/bzrlib/tests/blackbox/test_mv.py	2007-03-01 09:34:26 +0000
@@ -111,8 +111,6 @@
         self.run_bzr('mv', 'hello.txt', 'sub2')
         self.assertMoved('hello.txt','sub2/hello.txt')
 
-        tree.read_working_inventory()
-
         self.build_tree(['sub1/'])
         tree.add(['sub1'])
         self.run_bzr('mv', 'sub2/hello.txt', 'sub1')
@@ -129,7 +127,6 @@
         os.chdir('sub1/sub2')
         self.run_bzr('mv', '../hello.txt', '.')
         self.failUnlessExists('./hello.txt')
-        tree.read_working_inventory()
 
         os.chdir('..')
         self.run_bzr('mv', 'sub2/hello.txt', '.')

=== modified file 'bzrlib/tests/repository_implementations/test_iter_reverse_revision_history.py'
--- a/bzrlib/tests/repository_implementations/test_iter_reverse_revision_history.py	2007-02-17 02:02:41 +0000
+++ b/bzrlib/tests/repository_implementations/test_iter_reverse_revision_history.py	2007-03-01 11:56:46 +0000
@@ -71,6 +71,7 @@
             tree2.commit('rev-2-4', rev_id='rev-2-4')
 
             tree1.commit('rev-1-2', rev_id='rev-1-2')
+            tree1.flush() # workaround merge using _write_inventory
             tree1.merge_from_branch(tree2.branch)
             tree1.commit('rev-1-3', rev_id='rev-1-3')
 

=== modified file 'bzrlib/tests/test_dirstate.py'
--- a/bzrlib/tests/test_dirstate.py	2007-03-01 08:33:25 +0000
+++ b/bzrlib/tests/test_dirstate.py	2007-03-01 12:04:50 +0000
@@ -75,6 +75,7 @@
         state = self.create_empty_dirstate()
         try:
             state._set_data([], dirblocks)
+            state._validate()
         except:
             state.unlock()
             raise
@@ -146,6 +147,7 @@
         dirblocks.append(('a', [e_entry, f_entry]))
         dirblocks.append(('b', [g_entry, h_entry]))
         state = dirstate.DirState.initialize('dirstate')
+        state._validate()
         try:
             state._set_data([], dirblocks)
         except:
@@ -197,6 +199,7 @@
              [('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree
              ])])
         state = dirstate.DirState.from_tree(tree, 'dirstate')
+        state._validate()
         self.check_state_with_reopen(expected_result, state)
 
     def test_1_parents_empty_to_dirstate(self):
@@ -211,6 +214,7 @@
              ])])
         state = dirstate.DirState.from_tree(tree, 'dirstate')
         self.check_state_with_reopen(expected_result, state)
+        state._validate()
 
     def test_2_parents_empty_to_dirstate(self):
         # create a parent by doing a commit
@@ -227,6 +231,7 @@
              ])])
         state = dirstate.DirState.from_tree(tree, 'dirstate')
         self.check_state_with_reopen(expected_result, state)
+        state._validate()
 
     def test_empty_unknowns_are_ignored_to_dirstate(self):
         """We should be able to create a dirstate for an empty tree."""
@@ -418,6 +423,7 @@
         finally:
             state.unlock()
         state = dirstate.DirState.on_file('dirstate')
+        state._validate()
         state.lock_read()
         try:
             self.assertEqual(expected_rows, list(state._iter_entries()))
@@ -432,6 +438,7 @@
         mt.commit('foo', rev_id='parent-revid')
         rt = mt.branch.repository.revision_tree('parent-revid')
         state = dirstate.DirState.initialize('dirstate')
+        state._validate()
         try:
             state.set_parent_trees([('parent-revid', rt)], ghosts=[])
             state.set_path_id('', 'foobarbaz')
@@ -486,7 +493,9 @@
                 ['ghost-rev'])
             # check we can reopen and use the dirstate after setting parent
             # trees.
+            state._validate()
             state.save()
+            state._validate()
         finally:
             state.unlock()
         state = dirstate.DirState.on_file('dirstate')
@@ -645,6 +654,7 @@
             state.unlock()
         state = dirstate.DirState.on_file('dirstate')
         state.lock_read()
+        state._validate()
         try:
             self.assertEqual(expected_entries, list(state._iter_entries()))
         finally:

=== modified file 'bzrlib/tests/workingtree_implementations/test_add.py'
--- a/bzrlib/tests/workingtree_implementations/test_add.py	2007-02-26 22:11:07 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_add.py	2007-03-01 11:16:53 +0000
@@ -20,6 +20,7 @@
 
 from bzrlib import (
     errors,
+    inventory,
     osutils,
     )
 
@@ -146,3 +147,14 @@
         tree.unversion(['dir-id'])
         self.assertRaises(errors.NotVersionedError,
                           tree.add, ['dir/subdir'])
+
+    def test_add_root(self):
+        # adding the root should be a no-op, or at least not 
+        # do anything whacky.
+        tree = self.make_branch_and_tree('.')
+        tree.lock_write()
+        tree.add('')
+        self.assertEqual([tree.path2id('')], list(tree))
+        # the root should have been changed to be a new unique root.
+        self.assertNotEqual(inventory.ROOT_ID, tree.path2id(''))
+        tree.unlock()

=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py	2007-03-01 10:14:03 +0000
+++ b/bzrlib/workingtree_4.py	2007-03-01 12:28:40 +0000
@@ -168,6 +168,11 @@
             f = f.strip('/')
             assert '//' not in f
             assert '..' not in f
+            if self.path2id(f):
+                # special case tree root handling.
+                if f == '' and self.path2id(f) == ROOT_ID:
+                    state.set_path_id('', generate_ids.gen_file_id(f))
+                continue
             if file_id is None:
                 file_id = generate_ids.gen_file_id(f)
             # deliberately add the file with no cached stat or sha1
@@ -239,6 +244,14 @@
             kind = 'tree-reference'
         return kind, executable, stat_value
 
+    @needs_write_lock
+    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)
+        self._make_dirty(reset_inventory=True)
+        return result
+
     def current_dirstate(self):
         """Return the current dirstate object. 
 
@@ -506,7 +519,7 @@
             state._get_block_entry_index(to_entry_dirname, to_basename, 0)
         if not entry_present:
             raise errors.BzrMoveFailedError('', to_dir,
-                errors.NotInWorkingDirectory(to_dir))
+                errors.NotVersionedError(to_dir))
         to_entry = state._dirblocks[to_entry_block_index][1][to_entry_entry_index]
         # get a handle on the block itself.
         to_block_index = state._ensure_block(




More information about the bazaar-commits mailing list