Rev 2926: Fix bug #114615 by teaching unversion() to not touch renamed entries. in http://bzr.arbash-meinel.com/branches/bzr/0.92-dev/bogus_removal_114615
John Arbash Meinel
john at arbash-meinel.com
Tue Oct 23 22:11:41 BST 2007
At http://bzr.arbash-meinel.com/branches/bzr/0.92-dev/bogus_removal_114615
------------------------------------------------------------
revno: 2926
revision-id:john at arbash-meinel.com-20071023211052-ru4vxnhwb0vpemz4
parent: john at arbash-meinel.com-20071023195147-echbf8brs44uifo4
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bogus_removal_114615
timestamp: Tue 2007-10-23 16:10:52 -0500
message:
Fix bug #114615 by teaching unversion() to not touch renamed entries.
modified:
bzrlib/dirstate.py dirstate.py-20060728012006-d6mvoihjb3je9peu-1
bzrlib/tests/workingtree_implementations/test_commit.py test_commit.py-20060421013633-1610ec2331c8190f
bzrlib/workingtree_4.py workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
-------------- next part --------------
=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py 2007-10-23 19:51:47 +0000
+++ b/bzrlib/dirstate.py 2007-10-23 21:10:52 +0000
@@ -1967,10 +1967,7 @@
# build up paths that this id will be left at after the change is made,
# so we can update their cross references in tree 0
all_remaining_keys = set()
- # If the working tree claims it is present, don't worry about it,
- # because we are removing it. But if it is a rename, we need to remove
- # the actual location.
- details = current_old[1][0]
+ # Dont check the working tree, because it's going.
for details in current_old[1][1:]:
if details[0] not in ('a', 'r'): # absent, relocated
all_remaining_keys.add(current_old[0])
@@ -2002,6 +1999,8 @@
self._find_entry_index(update_key, self._dirblocks[update_block_index][1])
assert present, 'could not find entry for %s' % (update_key,)
update_tree_details = self._dirblocks[update_block_index][1][update_entry_index][1]
+ # it must not be absent at the moment
+ assert update_tree_details[0][0] != 'a' # absent
update_tree_details[0] = DirState.NULL_PARENT_DETAILS
self._dirblock_state = DirState.IN_MEMORY_MODIFIED
return last_reference
=== modified file 'bzrlib/tests/workingtree_implementations/test_commit.py'
--- a/bzrlib/tests/workingtree_implementations/test_commit.py 2007-10-23 19:51:47 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_commit.py 2007-10-23 21:10:52 +0000
@@ -21,6 +21,7 @@
from bzrlib import (
branch,
bzrdir,
+ conflicts,
errors,
osutils,
revision as _mod_revision,
@@ -135,6 +136,64 @@
('dir2/a', 'f1-id'),
], paths)
+ def test_no_autodelete_alternate_renamed(self):
+ # Test for bug #114615
+ tree_a = self.make_branch_and_tree('A')
+ self.build_tree(['A/a/', 'A/a/m', 'A/a/n'])
+ tree_a.add(['a', 'a/m', 'a/n'], ['a-id', 'm-id', 'n-id'])
+ tree_a.commit('init')
+
+ tree_a.lock_read()
+ try:
+ root_id = tree_a.inventory.root.file_id
+ finally:
+ tree_a.unlock()
+
+ tree_b = tree_a.bzrdir.sprout('B').open_workingtree()
+ self.build_tree(['B/xyz/'])
+ tree_b.add(['xyz'], ['xyz-id'])
+ tree_b.rename_one('a/m', 'xyz/m')
+ osutils.rmtree('B/a')
+ tree_b.commit('delete in B')
+
+ paths = [(path, ie.file_id)
+ for path, ie in tree_b.iter_entries_by_dir()]
+ self.assertEqual([('', root_id),
+ ('xyz', 'xyz-id'),
+ ('xyz/m', 'm-id'),
+ ], paths)
+
+ self.build_tree_contents([('A/a/n', 'new contents for n\n')])
+ tree_a.commit('change n in A')
+
+ # Merging from A should introduce conflicts because 'n' was modified
+ # and removed, so 'a' needs to be restored.
+ num_conflicts = tree_b.merge_from_branch(tree_a.branch)
+ self.assertEqual(3, num_conflicts)
+ paths = [(path, ie.file_id)
+ for path, ie in tree_b.iter_entries_by_dir()]
+ self.assertEqual([('', root_id),
+ ('a', 'a-id'),
+ ('xyz', 'xyz-id'),
+ ('a/n.OTHER', 'n-id'),
+ ('xyz/m', 'm-id'),
+ ], paths)
+ osutils.rmtree('B/a')
+ try:
+ # bzr resolve --all
+ tree_b.set_conflicts(conflicts.ConflictList())
+ except errors.UnsupportedOperation:
+ # On WT2, set_conflicts is unsupported, but the rmtree has the same
+ # effect.
+ pass
+ tree_b.commit('autoremove a, without touching xyz/m')
+ paths = [(path, ie.file_id)
+ for path, ie in tree_b.iter_entries_by_dir()]
+ self.assertEqual([('', root_id),
+ ('xyz', 'xyz-id'),
+ ('xyz/m', 'm-id'),
+ ], paths)
+
def test_commit_sets_last_revision(self):
tree = self.make_branch_and_tree('tree')
committed_id = tree.commit('foo', rev_id='foo')
=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py 2007-10-17 17:03:06 +0000
+++ b/bzrlib/workingtree_4.py 2007-10-23 21:10:52 +0000
@@ -1189,7 +1189,8 @@
# Mark this file id as having been removed
entry = block[1][entry_index]
ids_to_unversion.discard(entry[0][2])
- if (entry[1][0][0] == 'a'
+ if (entry[1][0][0] in 'ar' # don't remove absent or renamed
+ # entries
or not state._make_absent(entry)):
entry_index += 1
# go to the next block. (At the moment we dont delete empty
More information about the bazaar-commits
mailing list