Rev 5419: Merge orphan-non-versioned-files into deprecate-get-backup-name in file:///home/vila/src/bzr/bugs/323111-orphans/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Fri Sep 10 11:10:43 BST 2010
At file:///home/vila/src/bzr/bugs/323111-orphans/
------------------------------------------------------------
revno: 5419 [merge]
revision-id: v.ladeuil+lp at free.fr-20100910101043-gs9jn2kqw7b7g2wt
parent: v.ladeuil+lp at free.fr-20100909141334-mrdt8dya6hrcbu0a
parent: v.ladeuil+lp at free.fr-20100910082331-poegognv5g9kqnso
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: deprecate-get-backup-name
timestamp: Fri 2010-09-10 12:10:43 +0200
message:
Merge orphan-non-versioned-files into deprecate-get-backup-name
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/per_workingtree/test_pull.py test_pull.py-20060222044334-43594dd8e143b708
bzrlib/tests/test_bzrdir.py test_bzrdir.py-20060131065654-deba40eef51cf220
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2010-09-03 02:53:10 +0000
+++ b/NEWS 2010-09-10 08:23:31 +0000
@@ -20,6 +20,10 @@
is now named "msg" instead of earlier "message".
(Parth Malwankar, #603461)
+* ``BzrDir.generate_backup_name`` has been deprecated and replaced by a
+ private method. ``osutils.available_backup_name`` provides an extensible
+ replacement. (Vincent Ladeuil)
+
* ``bzrlib.transform.TreeTransformBase.final_kind``,
``bzrlib.transform.TreeTransform.tree_kind`` and
``bzrlib.transform.TransformPreview.tree_kind`` now return None instead
@@ -193,6 +197,12 @@
have dropped from 68 bytes to 40, and directory entries from 120 bytes
to 48). (Andrew Bennetts)
+* When a bzr command remove a previously versioned directory, all
+ unversioned files are moved to a 'bzr-orphans' directory at the working
+ tree root with backup names (<file>.~#~). This was previously creating
+ spurious conflicts during merge, pull or switch operations.
+ (Vincent Ladeuil, #323111)
+
* When building new working trees, default to reading from the repository
rather than the source tree unless explicitly requested. (via
``--files-from`` and ``--hardlink`` for ``bzr branch`` and
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py 2010-09-09 13:41:52 +0000
+++ b/bzrlib/bzrdir.py 2010-09-10 08:23:31 +0000
@@ -1311,7 +1311,7 @@
empty = repository.revision_tree(_mod_revision.NULL_REVISION)
# We ignore the conflicts returned by wt.revert since we're about to
# delete the wt metadata anyway, all that should be left here are
- # detritus.
+ # detritus. But see bug #634470.
conflicts = wt.revert(old_tree=empty)
self.destroy_workingtree_metadata()
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2010-09-09 13:41:52 +0000
+++ b/bzrlib/osutils.py 2010-09-09 20:43:37 +0000
@@ -2359,7 +2359,9 @@
def available_backup_name(base, exists):
"""Find a non-existing backup file name.
- This will *not* create anything, this only return a 'free' entry.
+ This will *not* create anything, this only return a 'free' entry. This
+ should be used for checking names in a directory below a locked
+ tree/branch/repo to avoid race conditions.
:param base: The base name.
:param exists: A callable returning True if the passed path exists.
=== modified file 'bzrlib/tests/per_workingtree/test_pull.py'
--- a/bzrlib/tests/per_workingtree/test_pull.py 2010-09-07 15:48:29 +0000
+++ b/bzrlib/tests/per_workingtree/test_pull.py 2010-09-10 08:23:31 +0000
@@ -91,7 +91,11 @@
'WorkingTreeFormat2 does not support missing parent conflicts')
trunk = self.make_branch_deleting_dir('trunk')
work = trunk.bzrdir.sprout('work', revision_id='2').open_workingtree()
- # Add an unversioned file in dir
- self.build_tree(['work/dir/foo'])
+ # Add some unversioned files in dir
+ self.build_tree(['work/dir/foo',
+ 'work/dir/subdir/',
+ 'work/dir/subdir/foo'])
work.pull(trunk)
self.assertLength(0, work.conflicts())
+ # The directory removal should succeed
+ self.failIfExists('work/dir')
=== modified file 'bzrlib/tests/test_bzrdir.py'
--- a/bzrlib/tests/test_bzrdir.py 2010-09-09 13:41:52 +0000
+++ b/bzrlib/tests/test_bzrdir.py 2010-09-10 08:23:31 +0000
@@ -803,8 +803,8 @@
# turn the line below into an assertRaises when 'subtree/.bzr' is
# orphaned and sprout tries to access the branch there (which is left
# by bzrdir.BzrDirMeta1.destroy_workingtree when it ignores the
- # [DeletingParent('Not deleting', u'subtree', None)] conflict)
- # -- vila 20100909
+ # [DeletingParent('Not deleting', u'subtree', None)] conflict). See bug
+ # #634470. -- vila 20100909
self.assertRaises(errors.NotBranchError,
tree.bzrdir.sprout, 'repo/tree2')
# self.failUnlessExists('repo/tree2/subtree')
=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py 2010-09-09 08:14:39 +0000
+++ b/bzrlib/tests/test_transform.py 2010-09-10 08:23:31 +0000
@@ -822,9 +822,13 @@
parent = tt.trans_id_file_id('parent-id')
tt.new_file('file', parent, 'Contents')
raw_conflicts = resolve_conflicts(tt)
+ # Since the directory doesn't exist it's seen as missing to resolve
+ # create a conflict asking for it to be created.
self.assertLength(1, raw_conflicts)
self.assertEqual(('missing parent', 'Created directory', 'new-1'),
raw_conflicts.pop())
+ # apply fail since the missing directory doesn't exist
+ self.assertRaises(errors.NoFinalPath, tt.apply)
def test_moving_versioned_directories(self):
create, root = self.get_transform()
@@ -2371,6 +2375,7 @@
tt.delete_contents(dir_tid)
tt.unversion_file(dir_tid)
conflicts = resolve_conflicts(tt)
+ # no conflicts or rather: orphaning 'file' resolve the 'dir' conflict
self.assertLength(0, conflicts)
@@ -3258,14 +3263,33 @@
class TestOrphan(tests.TestCaseWithTransport):
- # - can't create oprhan dir
+ # Alternative implementations may want to test:
+ # - can't create orphan dir
# - orphaning forbidden
# - can't create orphan
- # - create orphan
def test_no_orphan_for_transform_preview(self):
tree = self.make_branch_and_tree('tree')
- tt = TransformPreview(tree)
+ tt = transform.TransformPreview(tree)
self.addCleanup(tt.finalize)
self.assertRaises(NotImplementedError, tt.new_orphan, 'foo', 'bar')
+ def test_new_orphan(self):
+ wt = self.make_branch_and_tree('.')
+ self.build_tree(['dir/', 'dir/foo'])
+ wt.add(['dir'], ['dir-id'])
+ wt.commit('add dir')
+ tt = transform.TreeTransform(wt)
+ self.addCleanup(tt.finalize)
+ dir_tid = tt.trans_id_tree_path('dir')
+ foo_tid = tt.trans_id_tree_path('dir/foo')
+ tt.delete_contents(dir_tid)
+ tt.unversion_file(dir_tid)
+ raw_conflicts = tt.find_conflicts()
+ self.assertLength(1, raw_conflicts)
+ self.assertEqual(('missing parent', 'new-1'), raw_conflicts[0])
+ remaining_conflicts = resolve_conflicts(tt)
+ # Yeah for resolved conflicts !
+ self.assertLength(0, remaining_conflicts)
+ # We have a new orphan
+ self.assertEndsWith('foo.~1~', tt.final_name(foo_tid))
More information about the bazaar-commits
mailing list