Rev 4538: Fix NEWS for bug fix merges. in http://people.ubuntu.com/~robertc/baz2.0/integration

Robert Collins robertc at robertcollins.net
Wed Jul 15 22:29:32 BST 2009


At http://people.ubuntu.com/~robertc/baz2.0/integration

------------------------------------------------------------
revno: 4538 [merge]
revision-id: robertc at robertcollins.net-20090715212925-0d0ms080p84rs2kr
parent: robertc at robertcollins.net-20090715043314-jeuws3m6utp6cfyd
parent: robertc at robertcollins.net-20090715055437-ozlxxlwmcc9v1qyz
parent: robertc at robertcollins.net-20090715011320-coi9b5psw5d3tr2r
committer: Robert Collins <robertc at robertcollins.net>
branch nick: integration
timestamp: Thu 2009-07-16 07:29:25 +1000
message:
  Fix NEWS for bug fix merges.
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
  bzrlib/dirstate.py             dirstate.py-20060728012006-d6mvoihjb3je9peu-1
  bzrlib/tests/blackbox/test_commit.py test_commit.py-20060212094538-ae88fc861d969db0
  bzrlib/tests/per_workingtree/test_commit.py test_commit.py-20060421013633-1610ec2331c8190f
  bzrlib/tests/test_dirstate.py  test_dirstate.py-20060728012006-d6mvoihjb3je9peu-2
