[BUG] can't rename subtrees

John Arbash Meinel john at arbash-meinel.com
Sun Apr 1 01:56:42 BST 2007


Aaron Bentley wrote:
> Hi all,
> 
> I've found a bug in rename_one with dirstate trees().  If you try to
> rename a subtree, you get this:
> 

...

>   File "/home/abentley/bzr/bzr.dev/bzrlib/dirstate.py", line 963, in
> _entry_to_line
>     return '\0'.join(entire_entry)
> 

You forgot to include the actual error :) It is:
  File "/Users/jameinel/dev/bzr/bzr.dev/bzrlib/dirstate.py", line 963,
in _entry_to_line
    return '\0'.join(entire_entry)
TypeError: sequence item 4: expected string, NoneType found

I can confirm that you test causes this to happen.

Looking at the 'entire_entry' I have:

['', 'subtree2', 'tree_root-20070401004331-q7m0utsxyscdaui1-3', 't',
None, '0', 'n', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'r', 'subtree', '0',
'n', '']

Which is
parent_dir = ''
name = 'subtree2'
file_id = 'tree_root-....'
kind = 't' (subtree)
fingerprint = None # This is the bug
size = '0'
executable = 'n'
tree_specific_string = 'xx...' # ...

parent1_minikind = 'r' #renamed
parent1_path = 'subtree' # parent1 fingerprint is path when renamed
parent1_size = '0'
parent1_exec = 'n'
parent1_tree_specific = ''


the 'tree_specific_string' is either a 'packed_stat' for working trees,
or 'last_changed_revision' for revision trees.

But 'fingerprint' is the bug. It is usually either a sha1 (files) or
symlink target (symlinks), or '' (directories).

I think for nested trees, it could either be '', or the
last-committed-revision (but we could always just pull that out of the
actual nested tree).


Now, the code I see seems to be doing:

if kind == 'tree-reference':
  fingerprint = inv_entry.reference_revision or ''

But I also see this code in 'set_state_from_inventory':
                if current_new_minikind == 't':
                    fingerprint = current_new[1].reference_revision
                else:
                    fingerprint = ''

So I think we want:
              fingerprint = current_new[1].reference_revision or ''


This passes for me:
=== modified file 'bzrlib/dirstate.py'
--- bzrlib/dirstate.py  2007-03-21 04:14:35 +0000
+++ bzrlib/dirstate.py  2007-04-01 00:56:15 +0000
@@ -1959,7 +1959,7 @@
                 current_new_minikind = \
                     DirState._kind_to_minikind[current_new[1].kind]
                 if current_new_minikind == 't':
-                    fingerprint = current_new[1].reference_revision
+                    fingerprint = current_new[1].reference_revision or ''
                 else:
                     fingerprint = ''
             else:

=== modified file 'bzrlib/tests/test_revert.py'
--- bzrlib/tests/test_revert.py 2007-03-01 01:02:30 +0000
+++ bzrlib/tests/test_revert.py 2007-04-01 00:41:49 +0000
@@ -108,3 +108,14 @@
         tt.apply()
         transform.revert(tree, tree.basis_tree(), [])
         self.assertTrue(tree.is_executable('newfile-id'))
+
+    def test_revert_subtree(self):
+        tree = self.make_branch_and_tree('tree',
+            format='dirstate-with-subtree')
+        subtree = self.make_branch_and_tree('tree/subtree',
+            format='dirstate-with-subtree')
+        self.build_tree(['tree/subtree/file'])
+        tree.add_reference(subtree)
+        subtree.add('file')
+        tree.commit('create nested tree')
+        tree.rename_one('subtree', 'subtree2')


John
=:->



More information about the bazaar mailing list