Rev 3804: Updates to the form of add_inventory_by_delta that landed in trunk. in http://people.ubuntu.com/~robertc/baz2.0/commit-iterchanges

Robert Collins robertc at robertcollins.net
Wed Mar 18 01:08:08 GMT 2009


At http://people.ubuntu.com/~robertc/baz2.0/commit-iterchanges

------------------------------------------------------------
revno: 3804
revision-id: robertc at robertcollins.net-20090318010802-33da0qgt2ed867qy
parent: robertc at robertcollins.net-20090313022546-e7de5zsdkbay5okf
committer: Robert Collins <robertc at robertcollins.net>
branch nick: commit-iterchanges
timestamp: Wed 2009-03-18 12:08:02 +1100
message:
  Updates to the form of add_inventory_by_delta that landed in trunk.
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2009-03-13 02:25:46 +0000
+++ b/bzrlib/repository.py	2009-03-18 01:08:02 +0000
@@ -208,12 +208,9 @@
         if self.new_inventory is None:
             # an inventory delta was accumulated without creating a new
             # inventory.
-            try:
-                basis_id = self.parents[0]
-            except IndexError:
-                basis_id = _mod_revision.NULL_REVISION
-            self.inv_sha1 = self.repository.add_inventory_delta(
-                basis_id, self.basis_delta, self._new_revision_id,
+            basis_id = self.basis_delta_revision
+            self.inv_sha1 = self.repository.add_inventory_by_delta(
+                basis_id, self._basis_delta, self._new_revision_id,
                 self.parents)
         else:
             if self.new_inventory.root is None:
@@ -282,7 +279,7 @@
         entry = entry_factory['directory'](tree.path2id(''), '',
             None)
         entry.revision = self._new_revision_id
-        self.basis_delta.append(('', '', entry.file_id, entry))
+        self._basis_delta.append(('', '', entry.file_id, entry))
 
     def _get_delta(self, ie, basis_inv, path):
         """Get a delta against the basis inventory for ie."""
@@ -341,6 +338,11 @@
         builder.record_delete().
         """
         self._recording_deletes = True
+        try:
+            basis_id = self.parents[0]
+        except IndexError:
+            basis_id = _mod_revision.NULL_REVISION
+        self.basis_delta_revision = basis_id
 
     def record_entry_contents(self, ie, parent_invs, path, tree,
         content_summary):
@@ -559,8 +561,10 @@
         :param basis_tree: The basis tree this commit is being performed
             against.
         :param basis_revision_id: The revision id of the tree the iter_changes
-            has been generated against.
-        :param iter_changes: An iter_changes iterator.
+            has been generated against. Currently assumed to be the same
+            as self.parents[0] - if it is not, errors may occur.
+        :param iter_changes: An iter_changes iterator with the changes to apply
+            to basis_revision_id.
         :param _entry_factory: Private method to bind entry_factory locally for
             performance.
         :return: None
@@ -569,18 +573,27 @@
         # deltas between all the parent inventories. We use inventory delta's 
         # between the inventory objects because iter_changes masks
         # last-changed-field only changes.
-        basis_inv = basis_tree.inventory
+        # Working data:
         # file_id -> change map, change is fileid, paths, changed, versioneds,
         # parents, names, kinds, executables
         merged_ids = {}
         # file_id -> revision_id -> inventory entry, for entries in parent
         # trees that are not parents[0]
         parent_entries = {}
+        revtrees = list(self.repository.revision_trees(self.parents))
+        # The basis inventory from a repository 
+        if revtrees:
+            basis_inv = revtrees[0].inventory
+        else:
+            basis_inv = self.repository.revision_tree(
+                _mod_revision.NULL_REVISION).inventory
         if len(self.parents) > 1:
-            revtrees = list(self.repository.revision_trees(self.parents))
+            if basis_revision_id != self.parents[0]:
+                raise Exception(
+                    "arbitrary basis parents not yet supported with merges")
             repo_basis = revtrees[0]
             for revtree in revtrees[1:]:
-                for change in revtree.inventory.make_delta(basis_tree.inventory):
+                for change in revtree.inventory.make_delta(basis_inv):
                     if change[1] is None:
                         # Deleted
                         continue
@@ -597,12 +610,19 @@
                         parent_entries[change[2]][change[3].revision] = change[3]
         else:
             merged_ids = {}
+        # Setup the changes from the tree:
         changes= {}
         for change in iter_changes:
             # This probably looks up in basis_inv way to much.
-            changes[change[0]] = change, merged_ids.get(
-                change[0], [basis_inv[change[0]].revision])
+            if change[1][0] is not None:
+                head_candidate = [basis_inv[change[0]].revision]
+            else:
+                head_candidate = []
+            changes[change[0]] = change, merged_ids.get(change[0],
+                head_candidate)
         unchanged_merged = set(merged_ids) - set(changes)
+        # Extend the changes dict with synthetic changes to record merges of
+        # texts.
         for file_id in unchanged_merged:
             # Record a merged version of these items that did not change vs the
             # basis. This can be either identical parallel changes, or a revert
@@ -614,7 +634,7 @@
             # inv delta  change: (file_id, (path_in_source, path_in_target),
             #   changed_content, versioned, parent, name, kind,
             #   executable)
-            basis_entry = basis_inv[file_id]
+            basis_entry = repo_basis.inventory[file_id]
             change = (file_id,
                 (basis_inv.id2path(file_id), tree.id2path(file_id)),
                 False, (True, True),
@@ -628,7 +648,7 @@
         # inv delta is:
         # old_path, new_path, file_id, new_inventory_entry
         seen_root = False # Is the root in the basis delta?
-        inv_delta = self.basis_delta
+        inv_delta = self._basis_delta
         modified_rev = self._new_revision_id
         for change, head_candidates in changes.values():
             if change[3][1]: # versioned in target.
@@ -746,6 +766,7 @@
         if not seen_root:
             # housekeeping root entry changes do not affect no-change commits.
             self._require_root_change(tree)
+        self.basis_delta_revision = basis_revision_id
 
     def _add_text_to_weave(self, file_id, new_lines, parents, nostore_sha):
         # Note: as we read the content directly from the tree, we know its not

=== modified file 'bzrlib/tests/per_repository/test_commit_builder.py'
--- a/bzrlib/tests/per_repository/test_commit_builder.py	2009-03-13 02:25:46 +0000
+++ b/bzrlib/tests/per_repository/test_commit_builder.py	2009-03-18 01:08:02 +0000
@@ -104,14 +104,13 @@
         try:
             builder = tree.branch.get_commit_builder([])
             try:
-                builder.record_iter_changes(tree, tree.basis_tree(),
-                    tree.last_revision(), tree.iter_changes(tree.basis_tree()))
+                basis = tree.basis_tree()
+                last_rev = tree.last_revision()
+                changes = tree.iter_changes(basis)
+                builder.record_iter_changes(tree, basis, last_rev, changes)
                 builder.finish_inventory()
-            except:
+            finally:
                 builder.abort()
-                raise
-            builder.finish_inventory()
-            builder.abort()
         finally:
             tree.unlock()
 
@@ -400,7 +399,7 @@
                 builder.record_iter_changes(tree, tree.basis_tree(), rev_id,
                     [delete_change])
                 self.assertEqual(("foo", None, "foo-id", None),
-                    builder.basis_delta[0])
+                    builder._basis_delta[0])
                 self.assertTrue(builder.any_changes())
                 builder.finish_inventory()
                 rev_id2 = builder.commit('delete foo')
@@ -811,7 +810,7 @@
             changes = list(tree.iter_changes(parent_tree))
             builder.record_iter_changes(tree, parent_tree, parent_ids[0],
                 changes)
-            delta = builder.basis_delta
+            delta = builder._basis_delta
             delta_dict = dict((change[2], change) for change in delta)
             file_id = tree.path2id(new_name)
             version_recorded = (file_id in delta_dict and




More information about the bazaar-commits mailing list