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