Rev 5876: Simplify a bit. Handle that when a directory is added, we need to add its block. in http://bazaar.launchpad.net/~jameinel/bzr/2.4-set-parent-trees-delta-282941
John Arbash Meinel
john at arbash-meinel.com
Thu May 19 12:55:07 UTC 2011
At http://bazaar.launchpad.net/~jameinel/bzr/2.4-set-parent-trees-delta-282941
------------------------------------------------------------
revno: 5876
revision-id: john at arbash-meinel.com-20110519125458-9ubn8sn7x7309s4s
parent: john at arbash-meinel.com-20110519112716-cgk61q0iwa104bc2
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.4-set-parent-trees-delta-282941
timestamp: Thu 2011-05-19 14:54:58 +0200
message:
Simplify a bit. Handle that when a directory is added, we need to add its block.
Handle that when a directory is removed, if it is the last reference to that path,
the block should also be removed.
I'm going to try simplying the remove code now.
-------------- next part --------------
=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py 2011-05-19 11:19:42 +0000
+++ b/bzrlib/dirstate.py 2011-05-19 12:54:58 +0000
@@ -1666,13 +1666,12 @@
for old_path, new_path, file_id, new_details, real_add in adds:
dirname, basename = osutils.split(new_path)
entry_key = st(dirname, basename, file_id)
- try:
- # TODO: consider if we need add_if_missing=True
- _, block = self._find_block(entry_key)
- except errors.NotVersionedError, e:
+ block_index, present = self._find_block_index_from_key(entry_key)
+ if not present:
self._raise_invalid(new_path, file_id,
- "Got a not-versioned error trying to add path."
- " Is the parent missing? %s" % (e,))
+ "Unable to find block for this record."
+ " Was the parent added?")
+ block = self._dirblocks[block_index][1]
entry_index, present = self._find_entry_index(entry_key, block)
if real_add:
if old_path is not None:
@@ -1761,6 +1760,10 @@
elif active_kind == 'r':
raise NotImplementedError()
+ new_kind = new_details[0]
+ if new_kind == 'd':
+ self._ensure_block(block_index, entry_index, new_path)
+
def _update_basis_apply_changes(self, changes):
"""Apply a sequence of changes to tree 1 during update_basis_by_delta.
@@ -1821,6 +1824,18 @@
# state, and it is now deleted in the basis state,
# so just remove the record entirely
del self._dirblocks[block_index][1][entry_index]
+ old_kind = entry[1][1][0]
+ if old_kind == 'd':
+ # This was a directory, and the active tree says it
+ # doesn't exist, and now the basis tree says it doesn't
+ # exist. Remove its dirblock if present
+ (dir_block_index,
+ present) = self._find_block_index_from_key(
+ (old_path, '', ''))
+ if present:
+ assert not self._dirblocks[dir_block_index][1],\
+ "dirblock queued for deletion is not empty"
+ del self._dirblocks[dir_block_index]
elif active_kind == 'r':
# The active record is found at a different location
# we can consider it deleted *here*, but we have to update
@@ -1854,22 +1869,29 @@
"The file id was deleted but its children were "
"not deleted.")
else:
- if active_kind == 'a':
+ if active_kind in 'ar':
# The active tree doesn't have this file_id.
# The basis tree is changing this record. If this is a
# rename, then we don't want the record here at all
# anymore. If it is just an in-place change, we want the
# record here, but we'll add it if we need to. So we just
# delete it
- del self._dirblocks[block_index][1][entry_index]
- elif active_kind == 'r':
- # The active tree has this record at a different location.
- # implement the rename
- active_path_utf8 = entry[1][0][1]
- rename_targets[old_path] = active_path_utf8
- active_entry = self._get_entry(0, file_id, active_path_utf8)
- active_entry[1][1] = null
- del self._dirblocks[block_index][1][entry_index]
+ if active_kind == 'r':
+ active_path = entry[1][0][1]
+ rename_targets[old_path] = active_path
+ active_entry = self._get_entry(0, file_id, active_path)
+ active_entry[1][1] = null
+ del self._dirblocks[block_index][1][entry_index]
+ old_kind = entry[1][1][0]
+ if old_kind == 'd':
+ # This was a directory, and the active tree says it
+ # doesn't exist, and now the basis tree says it doesn't
+ # exist. Remove its dirblock if present
+ (dir_block_index,
+ present) = self._find_block_index_from_key(
+ (old_path, '', ''))
+ if present and not self._dirblocks[dir_block_index][1]:
+ del self._dirblocks[dir_block_index]
else:
# There is still an active record, so just mark this
# removed.
=== modified file 'bzrlib/tests/test_dirstate.py'
--- a/bzrlib/tests/test_dirstate.py 2011-05-19 11:27:16 +0000
+++ b/bzrlib/tests/test_dirstate.py 2011-05-19 12:54:58 +0000
@@ -2457,7 +2457,7 @@
dir_id = osutils.basename(dirname) + '-id'
if is_dir:
ie = inventory.InventoryDirectory(file_id, basename, dir_id)
- dir_ids[path] = dir_id
+ dir_ids[path] = file_id
else:
ie = inventory.InventoryFile(file_id, basename, dir_id)
ie.text_size = 0
@@ -2672,6 +2672,44 @@
target=[('file', 'file-id'),
('other-file', 'file-id-2')])
+ def test_rename_directory_with_contents(self):
+ state = self.assertUpdate( # active matches basis
+ active=[('dir1/', 'dir-id'),
+ ('dir1/file', 'file-id')],
+ basis= [('dir1/', 'dir-id'),
+ ('dir1/file', 'file-id')],
+ target=[('dir2/', 'dir-id'),
+ ('dir2/file', 'file-id')])
+ state = self.assertUpdate( # active matches target
+ active=[('dir2/', 'dir-id'),
+ ('dir2/file', 'file-id')],
+ basis= [('dir1/', 'dir-id'),
+ ('dir1/file', 'file-id')],
+ target=[('dir2/', 'dir-id'),
+ ('dir2/file', 'file-id')])
+ state = self.assertUpdate( # active empty
+ active=[],
+ basis= [('dir1/', 'dir-id'),
+ ('dir1/file', 'file-id')],
+ target=[('dir2/', 'dir-id'),
+ ('dir2/file', 'file-id')])
+ state = self.assertUpdate( # active present at other location
+ active=[('dir3/', 'dir-id'),
+ ('dir3/file', 'file-id')],
+ basis= [('dir1/', 'dir-id'),
+ ('dir1/file', 'file-id')],
+ target=[('dir2/', 'dir-id'),
+ ('dir2/file', 'file-id')])
+ state = self.assertUpdate( # active has different ids
+ active=[('dir1/', 'dir1-id'),
+ ('dir1/file', 'file1-id'),
+ ('dir2/', 'dir2-id'),
+ ('dir2/file', 'file2-id')],
+ basis= [('dir1/', 'dir-id'),
+ ('dir1/file', 'file-id')],
+ target=[('dir2/', 'dir-id'),
+ ('dir2/file', 'file-id')])
+
def test_invalid_file_not_present(self):
state = self.assertBadDelta(
active=[('file', 'file-id')],
More information about the bazaar-commits
mailing list