=== modified file 'NEWS'
--- a/NEWS	2009-07-15 04:33:14 +0000
+++ b/NEWS	2009-07-15 21:29:25 +0000
@@ -25,6 +25,16 @@
 * BranchBuilder now accepts timezone to avoid test failures in countries far
   from GMT. (Vincent Ladeuil, #397716)
 
+* ``bzr commit`` no longer saves the unversioning of missing files until
+  the commit has completed on the branch. This means that aborting a
+  commit that found a missing file will leave the tree unedited.
+  (Robert Collins, #282402)
+
+* Renames to lexographically lower basenames in trees that have never been
+  committed to will no longer corrupt the dirstate. This was caused by an
+  aliasing bug in the dirstate set_state_from_inventory method.
+  (Robert Collins, #395556)
+
 * ``WorkingTree4.unversion`` will no longer fail to unversion ids which
   were present in a parent tree but renamed in the working tree.
   (Robert Collins, #187207)

=== modified file 'bzrlib/commit.py'
--- a/bzrlib/commit.py	2009-06-15 19:04:38 +0000
+++ b/bzrlib/commit.py	2009-07-15 05:54:37 +0000
@@ -204,6 +204,7 @@
         """Commit working copy as a new revision.
 
         :param message: the commit message (it or message_callback is required)
+        :param message_callback: A callback: message = message_callback(cmt_obj)
 
         :param timestamp: if not None, seconds-since-epoch for a
             postdated/predated commit.
@@ -392,7 +393,10 @@
             # and now do the commit locally.
             self.branch.set_last_revision_info(new_revno, self.rev_id)
 
-            # Make the working tree up to date with the branch
+            # Make the working tree be up to date with the branch. This
+            # includes automatic changes scheduled to be made to the tree, such
+            # as updating its basis and unversioning paths that were missing.
+            self.work_tree.unversion(self.deleted_ids)
             self._set_progress_stage("Updating the working tree")
             self.work_tree.update_basis_by_delta(self.rev_id,
                  self.builder.get_basis_delta())
@@ -679,7 +683,7 @@
                             reporter.snapshot_change('modified', new_path)
             self._next_progress_entry()
         # Unversion IDs that were found to be deleted
-        self.work_tree.unversion(deleted_ids)
+        self.deleted_ids = deleted_ids
 
     def _record_unselected(self):
         # If specific files are selected, then all un-selected files must be
@@ -842,7 +846,7 @@
                 content_summary)
 
         # Unversion IDs that were found to be deleted
-        self.work_tree.unversion(deleted_ids)
+        self.deleted_ids = deleted_ids
 
     def _commit_nested_tree(self, file_id, path):
         "Commit a nested tree."

=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py	2009-07-10 05:33:07 +0000
+++ b/bzrlib/dirstate.py	2009-07-15 01:13:20 +0000
@@ -203,6 +203,7 @@
 
 import bisect
 import binascii
+from copy import deepcopy
 import errno
 import os
 from stat import S_IEXEC
@@ -2436,8 +2437,11 @@
         new_iterator = new_inv.iter_entries_by_dir()
         # we will be modifying the dirstate, so we need a stable iterator. In
         # future we might write one, for now we just clone the state into a
-        # list - which is a shallow copy.
-        old_iterator = iter(list(self._iter_entries()))
+        # list using a deep copy so that forward changes don't make the logic
+        # more complex. Using a shallow copy results in all entries being seen
+        # but the state of the entries being wrong, and that leads to stale
+        # entries being left behind.
+        old_iterator = iter(deepcopy(list(self._iter_entries())))
         # both must have roots so this is safe:
         current_new = new_iterator.next()
         current_old = old_iterator.next()

=== modified file 'bzrlib/tests/blackbox/test_commit.py'
--- a/bzrlib/tests/blackbox/test_commit.py	2009-07-08 05:27:06 +0000
+++ b/bzrlib/tests/blackbox/test_commit.py	2009-07-15 01:13:20 +0000
@@ -639,25 +639,3 @@
         out, err = self.run_bzr("commit tree/hello.txt")
         last_rev = tree.branch.repository.get_revision(tree.last_revision())
         self.assertEqual('save me some typing\n', last_rev.message)
-
-    def test_commit_and_mv_dance_a(self):
-        # see https://bugs.launchpad.net/bzr/+bug/395556
-        tree = self.make_branch_and_tree(".")
-        self.build_tree(["a"])
-        tree.add("a")
-        self.check_output("a => b\n", ["mv", "a", "b"])
-        self.check_output("", ["commit", "-q", "-m", "Actually no, b"])
-        self.check_output("b => a\n", ["mv", "b", "a"])
-        self.check_output("", ["commit", "-q", "-m", "No, really, a"])
-
-    def test_commit_and_mv_dance_b(self):
-        # see https://bugs.launchpad.net/bzr/+bug/395556
-        tree = self.make_branch_and_tree(".")
-        self.build_tree(["b"])
-        tree.add("b")
-        self.check_output("b => a\n", ["mv", "b", "a"])
-        self.check_output("", ["commit", "-q", "-m", "Actually no, a"])
-        self.check_output("a => b\n", ["mv", "a", "b"])
-        self.expectFailure("bug 395556: gives DuplicateFileId "
-            "committing renames",
-            self.check_output, "", ["commit", "-q", "-m", "No, really, b"])

=== modified file 'bzrlib/tests/per_workingtree/test_commit.py'
--- a/bzrlib/tests/per_workingtree/test_commit.py	2009-07-10 07:14:02 +0000
+++ b/bzrlib/tests/per_workingtree/test_commit.py	2009-07-15 21:29:25 +0000
@@ -280,6 +280,15 @@
         wt2.merge_from_branch(wt.branch)
         wt2.commit('merged kind change')
 
+    def test_commit_aborted_does_not_apply_automatic_changes_bug_282402(self):
+        wt = self.make_branch_and_tree('.')
+        wt.add(['a'], ['a-id'], ['file'])
+        def fail_message(obj):
+            raise errors.BzrCommandError("empty commit message")
+        self.assertRaises(errors.BzrCommandError, wt.commit,
+            message_callback=fail_message)
+        self.assertEqual('a', wt.id2path('a-id'))
+
     def test_local_commit_ignores_master(self):
         # a --local commit does not require access to the master branch
         # at all, or even for it to exist.
@@ -602,29 +611,3 @@
         revid = tree.commit('first post')
         committed_tree = tree.basis_tree()
         self.assertTrue(committed_tree.has_filename("newfile"))
-
-    def test_commit_and_mv_dance_a(self):
-        # should fail because of
-        # <https://bugs.launchpad.net/bzr/+bug/395556> but apparently does
-        # not, while the blackbox.test_commit equivalent does - maybe because
-        # of different format combinations
-        tree = self.make_branch_and_tree(".")
-        self.build_tree(["a"])
-        tree.add("a")
-        tree.rename_one("a", "b")
-        tree.commit("Actually no, b")
-        tree.rename_one("b", "a")
-        tree.commit("No, really, a")
-
-    def test_commit_and_mv_dance_b(self):
-        # should fail because of
-        # <https://bugs.launchpad.net/bzr/+bug/395556> but apparently does
-        # not, while the blackbox.test_commit equivalent does - maybe because
-        # of different format combinations
-        tree = self.make_branch_and_tree(".")
-        self.build_tree(["b"])
-        tree.add("b")
-        tree.rename_one("b", "a")
-        tree.commit("Actually no, a")
-        tree.rename_one("a", "b")
-        tree.commit("No, really, b")

=== modified file 'bzrlib/tests/test_dirstate.py'
--- a/bzrlib/tests/test_dirstate.py	2009-05-06 05:36:28 +0000
+++ b/bzrlib/tests/test_dirstate.py	2009-07-15 01:13:20 +0000
@@ -827,7 +827,6 @@
         finally:
             tree.unlock()
 
-
     def test_set_state_from_inventory_mixed_paths(self):
         tree1 = self.make_branch_and_tree('tree1')
         self.build_tree(['tree1/a/', 'tree1/a/b/', 'tree1/a-b/',
@@ -942,7 +941,6 @@
         finally:
             state.unlock()
 
-
     def test_set_parent_trees_no_content(self):
         # set_parent_trees is a slow but important api to support.
         tree1 = self.make_branch_and_memory_tree('tree1')
@@ -1238,6 +1236,38 @@
         self.assertRaises(errors.BzrError,
             state.add, '..', 'ass-id', 'directory', None, None)
 
+    def test_set_state_with_rename_b_a_bug_395556(self):
+        # bug 395556 uncovered a bug where the dirstate ends up with a false
+        # relocation record - in a tree with no parents there should be no
+        # absent or relocated records. This then leads to further corruption
+        # when a commit occurs, as the incorrect relocation gathers an
+        # incorrect absent in tree 1, and future changes go to pot.
+        tree1 = self.make_branch_and_tree('tree1')
+        self.build_tree(['tree1/b'])
+        tree1.lock_write()
+        try:
+            tree1.add(['b'], ['b-id'])
+            root_id = tree1.get_root_id()
+            inv = tree1.inventory
+            state = dirstate.DirState.initialize('dirstate')
+            try:
+                # Set the initial state with 'b'
+                state.set_state_from_inventory(inv)
+                inv.rename('b-id', root_id, 'a')
+                # Set the new state with 'a', which currently corrupts.
+                state.set_state_from_inventory(inv)
+                expected_result1 = [('', '', root_id, 'd'),
+                                    ('', 'a', 'b-id', 'f'),
+                                   ]
+                values = []
+                for entry in state._iter_entries():
+                    values.append(entry[0] + entry[1][0][:1])
+                self.assertEqual(expected_result1, values)
+            finally:
+                state.unlock()
+        finally:
+            tree1.unlock()
+
 
 class TestGetLines(TestCaseWithDirState):
 




More information about the bazaar-commits mailing list