[RFC] Copy revision texts in topological order

John Arbash Meinel john at arbash-meinel.com
Wed Jun 4 22:03:11 BST 2008


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

At the moment, it is possible to ^C a copy from pack => knits at the right time
so that the final repository is missing revisions in the ancestry.

Specifically, the code is sending revisions in a "random" order (the order that
they were found when searching), and knits expect them to be inserted in
'topological' order.

When you ^C with the current code, it would create a ghost for any revisions
that had not been transferred yet, and future pushes won't copy them, because we
disabled automatic ghost transfer.

This patch changes the Generic fetch to always copy revisions in topological
order. So that it won't seems like we finished pushing if we ^C in the middle.
We don't need this for pack => pack or knit => knit because they already have
separate code path (and packs don't care about out-of-order until you do the
final 'set-pack-names').

I'm pretty sure this is correct, but I'd like some feedback about it:
=== modified file 'bzrlib/fetch.py'
- --- bzrlib/fetch.py     2008-05-12 01:23:41 +0000
+++ bzrlib/fetch.py     2008-06-04 20:59:15 +0000
@@ -31,7 +31,10 @@
~ """

~ import bzrlib
- -import bzrlib.errors as errors
+from bzrlib import (
+    errors,
+    tsort,
+    )
~ from bzrlib.errors import InstallFailed
~ from bzrlib.progress import ProgressPhase
~ from bzrlib.revision import is_null, NULL_REVISION
@@ -262,7 +265,13 @@
~         count = 0
~         total = len(revs)
~         to_store = self.to_repository._revision_store
- -        for rev in revs:
+        # Make sure the revision list is topologically sorted
+        graph = self.from_repository.get_graph(self.to_repository)
+        parent_map = graph.get_parent_map(revs)
+        filtered_parent_map = {}
+        for node, parents in parent_map.iteritems():
+            filtered_parent_map[node] = [p for p in parents if p in parent_map]
+        for rev in tsort.topo_sort(filtered_parent_map):
~             pb.update('copying revisions', count, total)
~             try:
~                 sig_text = self.from_repository.get_signature_text(rev)


John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkhHAw8ACgkQJdeBCYSNAAPqEACfWRrdX+gWTOeOIviKJa+VxQTA
Bh0AnAv1GbdkL4FwfK3Tl5DU77e4exG0
=3ei9
-----END PGP SIGNATURE-----



More information about the bazaar mailing list