Rev 3931: (Charles Duffy) Fix bug #314251 adding a file with a recently removed in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Jan 8 20:52:03 GMT 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3931
revision-id: pqm at pqm.ubuntu.com-20090108205158-sez8mmopbhn2xkr5
parent: pqm at pqm.ubuntu.com-20090108195901-lechto0ubxsirqrd
parent: charles_duffy at messageone.com-20090108055319-can05w3dapd0fhxm
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2009-01-08 20:51:58 +0000
message:
  (Charles Duffy) Fix bug #314251 adding a file with a recently removed
  	file-id. should not break dirstate
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/dirstate.py             dirstate.py-20060728012006-d6mvoihjb3je9peu-1
  bzrlib/tests/workingtree_implementations/test_move.py test_move.py-20070225171927-mohn2vqj5fx7edc6-1
    ------------------------------------------------------------
    revno: 3923.2.2
    revision-id: charles_duffy at messageone.com-20090108055319-can05w3dapd0fhxm
    parent: charles_duffy at messageone.com-20090107063323-vxwaev9xe4p4gcel
    committer: Charles Duffy <charles_duffy at messageone.com>
    branch nick: bzr.cduffy.bug314251
    timestamp: Wed 2009-01-07 23:53:19 -0600
    message:
      Update fix for #314251 per feedback from Ian
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/dirstate.py             dirstate.py-20060728012006-d6mvoihjb3je9peu-1
    ------------------------------------------------------------
    revno: 3923.2.1
    revision-id: charles_duffy at messageone.com-20090107063323-vxwaev9xe4p4gcel
    parent: pqm at pqm.ubuntu.com-20090106171520-9pzjoqa7m74hvhht
    committer: Charles Duffy <charles_duffy at messageone.com>
    branch nick: bzr.cduffy.bug314251
    timestamp: Wed 2009-01-07 00:33:23 -0600
    message:
      Fix bug #314251 (dirstate crash on rename via delete+add)
    modified:
      bzrlib/dirstate.py             dirstate.py-20060728012006-d6mvoihjb3je9peu-1
      bzrlib/tests/workingtree_implementations/test_move.py test_move.py-20070225171927-mohn2vqj5fx7edc6-1
=== modified file 'NEWS'
--- a/NEWS	2009-01-08 19:59:01 +0000
+++ b/NEWS	2009-01-08 20:51:58 +0000
@@ -113,6 +113,9 @@
     * Use the short status format when the short format is used for log.
       (Vincent Ladeuil, #87179)
 
+    * Allow files to be renamed or moved via remove + add-by-id. (Charles
+      Duffy, #314251)
+
   DOCUMENTATION:
 
     * Improved the formats help topic to explain why multiple formats

=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py	2008-09-26 04:57:33 +0000
+++ b/bzrlib/dirstate.py	2009-01-08 05:53:19 +0000
@@ -415,12 +415,24 @@
             raise AssertionError(
                 "must be a utf8 file_id not %s" % (type(file_id), ))
         # Make sure the file_id does not exist in this tree
-        file_id_entry = self._get_entry(0, fileid_utf8=file_id)
+        rename_from = None
+        file_id_entry = self._get_entry(0, fileid_utf8=file_id, include_deleted=True)
         if file_id_entry != (None, None):
-            path = osutils.pathjoin(file_id_entry[0][0], file_id_entry[0][1])
-            kind = DirState._minikind_to_kind[file_id_entry[1][0][0]]
-            info = '%s:%s' % (kind, path)
-            raise errors.DuplicateFileId(file_id, info)
+            if file_id_entry[1][0][0] == 'a':
+                if file_id_entry[0] != (dirname, basename, file_id):
+                    # set the old name's current operation to rename
+                    self.update_minimal(file_id_entry[0],
+                        'r',
+                        path_utf8='',
+                        packed_stat='',
+                        fingerprint=utf8path
+                    )
+                    rename_from = file_id_entry[0][0:2]
+            else:
+                path = osutils.pathjoin(file_id_entry[0][0], file_id_entry[0][1])
+                kind = DirState._minikind_to_kind[file_id_entry[1][0][0]]
+                info = '%s:%s' % (kind, path)
+                raise errors.DuplicateFileId(file_id, info)
         first_key = (dirname, basename, '')
         block_index, present = self._find_block_index_from_key(first_key)
         if present:
@@ -453,6 +465,12 @@
             packed_stat = pack_stat(stat)
         parent_info = self._empty_parent_info()
         minikind = DirState._kind_to_minikind[kind]
+        if rename_from is not None:
+            if rename_from[0]:
+                old_path_utf8 = '%s/%s' % rename_from
+            else:
+                old_path_utf8 = rename_from[1]
+            parent_info[0] = ('r', old_path_utf8, 0, False, '')
         if kind == 'file':
             entry_data = entry_key, [
                 (minikind, fingerprint, size, False, packed_stat),
@@ -1722,7 +1740,7 @@
             entry_index += 1
         return block_index, entry_index, True, False
 
-    def _get_entry(self, tree_index, fileid_utf8=None, path_utf8=None):
+    def _get_entry(self, tree_index, fileid_utf8=None, path_utf8=None, include_deleted=False):
         """Get the dirstate entry for path in tree tree_index.
 
         If either file_id or path is supplied, it is used as the key to lookup.
@@ -1736,6 +1754,9 @@
             trees.
         :param fileid_utf8: A utf8 file_id to look up.
         :param path_utf8: An utf8 path to be looked up.
+        :param include_deleted: If True, and performing a lookup via
+            fileid_utf8 rather than path_utf8, return an entry for deleted
+            (absent) paths.
         :return: The dirstate entry tuple for path, or (None, None)
         """
         self._read_dirblocks_if_needed()
@@ -1782,6 +1803,8 @@
                         return entry
                     if entry[1][tree_index][0] == 'a':
                         # there is no home for this entry in this tree
+                        if include_deleted:
+                            return entry
                         return None, None
                     if entry[1][tree_index][0] != 'r':
                         raise AssertionError(

=== modified file 'bzrlib/tests/workingtree_implementations/test_move.py'
--- a/bzrlib/tests/workingtree_implementations/test_move.py	2008-12-22 08:44:20 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_move.py	2009-01-07 06:33:23 +0000
@@ -43,6 +43,16 @@
         actual = self.get_tree_layout(tree)
         self.assertEqual(expected, actual)
 
+    def test_move_via_rm_and_add(self):
+        """Move by remove and add-with-id"""
+        self.build_tree(['a1', 'b1'])
+        tree = self.make_branch_and_tree('.')
+        tree.add(['a1'], ids=['a1-id'])
+        tree.commit('initial commit')
+        tree.remove('a1', force=True, keep_files=False)
+        tree.add(['b1'], ids=['a1-id'])
+        tree._validate()
+
     def test_move_correct_call_named(self):
         """tree.move has the deprecated parameter 'to_name'.
         It has been replaced by 'to_dir' for consistency.




More information about the bazaar-commits mailing list