Rev 3779: Start on a CommitBuilder.record_iter_changes method. in http://people.ubuntu.com/~robertc/baz2.0/commit-iterchanges
Robert Collins
robertc at robertcollins.net
Tue Nov 18 00:32:40 GMT 2008
At http://people.ubuntu.com/~robertc/baz2.0/commit-iterchanges
------------------------------------------------------------
revno: 3779
revision-id: robertc at robertcollins.net-20081118003228-oy2yij3x208wnfiy
parent: robertc at robertcollins.net-20081013044331-ibghe8j4no7uhb55
committer: Robert Collins <robertc at robertcollins.net>
branch nick: commit-iterchanges
timestamp: Tue 2008-11-18 11:32:28 +1100
message:
Start on a CommitBuilder.record_iter_changes method.
modified:
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py 2008-10-13 04:32:29 +0000
+++ b/bzrlib/repository.py 2008-11-18 00:32:28 +0000
@@ -48,7 +48,12 @@
from bzrlib import registry
from bzrlib.decorators import needs_read_lock, needs_write_lock
from bzrlib.inter import InterObject
-from bzrlib.inventory import Inventory, InventoryDirectory, ROOT_ID
+from bzrlib.inventory import (
+ Inventory,
+ InventoryDirectory,
+ ROOT_ID,
+ entry_factory,
+ )
from bzrlib.symbol_versioning import (
deprecated_method,
one_one,
@@ -156,17 +161,33 @@
self._new_revision_id)
def finish_inventory(self):
- """Tell the builder that the inventory is finished."""
- if self.new_inventory.root is None:
- raise AssertionError('Root entry should be supplied to'
- ' record_entry_contents, as of bzr 0.10.')
- self.new_inventory.add(InventoryDirectory(ROOT_ID, '', None))
- self.new_inventory.revision_id = self._new_revision_id
- self.inv_sha1 = self.repository.add_inventory(
- self._new_revision_id,
- self.new_inventory,
- self.parents
- )
+ """Tell the builder that the inventory is finished.
+
+ :return: The inventory id in the repository, which can be used with
+ repository.get_inventory.
+ """
+ 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,
+ self.parents)
+ else:
+ if self.new_inventory.root is None:
+ raise AssertionError('Root entry should be supplied to'
+ ' record_entry_contents, as of bzr 0.10.')
+ self.new_inventory.add(InventoryDirectory(ROOT_ID, '', None))
+ self.new_inventory.revision_id = self._new_revision_id
+ self.inv_sha1 = self.repository.add_inventory(
+ self._new_revision_id,
+ self.new_inventory,
+ self.parents
+ )
+ return self._new_revision_id
def _gen_revision_id(self):
"""Return new revision-id."""
@@ -458,6 +479,40 @@
ie.revision = self._new_revision_id
return self._get_delta(ie, basis_inv, path), True, fingerprint
+ def record_iter_changes(self, basis_revision_id, iter_changes,
+ _entry_factory=entry_factory):
+ """Record a new tree via iter_changes.
+
+ :param basis_revision_id: The revision id of the tree the iter_changes
+ has been generated against.
+ :param iter_changes: An iter_changes iterator.
+ :param _entry_factory: Private method to bind entry_factory locally for
+ performance.
+ :return: None
+ """
+ # Create an inventory delta based on deltas between all the parents and
+ # deltas between all the parent inventories. We use inventory delta's
+ # between the inventory objects because iter_changes masks
+ # last-changed-field only changes.
+ # file_id -> change map, change is fileid, paths, changed, versioneds,
+ # parents, names, kinds, executables
+ changes= {}
+ for change in iter_changes:
+ changes[change[0]] = change
+ # inv delta is:
+ # old_path, new_path, file_id, new_inventory_entry
+ inv_delta = self.basis_delta
+ modified_rev = self._new_revision_id
+ for change in changes.values():
+ if change[3][1]: # versioned in target.
+ entry = entry_factory[change[6][1]](
+ change[0], change[5][1], change[4][1])
+ entry.revision = modified_rev
+ else:
+ entry = None
+ inv_delta.append((change[1][0], change[1][1], change[0], entry))
+ self.new_inventory = None
+
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
# been turned into unicode or badly split - but a broken tree
=== modified file 'bzrlib/tests/per_repository/test_commit_builder.py'
--- a/bzrlib/tests/per_repository/test_commit_builder.py 2008-10-13 04:32:29 +0000
+++ b/bzrlib/tests/per_repository/test_commit_builder.py 2008-11-18 00:32:28 +0000
@@ -58,14 +58,32 @@
builder.record_entry_contents(ie, parent_invs, '', tree,
tree.path_content_summary(''))
- def test_finish_inventory(self):
+ def test_finish_inventory_with_record_root(self):
tree = self.make_branch_and_tree(".")
tree.lock_write()
try:
builder = tree.branch.get_commit_builder([])
+ repo = tree.branch.repository
self.record_root(builder, tree)
builder.finish_inventory()
- tree.branch.repository.commit_write_group()
+ repo.commit_write_group()
+ finally:
+ tree.unlock()
+
+ def test_finish_inventory_record_iter_changes(self):
+ tree = self.make_branch_and_tree(".")
+ tree.lock_write()
+ try:
+ builder = tree.branch.get_commit_builder([])
+ try:
+ builder.record_iter_changes(tree.last_revision(),
+ tree.iter_changes(tree.basis_tree()))
+ builder.finish_inventory()
+ except:
+ builder.abort()
+ raise
+ repo = tree.branch.repository
+ repo.commit_write_group()
finally:
tree.unlock()
More information about the bazaar-commits
mailing list