[MERGE][#230567] Faster (local) branch
Aaron Bentley
aaron at aaronbentley.com
Tue Jun 3 14:01:11 BST 2008
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Ian Clatworthy wrote:
> I've headed back towards a single code path in the attached patch.
Basically, you're not using _apply_insertions at all if you're building
a tree. You might as well not call it.
> I've also put things back so that resolve_conflicts is always called
> and fixed the issue that was breaking some tests.
Your changes do call resolve_conflicts, but it's not correct to call
resolve_conflicts and then ignore the results.
resolve_conflicts can change the filename that is used, so you cannot
use the filename from the source tree inventory if that happened.
bb:resubmit
Aaron
> === modified file 'bzrlib/transform.py'
> --- bzrlib/transform.py 2008-05-12 02:48:08 +0000
> +++ bzrlib/transform.py 2008-05-30 07:42:07 +0000
> @@ -856,7 +856,8 @@
> def _set_executability(self, path, entry, trans_id):
> """Set the executability of versioned files """
> new_executability = self._new_executability[trans_id]
> - entry.executable = new_executability
> + if entry is not None:
> + entry.executable = new_executability
^^^ It does not make sense to set the executability of an unversioned file.
> @@ -1194,7 +1197,8 @@
> child_pb.update('Apply phase', 0, 2)
> self._apply_removals(inventory_delta, mover)
> child_pb.update('Apply phase', 1, 2)
> - modified_paths = self._apply_insertions(inventory_delta, mover)
> + modified_paths = self._apply_insertions(inventory_delta, mover,
> + creation_inv_delta)
> except:
> mover.rollback()
> raise
> @@ -1246,13 +1250,21 @@
> finally:
> child_pb.finished()
>
> - def _apply_insertions(self, inventory_delta, mover):
> + def _apply_insertions(self, inventory_delta, mover, creation_inv_delta):
> """Perform tree operations that insert directory/inventory names.
>
> That is, create any files that need to be created, and restore from
> limbo any files that needed renaming. This must be done in strict
> parent-to-child order.
> +
> + :param creation_inv_delta: the precomputed inventory delta when
> + creating a tree from scratch, otherwise None
> """
> + if creation_inv_delta is not None:
> + self._apply_creation(mover)
> + inventory_delta.extend(creation_inv_delta)
> + return [new for old, new, file_id, ie in creation_inv_delta]
It seems strange to pass a precomputed delta into this function, only to
return the same delta.
> @@ -1310,6 +1322,28 @@
> del self._new_contents[trans_id]
> return modified_paths
>
> + def _apply_creation(self, mover):
> + """Perform tree operations to create a tree from scratch."""
> + # Rename the top level directories in limbo
> + fp = FinalPaths(self)
> + for trans_id in self._needs_rename:
> + path = fp.get_path(trans_id)
> + try:
> + full_path = self._tree.abspath(path)
> + mover.rename(self._limbo_name(trans_id), full_path)
> + except OSError, e:
> + # We may be renaming a dangling inventory id
> + if e.errno != errno.ENOENT:
> + raise
> + else:
> + self.rename_count += 1
^^^ This code appears to be identical to the code in _apply_insertions.
This duplication should be eliminated.
> + # Set the execute bits for the required files and clean-up
> + for trans_id in self._new_executability:
> + path = fp.get_path(trans_id)
> + self._set_executability(path, None, trans_id)
> + self._new_contents = {}
The existing implementation removes items from the dict. If something
was holding onto the dict itself, it would break. It would be more
correct to call self._new_contents.clear(). Probably doesn't matter,
but it's just as easy to do, and more consistent.
> @@ -1607,7 +1641,12 @@
> for num, _unused in enumerate(wt.all_file_ids()):
> if num > 0: # more than just a root
> raise errors.WorkingTreeAlreadyPopulated(base=wt.basedir)
> - file_trans_id = {}
> + # If there are no existing files outside of .bzr, we can skip
> + # checking whether we need to reparent them or not.
> + existing_files = False
> + for file in wt.list_files():
> + existing_files = True
> + break
^^^ alternatively, you could list all files, store them in a set, and
use that to avoid invoking reparent even when there were some files
already present.
>
>
> +def _reparent_required(tree, wt, tt, divert, tree_path, entry):
> + target_path = wt.abspath(tree_path)
> + try:
> + kind = file_kind(target_path)
> + except NoSuchFile:
> + pass
^^^ You can just return False here.
> + else:
> + file_id = entry.file_id
> + if kind == "directory":
> + try:
> + bzrdir.BzrDir.open(target_path)
> + except errors.NotBranchError:
> + pass
> + else:
> + divert.add(file_id)
> + if (file_id not in divert and
> + _content_match(tree, entry, file_id, kind,
> + target_path)):
> + tt.delete_contents(tt.trans_id_tree_path(tree_path))
^^^ From the name _reparent_required I don't think anyone would guess
that the contents would be altered.
> +def _check_conflicts_after_build(tt, wt, divert_trans):
> + resolver = lambda t, c: resolve_checkout(t, c, divert_trans)
> + raw_conflicts = resolve_conflicts(tt, pass_func=resolver)
> + conflicts = cook_conflicts(raw_conflicts, tt)
> + for conflict in conflicts:
> + warning(conflict)
> + try:
> + wt.add_conflicts(conflicts)
> + except errors.UnsupportedOperation:
> + pass
^^^ This doesn't seem very specific to a build.
Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFIRUCW0F+nu1YWqI0RAg3PAJsERVz5MJnHGBNYU/4tB7qN9qRR2ACfQwh4
EmsIlGHIxl8rF9VkXhY0BzI=
=Wpdu
-----END PGP SIGNATURE-----
More information about the bazaar
mailing list