Rev 3313: Deprecate a number of VersionedFile method calls, in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Fri Mar 28 06:42:38 GMT 2008


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3313
revision-id:pqm at pqm.ubuntu.com-20080328064220-ongijg78bfqhvbay
parent: pqm at pqm.ubuntu.com-20080328032801-o2sda79zu2g6ckxg
parent: robertc at robertcollins.net-20080328045853-ieqn8amdd8a1eon4
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2008-03-28 06:42:20 +0000
message:
  Deprecate a number of VersionedFile method calls,
  	and Repository.get_revision_graph. (Robert Collins)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
  bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
  bzrlib/reconcile.py            reweave_inventory.py-20051108164726-1e5e0934febac06e
  bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
  bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
  bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
  bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/revision.py             revision.py-20050309040759-e77802c08f3999d5
  bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
  bzrlib/tests/blackbox/test_serve.py test_serve.py-20060913064329-8t2pvmsikl4s3xhl-1
  bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
  bzrlib/tests/interversionedfile_implementations/test_join.py test_join.py-20060302012326-9b5e9b0f0a03fedc
  bzrlib/tests/repository_implementations/test_reconcile.py test_reconcile.py-20060223022332-572ef70a3288e369
  bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
  bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
  bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
  bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
  bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
  bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
    ------------------------------------------------------------
    revno: 3287.5.9.1.9
    revision-id:robertc at robertcollins.net-20080328045853-ieqn8amdd8a1eon4
    parent: robertc at robertcollins.net-20080328035440-4cflvryqujresn2g
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: integration
    timestamp: Fri 2008-03-28 15:58:53 +1100
    message:
      One last use of deprecated methods.
    modified:
      bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
    ------------------------------------------------------------
    revno: 3287.5.9.1.8
    revision-id:robertc at robertcollins.net-20080328035440-4cflvryqujresn2g
    parent: robertc at robertcollins.net-20080327045412-rju4uoh3glidd2px
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: versionedfile.apicleanup
    timestamp: Fri 2008-03-28 14:54:40 +1100
    message:
      Reduce code duplication as per review.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
    ------------------------------------------------------------
    revno: 3287.5.9.1.7
    revision-id:robertc at robertcollins.net-20080327045412-rju4uoh3glidd2px
    parent: robertc at robertcollins.net-20080327041759-8b7gao08zdz99dei
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: versionedfile.apicleanup
    timestamp: Thu 2008-03-27 15:54:12 +1100
    message:
       * ``VersionedFile.get_graph_with_ghosts`` is deprecated, with no
         replacement method.  The method was size(history) and not desirable.
         (Robert Collins)
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/tests/interversionedfile_implementations/test_join.py test_join.py-20060302012326-9b5e9b0f0a03fedc
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
    ------------------------------------------------------------
    revno: 3287.5.9.1.6
    revision-id:robertc at robertcollins.net-20080327041759-8b7gao08zdz99dei
    parent: robertc at robertcollins.net-20080327012524-yfgr0lek5ckiowhn
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: versionedfile.apicleanup
    timestamp: Thu 2008-03-27 15:17:59 +1100
    message:
      Unbreak has_ghosts.
    modified:
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
    ------------------------------------------------------------
    revno: 3287.5.9.1.5
    revision-id:robertc at robertcollins.net-20080327012524-yfgr0lek5ckiowhn
    parent: robertc at robertcollins.net-20080327002741-1vrg4yekrlvv4lfn
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: versionedfile.apicleanup
    timestamp: Thu 2008-03-27 12:25:24 +1100
    message:
      Deprecate VersionedFile.has_ghost.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/tests/interversionedfile_implementations/test_join.py test_join.py-20060302012326-9b5e9b0f0a03fedc
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
    ------------------------------------------------------------
    revno: 3287.5.9.1.4
    revision-id:robertc at robertcollins.net-20080327002741-1vrg4yekrlvv4lfn
    parent: robertc at robertcollins.net-20080326215555-d8f6bca03zxtzmsb
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: versionedfile.apicleanup
    timestamp: Thu 2008-03-27 11:27:41 +1100
    message:
      Fix up deprecation warnings for get_revision_graph.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/tests/blackbox/test_serve.py test_serve.py-20060913064329-8t2pvmsikl4s3xhl-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
    ------------------------------------------------------------
    revno: 3287.5.9.1.3
    revision-id:robertc at robertcollins.net-20080326215555-d8f6bca03zxtzmsb
    parent: robertc at robertcollins.net-20080326215332-0gdkjjcl3kxyeysq
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: versionedfile.apicleanup
    timestamp: Thu 2008-03-27 08:55:55 +1100
    message:
      More deprecations for NEWS.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 3287.5.9.1.2
    revision-id:robertc at robertcollins.net-20080326215332-0gdkjjcl3kxyeysq
    parent: robertc at robertcollins.net-20080326214235-3wmnqamcgytwif89
    parent: pqm at pqm.ubuntu.com-20080326124829-ggl5f8711x321ahw
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: versionedfile.apicleanup
    timestamp: Thu 2008-03-27 08:53:32 +1100
    message:
      Merge bzr.dev.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bundle/__init__.py      changeset.py-20050513021216-b02ab57fb9738913
      bzrlib/debug.py                debug.py-20061102062349-vdhrw9qdpck8cl35-1
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_pull.py test_pull.py-20051201144907-64959364f629947f
      bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/test_bundle.py    test.py-20050630184834-092aa401ab9f039c
      bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
      bzrlib/tests/test_read_bundle.py test_read_bundle.py-20060615211421-ud8cwr1ulgd914zf-1
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3287.5.9.1.1
    revision-id:robertc at robertcollins.net-20080326214235-3wmnqamcgytwif89
    parent: robertc at robertcollins.net-20080326011541-h9cxdap8x5pafq13
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: versionedfile.apicleanup
    timestamp: Thu 2008-03-27 08:42:35 +1100
    message:
       * ``VersionedFile.get_graph`` is deprecated, with no replacement method.
         The method was size(history) and not desirable. (Robert Collins)
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/reconcile.py            reweave_inventory.py-20051108164726-1e5e0934febac06e
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/revision.py             revision.py-20050309040759-e77802c08f3999d5
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
      bzrlib/tests/interversionedfile_implementations/test_join.py test_join.py-20060302012326-9b5e9b0f0a03fedc
      bzrlib/tests/repository_implementations/test_reconcile.py test_reconcile.py-20060223022332-572ef70a3288e369
      bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
=== modified file 'NEWS'
--- a/NEWS	2008-03-28 01:49:20 +0000
+++ b/NEWS	2008-03-28 06:42:20 +0000
@@ -74,9 +74,25 @@
       show_merge_revno methods. The latter had been deprecated since the 0.17
       release. (James Westby)
 
+    * ``Repository.get_revision_graph`` is deprecated, with no replacement
+      method. The method was size(history) and not desirable. (Robert Collins)
+
+    * ``revision.revision_graph`` is deprecated, with no replacement function.
+      The function was size(history) and not desirable. (Robert Collins)
+
+    * ``VersionedFile.get_graph`` is deprecated, with no replacement method.
+      The method was size(history) and not desirable. (Robert Collins)
+
+    * ``VersionedFile.get_graph_with_ghosts`` is deprecated, with no
+      replacement method.  The method was size(history) and not desirable.
+      (Robert Collins)
+
     * ``VersionedFile.get_parents`` is deprecated, please use
       ``VersionedFile.get_parent_map``. (Robert Collins)
 
+    * ``VersionedFile.has_ghost`` is now deprecated, as it is both expensive
+      and unused outside of a single test. (Robert Collins)
+
   TESTING:
 
     * New -Dselftest_debug flag disables clearing of the debug flags during

=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2008-03-14 10:55:37 +0000
+++ b/bzrlib/branch.py	2008-03-28 03:54:40 +0000
@@ -25,6 +25,7 @@
         errors,
         lockdir,
         lockable_files,
+        repository,
         revision as _mod_revision,
         transport,
         tsort,
@@ -192,7 +193,8 @@
         :return: A dictionary mapping revision_id => dotted revno.
         """
         last_revision = self.last_revision()
-        revision_graph = self.repository.get_revision_graph(last_revision)
+        revision_graph = repository._old_get_graph(self.repository,
+            last_revision)
         merge_sorted_revisions = tsort.merge_sort(
             revision_graph,
             last_revision,

=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py	2008-03-20 01:31:04 +0000
+++ b/bzrlib/knit.py	2008-03-27 04:54:12 +0000
@@ -101,18 +101,24 @@
     RevisionNotPresent,
     RevisionAlreadyPresent,
     )
-from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
+from bzrlib.graph import Graph
 from bzrlib.osutils import (
     contains_whitespace,
     contains_linebreaks,
     sha_string,
     sha_strings,
     )
-from bzrlib.symbol_versioning import DEPRECATED_PARAMETER, deprecated_passed
+from bzrlib.symbol_versioning import (
+    DEPRECATED_PARAMETER,
+    deprecated_method,
+    deprecated_passed,
+    one_four,
+    )
 from bzrlib.tsort import topo_sort
+from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
 import bzrlib.ui
+from bzrlib.versionedfile import VersionedFile, InterVersionedFile
 import bzrlib.weave
-from bzrlib.versionedfile import VersionedFile, InterVersionedFile
 
 
 # TODO: Split out code specific to this format into an associated object.
@@ -751,10 +757,10 @@
             annotated_part = "plain"
         return "knit-%s" % (annotated_part,)
         
+    @deprecated_method(one_four)
     def get_graph_with_ghosts(self):
         """See VersionedFile.get_graph_with_ghosts()."""
-        graph_items = self._index.get_graph()
-        return dict(graph_items)
+        return self.get_parent_map(self.versions())
 
     def get_sha1(self, version_id):
         return self.get_sha1s([version_id])[0]
@@ -770,18 +776,18 @@
         """See VersionedFile.get_suffixes()."""
         return [DATA_SUFFIX, INDEX_SUFFIX]
 
+    @deprecated_method(one_four)
     def has_ghost(self, version_id):
         """True if there is a ghost reference in the file to version_id."""
         # maybe we have it
         if self.has_version(version_id):
             return False
         # optimisable if needed by memoising the _ghosts set.
-        items = self._index.get_graph()
-        for node, parents in items:
+        items = self.get_parent_map(self.versions())
+        for parents in items.itervalues():
             for parent in parents:
-                if parent not in self._index._cache:
-                    if parent == version_id:
-                        return True
+                if parent == version_id and parent not in items:
+                    return True
         return False
 
     def insert_data_stream(self, (format, data_list, reader_callable)):
@@ -1427,10 +1433,6 @@
                 self._transport.put_bytes_non_atomic(
                     self._filename, self.HEADER, mode=self._file_mode)
 
-    def get_graph(self):
-        """Return a list of the node:parents lists from this knit index."""
-        return [(vid, idx[4]) for vid, idx in self._cache.iteritems()]
-
     def get_ancestry(self, versions, topo_sorted=True):
         """See VersionedFile.get_ancestry."""
         # get a graph of all the mentioned versions:
@@ -1848,15 +1850,6 @@
         else:
             return 'fulltext'
 
-    def get_graph(self):
-        """Return a list of the node:parents lists from this knit index."""
-        if not self._parents:
-            return [(key, ()) for key in self.get_versions()]
-        result = []
-        for index, key, value, refs in self._graph_index.iter_all_entries():
-            result.append((key[0], tuple([ref[0] for ref in refs[0]])))
-        return result
-
     def iter_parents(self, version_ids):
         """Iterate through the parents for many version ids.
 
@@ -2673,8 +2666,14 @@
         see join() for the parameter definitions.
         """
         version_ids = self._get_source_version_ids(version_ids, ignore_missing)
-        graph = self.source.get_graph(version_ids)
-        order = topo_sort(graph.items())
+        # --- the below is factorable out with VersionedFile.join, but wait for
+        # VersionedFiles, it may all be simpler then.
+        graph = Graph(self.source)
+        search = graph._make_breadth_first_searcher(version_ids)
+        transitive_ids = set()
+        map(transitive_ids.update, list(search))
+        parent_map = self.source.get_parent_map(transitive_ids)
+        order = topo_sort(parent_map.items())
 
         def size_of_content(content):
             return sum(len(line) for line in content.text())
@@ -2741,7 +2740,8 @@
     
             if not needed_versions:
                 return 0
-            full_list = topo_sort(self.source.get_graph())
+            full_list = topo_sort(
+                self.source.get_parent_map(self.source.versions()))
     
             version_list = [i for i in full_list if (not self.target.has_version(i)
                             and i in needed_versions)]
@@ -2843,7 +2843,8 @@
     
             if not needed_versions:
                 return 0
-            full_list = topo_sort(self.source.get_graph())
+            full_list = topo_sort(
+                self.source.get_parent_map(self.source.versions()))
     
             version_list = [i for i in full_list if (not self.target.has_version(i)
                             and i in needed_versions)]

=== modified file 'bzrlib/log.py'
--- a/bzrlib/log.py	2008-03-24 14:23:15 +0000
+++ b/bzrlib/log.py	2008-03-28 03:54:40 +0000
@@ -72,6 +72,7 @@
     get_terminal_encoding,
     terminal_width,
     )
+from bzrlib.repository import _strip_NULL_ghosts
 from bzrlib.revision import (
     NULL_REVISION,
     )
@@ -459,11 +460,16 @@
     weave_modifed_revisions = set(file_weave.versions())
     # build the ancestry of each revision in the graph
     # - only listing the ancestors that change the specific file.
-    rev_graph = branch.repository.get_revision_graph(mainline_revisions[-1])
-    sorted_rev_list = topo_sort(rev_graph)
+    graph = branch.repository.get_graph()
+    # This asks for all mainline revisions, which means we only have to spider
+    # sideways, rather than depth history. That said, its still size-of-history
+    # and should be addressed.
+    parent_map = dict(((key, value) for key, value in
+        graph.iter_ancestry(mainline_revisions) if value is not None))
+    sorted_rev_list = topo_sort(parent_map.items())
     ancestry = {}
     for rev in sorted_rev_list:
-        parents = rev_graph[rev]
+        parents = parent_map[rev]
         if rev not in weave_modifed_revisions and len(parents) == 1:
             # We will not be adding anything new, so just use a reference to
             # the parent ancestry.
@@ -477,7 +483,7 @@
         ancestry[rev] = rev_ancestry
 
     def is_merging_rev(r):
-        parents = rev_graph[r]
+        parents = parent_map[r]
         if len(parents) > 1:
             leftparent = parents[0]
             for rightparent in parents[1:]:
@@ -505,8 +511,16 @@
         for revision_id in revision_ids:
             yield revision_id, str(rev_nos[revision_id]), 0
         return
+    graph = branch.repository.get_graph()
+    # This asks for all mainline revisions, which means we only have to spider
+    # sideways, rather than depth history. That said, its still size-of-history
+    # and should be addressed.
+    parent_map = dict(((key, value) for key, value in
+        graph.iter_ancestry(mainline_revs) if value is not None))
+    # filter out ghosts; merge_sort errors on ghosts.
+    rev_graph = _strip_NULL_ghosts(parent_map)
     merge_sorted_revisions = merge_sort(
-        branch.repository.get_revision_graph(mainline_revs[-1]),
+        rev_graph,
         mainline_revs[-1],
         mainline_revs,
         generate_revno=True)

=== modified file 'bzrlib/reconcile.py'
--- a/bzrlib/reconcile.py	2008-03-19 04:39:04 +0000
+++ b/bzrlib/reconcile.py	2008-03-26 21:42:35 +0000
@@ -333,10 +333,10 @@
 
         # we have topological order of revisions and non ghost parents ready.
         self._setup_steps(len(self.revisions))
-        graph = self.revisions.get_graph()
-        parent_map = self.revisions.get_parent_map(graph.keys())
+        revision_ids = self.revisions.versions()
+        graph = self.revisions.get_parent_map(revision_ids)
         for rev_id in TopoSorter(graph.items()).iter_topo_order():
-            parents = parent_map[rev_id]
+            parents = graph[rev_id]
             # double check this really is in topological order, ignoring existing ghosts.
             unavailable = [p for p in parents if p not in new_inventory_vf and
                 p in self.revisions]

=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2008-03-14 10:55:37 +0000
+++ b/bzrlib/remote.py	2008-03-27 00:27:41 +0000
@@ -361,8 +361,13 @@
         self._ensure_real()
         return self._real_repository._generate_text_key_index()
 
+    @symbol_versioning.deprecated_method(symbol_versioning.one_four)
     def get_revision_graph(self, revision_id=None):
         """See Repository.get_revision_graph()."""
+        return self._get_revision_graph(revision_id)
+
+    def _get_revision_graph(self, revision_id):
+        """Private method for using with old (< 1.2) servers to fallback."""
         if revision_id is None:
             revision_id = ''
         elif revision.is_null(revision_id):
@@ -836,6 +841,10 @@
             # We already found out that the server can't understand
             # Repository.get_parent_map requests, so just fetch the whole
             # graph.
+            # XXX: Note that this will issue a deprecation warning. This is ok
+            # :- its because we're working with a deprecated server anyway, and
+            # the user will almost certainly have seen a warning about the
+            # server version already.
             return self.get_revision_graph()
 
         keys = set(keys)
@@ -889,7 +898,7 @@
             # To avoid having to disconnect repeatedly, we keep track of the
             # fact the server doesn't understand remote methods added in 1.2.
             medium._remote_is_at_least_1_2 = False
-            return self.get_revision_graph()
+            return self._get_revision_graph(None)
         elif response[0][0] not in ['ok']:
             reponse[1].cancel_read_body()
             raise errors.UnexpectedSmartServerResponse(response[0])

=== modified file 'bzrlib/repofmt/knitrepo.py'
--- a/bzrlib/repofmt/knitrepo.py	2008-03-19 04:39:04 +0000
+++ b/bzrlib/repofmt/knitrepo.py	2008-03-26 21:42:35 +0000
@@ -195,6 +195,7 @@
         revision_id = osutils.safe_revision_id(revision_id)
         return self.get_revision_reconcile(revision_id)
 
+    @symbol_versioning.deprecated_method(symbol_versioning.one_four)
     @needs_read_lock
     def get_revision_graph(self, revision_id=None):
         """Return a dictionary containing the revision graph.

=== modified file 'bzrlib/repofmt/pack_repo.py'
--- a/bzrlib/repofmt/pack_repo.py	2008-03-14 10:55:37 +0000
+++ b/bzrlib/repofmt/pack_repo.py	2008-03-26 21:42:35 +0000
@@ -1928,6 +1928,7 @@
             found_parents[key[0]] = parents
         return found_parents
 
+    @symbol_versioning.deprecated_method(symbol_versioning.one_four)
     @needs_read_lock
     def get_revision_graph(self, revision_id=None):
         """Return a dictionary containing the revision graph.

=== modified file 'bzrlib/repofmt/weaverepo.py'
--- a/bzrlib/repofmt/weaverepo.py	2008-03-19 04:39:04 +0000
+++ b/bzrlib/repofmt/weaverepo.py	2008-03-26 21:42:35 +0000
@@ -43,6 +43,7 @@
     RepositoryFormat,
     )
 from bzrlib.store.text import TextStore
+from bzrlib.symbol_versioning import deprecated_method, one_four
 from bzrlib.trace import mutter
 
 
@@ -141,6 +142,7 @@
             self._check_revision_parents(rev, inv)
         return revs
 
+    @deprecated_method(one_four)
     @needs_read_lock
     def get_revision_graph(self, revision_id=None):
         """Return a dictionary containing the revision graph.
@@ -282,6 +284,7 @@
         self._check_revision_parents(r, inv)
         return r
 
+    @deprecated_method(one_four)
     @needs_read_lock
     def get_revision_graph(self, revision_id=None):
         """Return a dictionary containing the revision graph.

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2008-03-26 06:47:29 +0000
+++ b/bzrlib/repository.py	2008-03-28 03:54:40 +0000
@@ -1339,9 +1339,8 @@
         """
         # All revisions, to find inventory parents.
         if ancestors is None:
-            # self.get_revision_graph_with_ghosts().get_ancestors() wasn't
-            # returning any ghosts anyway.
-            ancestors = self.get_revision_graph()
+            graph = self.get_graph()
+            ancestors = graph.get_parent_map(self.all_revision_ids())
         if text_key_references is None:
             text_key_references = self.find_text_key_references()
         pb = ui.ui_factory.nested_progress_bar()
@@ -1553,6 +1552,7 @@
         return self.get_revision(revision_id).inventory_sha1
 
     @needs_read_lock
+    @deprecated_method(symbol_versioning.one_four)
     def get_revision_graph(self, revision_id=None):
         """Return a dictionary containing the revision graph.
 
@@ -3140,3 +3140,22 @@
                 if correct_parents != knit_parents:
                     wrong_parents[revision_id] = (knit_parents, correct_parents)
         return wrong_parents, unused_versions
+
+
+def _old_get_graph(repository, revision_id):
+    """DO NOT USE. That is all. I'm serious."""
+    graph = repository.get_graph()
+    revision_graph = dict(((key, value) for key, value in
+        graph.iter_ancestry([revision_id]) if value is not None))
+    return _strip_NULL_ghosts(revision_graph)
+
+
+def _strip_NULL_ghosts(revision_graph):
+    """Also don't use this. more compatibility code for unmigrated clients."""
+    # Filter ghosts, and null:
+    if _mod_revision.NULL_REVISION in revision_graph:
+        del revision_graph[_mod_revision.NULL_REVISION]
+    for key, parents in revision_graph.items():
+        revision_graph[key] = tuple(parent for parent in parents if parent
+            in revision_graph)
+    return revision_graph

=== modified file 'bzrlib/revision.py'
--- a/bzrlib/revision.py	2008-03-10 15:39:56 +0000
+++ b/bzrlib/revision.py	2008-03-26 21:42:35 +0000
@@ -188,6 +188,7 @@
     return matches
 
 
+ at deprecated_function(symbol_versioning.one_four)
 def revision_graph(revision, revision_source):
     """Produce a graph of the ancestry of the specified revision.
     

=== modified file 'bzrlib/smart/repository.py'
--- a/bzrlib/smart/repository.py	2008-03-16 00:39:40 +0000
+++ b/bzrlib/smart/repository.py	2008-03-28 03:54:40 +0000
@@ -31,6 +31,7 @@
     SmartServerRequest,
     SuccessfulSmartServerResponse,
     )
+from bzrlib.repository import _strip_NULL_ghosts
 from bzrlib import revision as _mod_revision
 
 
@@ -87,6 +88,18 @@
             repository.unlock()
 
 
+class SmartServerRepositoryReadLocked(SmartServerRepositoryRequest):
+    """Calls self.do_readlocked_repository_request."""
+
+    def do_repository_request(self, repository, *args):
+        """Read lock a repository for do_readlocked_repository_request."""
+        repository.lock_read()
+        try:
+            return self.do_readlocked_repository_request(repository, *args)
+        finally:
+            repository.unlock()
+
+
 class SmartServerRepositoryGetParentMap(SmartServerRepositoryRequest):
     """Bzr 1.2+ - get parent data for revisions during a graph search."""
     
@@ -173,10 +186,12 @@
             ('ok', ), bz2.compress('\n'.join(lines)))
 
 
-class SmartServerRepositoryGetRevisionGraph(SmartServerRepositoryRequest):
+class SmartServerRepositoryGetRevisionGraph(SmartServerRepositoryReadLocked):
     
-    def do_repository_request(self, repository, revision_id):
+    def do_readlocked_repository_request(self, repository, revision_id):
         """Return the result of repository.get_revision_graph(revision_id).
+
+        Deprecated as of bzr 1.4, but supported for older clients.
         
         :param repository: The repository to query in.
         :param revision_id: The utf8 encoded revision_id to get a graph from.
@@ -187,9 +202,17 @@
             revision_id = None
 
         lines = []
-        try:
-            revision_graph = repository.get_revision_graph(revision_id)
-        except errors.NoSuchRevision:
+        graph = repository.get_graph()
+        if revision_id:
+            search_ids = [revision_id]
+        else:
+            search_ids = repository.all_revision_ids()
+        search = graph._make_breadth_first_searcher(search_ids)
+        transitive_ids = set()
+        map(transitive_ids.update, list(search))
+        parent_map = graph.get_parent_map(transitive_ids)
+        revision_graph = _strip_NULL_ghosts(parent_map)
+        if revision_id and revision_id not in revision_graph:
             # Note that we return an empty body, rather than omitting the body.
             # This way the client knows that it can always expect to find a body
             # in the response for this method, even in the error case.

=== modified file 'bzrlib/tests/blackbox/test_serve.py'
--- a/bzrlib/tests/blackbox/test_serve.py	2007-07-11 19:44:51 +0000
+++ b/bzrlib/tests/blackbox/test_serve.py	2008-03-27 00:27:41 +0000
@@ -57,6 +57,16 @@
         self.assertEqual('', result[0])
         self.assertEqual('bzr: interrupted\n', result[1])
 
+    def make_read_requests(self, branch):
+        """Do some read only requests."""
+        branch.lock_read()
+        try:
+            branch.repository.all_revision_ids()
+            self.assertEqual(_mod_revision.NULL_REVISION,
+                             _mod_revision.ensure_null(branch.last_revision()))
+        finally:
+            branch.unlock()
+
     def start_server_inet(self, extra_options=()):
         """Start a bzr server subprocess using the --inet option.
 
@@ -107,9 +117,7 @@
 
         # We get a working branch
         branch = BzrDir.open_from_transport(transport).open_branch()
-        branch.repository.get_revision_graph()
-        self.assertEqual(_mod_revision.NULL_REVISION,
-                         _mod_revision.ensure_null(branch.last_revision()))
+        self.make_read_requests(branch)
         self.assertInetServerShutsdownCleanly(process)
 
     def test_bzr_serve_port_readonly(self):
@@ -127,12 +135,7 @@
 
         # Connect to the server
         branch = Branch.open(url)
-
-        # We get a working branch
-        branch.repository.get_revision_graph()
-        self.assertEqual(_mod_revision.NULL_REVISION,
-                         _mod_revision.ensure_null(branch.last_revision()))
-
+        self.make_read_requests(branch)
         self.assertServerFinishesCleanly(process)
 
     def test_bzr_connect_to_bzr_ssh(self):
@@ -208,10 +211,7 @@
                 path_to_branch = os.path.splitdrive(path_to_branch)[1]
             branch = Branch.open(
                 'bzr+ssh://fred:secret@localhost:%d%s' % (port, path_to_branch))
-            
-            branch.repository.get_revision_graph()
-            self.assertEqual(_mod_revision.NULL_REVISION,
-                             _mod_revision.ensure_null(branch.last_revision()))
+            self.make_read_requests(branch)
             # Check we can perform write operations
             branch.bzrdir.root_transport.mkdir('foo')
         finally:

=== modified file 'bzrlib/tests/branch_implementations/test_branch.py'
--- a/bzrlib/tests/branch_implementations/test_branch.py	2008-03-04 21:59:33 +0000
+++ b/bzrlib/tests/branch_implementations/test_branch.py	2008-03-28 04:58:53 +0000
@@ -57,8 +57,11 @@
 
     def test_create_tree_with_merge(self):
         tree = self.create_tree_with_merge()
-        ancestry_graph = tree.branch.repository.get_revision_graph('rev-3')
-        self.assertEqual({'rev-1':(),
+        tree.lock_read()
+        self.addCleanup(tree.unlock)
+        graph = tree.branch.repository.get_graph()
+        ancestry_graph = graph.get_parent_map(tree.branch.repository.all_revision_ids())
+        self.assertEqual({'rev-1':('null:',),
                           'rev-2':('rev-1', ),
                           'rev-1.1.1':('rev-1', ),
                           'rev-3':('rev-2', 'rev-1.1.1', ),

=== modified file 'bzrlib/tests/interversionedfile_implementations/test_join.py'
--- a/bzrlib/tests/interversionedfile_implementations/test_join.py	2008-03-20 00:43:25 +0000
+++ b/bzrlib/tests/interversionedfile_implementations/test_join.py	2008-03-27 04:54:12 +0000
@@ -205,62 +205,35 @@
         # does not must discard it, and when filling a ghost for a listed
         # ghost must reconcile it
         source = self.get_source()
-        try:
-            source.has_ghost('a')
-            source_ghosts = True
-        except NotImplementedError:
-            source_ghosts = False
         target = self.get_target()
-        try:
-            target.has_ghost('a')
-            target_ghosts = True
-        except NotImplementedError:
-            target_ghosts = False
-
-        if not source_ghosts and not target_ghosts:
-            # nothing to do
-            return
-        if source_ghosts and not target_ghosts:
-            # switch source and target so source is ghostless
-            t = source
-            source = target
-            target = t
-            source_ghosts = False
-            target_ghosts = True
-        # now target always supports ghosts.
-
         # try filling target with ghosts and filling in reverse -  
-        target.add_lines_with_ghosts('notbase', ['base'], [])
+        try:
+            target.add_lines_with_ghosts('notbase', ['base'], [])
+        except NotImplementedError:
+            # The target does not support ghosts; the test is irrelevant.
+            return
         try:
             source.join(target)
         except errors.RevisionNotPresent:
-            # can't join a ghost containing target onto a non-ghost supporting
-            # source.
-            self.assertFalse(source_ghosts)
             return
-        else:
-            self.assertTrue(source_ghosts)
         # legacy apis should behave
         self.assertEqual(['notbase'], source.get_ancestry(['notbase']))
-        self.assertEqual({'notbase':()}, source.get_graph())
         self.assertFalse(source.has_version('base'))
         # ghost data should have been preserved
         self.assertEqual(['base', 'notbase'], source.get_ancestry_with_ghosts(['notbase']))
         self.assertEqual(['base'], source.get_parents_with_ghosts('notbase'))
-        self.assertEqual({'notbase':('base',)}, source.get_parent_map(['notbase']))
-        self.assertEqual({'notbase':('base',)}, source.get_graph_with_ghosts())
-        self.assertTrue(source.has_ghost('base'))
+        self.assertEqual({'notbase':('base',)},
+            source.get_parent_map(source.versions()))
 
         # if we add something that is fills out what is a ghost, then 
         # when joining into a ghost aware join it should flesh out the ghosts.
         source.add_lines('base', [], [])
-        target.join(source, version_ids=['base']) 
+        target.join(source, version_ids=['base'])
         self.assertEqual(['base', 'notbase'], target.get_ancestry(['notbase']))
-        self.assertEqual({'notbase':('base',)}, target.get_parent_map(['notbase']))
         self.assertEqual({'base':(),
                           'notbase':('base', ),
                           },
-                         target.get_graph())
+                         target.get_parent_map(target.versions()))
         self.assertTrue(target.has_version('base'))
         # we have _with_ghost apis to give us ghost information.
         self.assertEqual(['base', 'notbase'], target.get_ancestry_with_ghosts(['notbase']))
@@ -268,8 +241,7 @@
         self.assertEqual({'base':(),
                           'notbase':('base',),
                           },
-                         target.get_graph_with_ghosts())
-        self.assertFalse(target.has_ghost('base'))
+            source.get_parent_map(source.versions()))
 
     def test_restricted_join_into_empty(self):
         # joining into an empty versioned file with a version_ids list

=== modified file 'bzrlib/tests/repository_implementations/test_reconcile.py'
--- a/bzrlib/tests/repository_implementations/test_reconcile.py	2007-11-29 01:45:12 +0000
+++ b/bzrlib/tests/repository_implementations/test_reconcile.py	2008-03-26 21:42:35 +0000
@@ -345,9 +345,14 @@
         t = get_transport(self.get_url()).clone('wrong-first-parent')
         d = bzrlib.bzrdir.BzrDir.open_from_transport(t)
         repo = d.open_repository()
-        g = repo.get_revision_graph()
-        if tuple(g['wrong-first-parent']) == ('1', '2'):
-            raise TestSkipped('wrong-first-parent is not setup for testing')
+        repo.lock_read()
+        try:
+            g = repo.get_graph()
+            if g.get_parent_map(['wrong-first-parent'])['wrong-first-parent'] \
+                == ('1', '2'):
+                raise TestSkipped('wrong-first-parent is not setup for testing')
+        finally:
+            repo.unlock()
         self.checkUnreconciled(d, repo.reconcile())
         # nothing should have been altered yet : inventories without
         # revisions are not data loss incurring for current format
@@ -357,8 +362,12 @@
         # and no garbage inventories
         self.assertEqual(0, reconciler.garbage_inventories)
         # and should have been fixed:
-        g = repo.get_revision_graph()
-        self.assertEqual(('1', '2'), g['wrong-first-parent'])
+        repo.lock_read()
+        self.addCleanup(repo.unlock)
+        g = repo.get_graph()
+        self.assertEqual(
+            {'wrong-first-parent':('1', '2')},
+            g.get_parent_map(['wrong-first-parent']))
 
     def test_reconcile_wrong_order_secondary_inventory(self):
         # a wrong order in the parents for inventories is ignored.

=== modified file 'bzrlib/tests/repository_implementations/test_repository.py'
--- a/bzrlib/tests/repository_implementations/test_repository.py	2008-03-26 04:37:39 +0000
+++ b/bzrlib/tests/repository_implementations/test_repository.py	2008-03-26 21:53:32 +0000
@@ -37,7 +37,7 @@
     )
 from bzrlib.revision import NULL_REVISION, Revision
 from bzrlib.smart import server
-from bzrlib.symbol_versioning import one_two, one_three
+from bzrlib.symbol_versioning import one_two, one_three, one_four
 from bzrlib.tests import (
     KnownFailure,
     TestCaseWithTransport,
@@ -933,24 +933,28 @@
                           'rev3':('rev2', ),
                           'rev4':('rev3', ),
                           },
-                         self.bzrdir.open_repository().get_revision_graph(None))
+            self.applyDeprecated(one_four,
+                self.bzrdir.open_repository().get_revision_graph, None))
         self.assertEqual({'rev1':()},
-                         self.bzrdir.open_repository().get_revision_graph('rev1'))
+            self.applyDeprecated(one_four,
+                self.bzrdir.open_repository().get_revision_graph, 'rev1'))
         self.assertEqual({'rev1':(),
                           'rev2':('rev1', )},
-                         self.bzrdir.open_repository().get_revision_graph('rev2'))
-        self.assertRaises(errors.NoSuchRevision,
-                          self.bzrdir.open_repository().get_revision_graph,
-                          'orphan')
+            self.applyDeprecated(one_four,
+                self.bzrdir.open_repository().get_revision_graph, 'rev2'))
+        self.assertRaises(errors.NoSuchRevision, self.applyDeprecated, one_four,
+            self.bzrdir.open_repository().get_revision_graph, 'orphan')
         # and ghosts are not mentioned
         self.assertEqual({'rev1':(),
                           'rev2':('rev1', ),
                           'rev3':('rev2', ),
                           },
-                         self.bzrdir.open_repository().get_revision_graph('rev3'))
+            self.applyDeprecated(one_four,
+                self.bzrdir.open_repository().get_revision_graph, 'rev3'))
         # and we can ask for the NULLREVISION graph
         self.assertEqual({},
-            self.bzrdir.open_repository().get_revision_graph(NULL_REVISION))
+            self.applyDeprecated(one_four,
+                self.bzrdir.open_repository().get_revision_graph, NULL_REVISION))
 
     def test_get_revision_graph_with_ghosts(self):
         # we can get a graph object with roots, ghosts, ancestors and

=== modified file 'bzrlib/tests/test_knit.py'
--- a/bzrlib/tests/test_knit.py	2008-03-20 01:31:04 +0000
+++ b/bzrlib/tests/test_knit.py	2008-03-27 04:54:12 +0000
@@ -628,18 +628,6 @@
             {}),
             transport.calls.pop(0))
 
-    def test_get_graph(self):
-        transport = MockTransport()
-        index = self.get_knit_index(transport, "filename", "w", create=True)
-        self.assertEqual([], index.get_graph())
-
-        index.add_version("a", ["option"], (None, 0, 1), ["b"])
-        self.assertEqual([("a", ("b",))], index.get_graph())
-
-        index.add_version("c", ["option"], (None, 0, 1), ["d"])
-        self.assertEqual([("a", ("b",)), ("c", ("d",))],
-            sorted(index.get_graph()))
-
     def test_get_ancestry(self):
         transport = MockTransport([
             _KnitIndex.HEADER,
@@ -1897,7 +1885,9 @@
         # The target knit object is in a consistent state, i.e. the record we
         # just added is immediately visible.
         self.assertTrue(target.has_version('text-a'))
-        self.assertTrue(target.has_ghost('text-ghost'))
+        self.assertFalse(target.has_version('text-ghost'))
+        self.assertEqual({'text-a':('text-ghost',)},
+            target.get_parent_map(['text-a', 'text-ghost']))
         self.assertEqual(split_lines(TEXT_1), target.get_lines('text-a'))
 
     def test_insert_data_stream_inconsistent_version_lines(self):
@@ -2289,15 +2279,6 @@
         return KnitGraphIndex(combined_index, deltas=deltas,
             add_callback=add_callback)
 
-    def test_get_graph(self):
-        index = self.two_graph_index()
-        self.assertEqual(set([
-            ('tip', ('parent', )),
-            ('tail', ()),
-            ('parent', ('tail', 'ghost')),
-            ('separate', ()),
-            ]), set(index.get_graph()))
-
     def test_get_ancestry(self):
         # get_ancestry is defined as eliding ghosts, not erroring.
         index = self.two_graph_index()
@@ -2587,15 +2568,6 @@
         return KnitGraphIndex(combined_index, parents=False,
             add_callback=add_callback)
 
-    def test_get_graph(self):
-        index = self.two_graph_index()
-        self.assertEqual(set([
-            ('tip', ()),
-            ('tail', ()),
-            ('parent', ()),
-            ('separate', ()),
-            ]), set(index.get_graph()))
-
     def test_get_ancestry(self):
         # with no parents, ancestry is always just the key.
         index = self.two_graph_index()

=== modified file 'bzrlib/tests/test_log.py'
--- a/bzrlib/tests/test_log.py	2008-01-10 22:34:09 +0000
+++ b/bzrlib/tests/test_log.py	2008-03-26 21:42:35 +0000
@@ -685,6 +685,8 @@
     def test_get_view_revisions_forward(self):
         """Test the get_view_revisions method"""
         mainline_revs, rev_nos, wt = self.make_tree_with_commits()
+        wt.lock_read()
+        self.addCleanup(wt.unlock)
         revisions = list(get_view_revisions(mainline_revs, rev_nos, wt.branch,
                                             'forward'))
         self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3', '3', 0)],
@@ -696,6 +698,8 @@
     def test_get_view_revisions_reverse(self):
         """Test the get_view_revisions with reverse"""
         mainline_revs, rev_nos, wt = self.make_tree_with_commits()
+        wt.lock_read()
+        self.addCleanup(wt.unlock)
         revisions = list(get_view_revisions(mainline_revs, rev_nos, wt.branch,
                                             'reverse'))
         self.assertEqual([('3', '3', 0), ('2', '2', 0), ('1', '1', 0), ],
@@ -707,6 +711,8 @@
     def test_get_view_revisions_merge(self):
         """Test get_view_revisions when there are merges"""
         mainline_revs, rev_nos, wt = self.make_tree_with_merges()
+        wt.lock_read()
+        self.addCleanup(wt.unlock)
         revisions = list(get_view_revisions(mainline_revs, rev_nos, wt.branch,
                                             'forward'))
         self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3', '3', 0),
@@ -721,6 +727,8 @@
     def test_get_view_revisions_merge_reverse(self):
         """Test get_view_revisions in reverse when there are merges"""
         mainline_revs, rev_nos, wt = self.make_tree_with_merges()
+        wt.lock_read()
+        self.addCleanup(wt.unlock)
         revisions = list(get_view_revisions(mainline_revs, rev_nos, wt.branch,
                                             'reverse'))
         self.assertEqual([('4b', '4', 0), ('4a', '3.1.1', 1),
@@ -735,6 +743,8 @@
     def test_get_view_revisions_merge2(self):
         """Test get_view_revisions when there are merges"""
         mainline_revs, rev_nos, wt = self.make_tree_with_many_merges()
+        wt.lock_read()
+        self.addCleanup(wt.unlock)
         revisions = list(get_view_revisions(mainline_revs, rev_nos, wt.branch,
                                             'forward'))
         expected = [('1', '1', 0), ('2', '2', 0), ('3c', '3', 0),

=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py	2008-03-26 22:00:30 +0000
+++ b/bzrlib/tests/test_remote.py	2008-03-28 06:42:20 +0000
@@ -45,6 +45,7 @@
 from bzrlib.revision import NULL_REVISION
 from bzrlib.smart import server, medium
 from bzrlib.smart.client import _SmartClient
+from bzrlib.symbol_versioning import one_four
 from bzrlib.transport.memory import MemoryTransport
 from bzrlib.transport.remote import RemoteTransport
 
@@ -707,7 +708,8 @@
         transport_path = 'empty'
         repo, client = self.setup_fake_client_and_repository(
             responses, transport_path)
-        result = repo.get_revision_graph(NULL_REVISION)
+        result = self.applyDeprecated(one_four, repo.get_revision_graph,
+            NULL_REVISION)
         self.assertEqual([], client._calls)
         self.assertEqual({}, result)
 
@@ -722,7 +724,7 @@
         transport_path = 'sinhala'
         repo, client = self.setup_fake_client_and_repository(
             responses, transport_path)
-        result = repo.get_revision_graph()
+        result = self.applyDeprecated(one_four, repo.get_revision_graph)
         self.assertEqual(
             [('call_expecting_body', 'Repository.get_revision_graph',
              ('sinhala/', ''))],
@@ -742,7 +744,7 @@
         transport_path = 'sinhala'
         repo, client = self.setup_fake_client_and_repository(
             responses, transport_path)
-        result = repo.get_revision_graph(r2)
+        result = self.applyDeprecated(one_four, repo.get_revision_graph, r2)
         self.assertEqual(
             [('call_expecting_body', 'Repository.get_revision_graph',
              ('sinhala/', r2))],
@@ -757,7 +759,7 @@
             responses, transport_path)
         # also check that the right revision is reported in the error
         self.assertRaises(errors.NoSuchRevision,
-            repo.get_revision_graph, revid)
+            self.applyDeprecated, one_four, repo.get_revision_graph, revid)
         self.assertEqual(
             [('call_expecting_body', 'Repository.get_revision_graph',
              ('sinhala/', revid))],

=== modified file 'bzrlib/tests/test_versionedfile.py'
--- a/bzrlib/tests/test_versionedfile.py	2008-03-20 00:43:25 +0000
+++ b/bzrlib/tests/test_versionedfile.py	2008-03-27 04:54:12 +0000
@@ -630,10 +630,8 @@
             vf.add_lines_with_ghosts('notbxbfse', [parent_id_utf8], [])
         except NotImplementedError:
             # check the other ghost apis are also not implemented
-            self.assertRaises(NotImplementedError, vf.has_ghost, 'foo')
             self.assertRaises(NotImplementedError, vf.get_ancestry_with_ghosts, ['foo'])
             self.assertRaises(NotImplementedError, vf.get_parents_with_ghosts, 'foo')
-            self.assertRaises(NotImplementedError, vf.get_graph_with_ghosts)
             return
         vf = self.reopen_file()
         # test key graph related apis: getncestry, _graph, get_parents
@@ -647,8 +645,10 @@
         # we have _with_ghost apis to give us ghost information.
         self.assertEqual([parent_id_utf8, 'notbxbfse'], vf.get_ancestry_with_ghosts(['notbxbfse']))
         self.assertEqual([parent_id_utf8], vf.get_parents_with_ghosts('notbxbfse'))
-        self.assertEqual({'notbxbfse':(parent_id_utf8,)}, vf.get_graph_with_ghosts())
-        self.assertTrue(vf.has_ghost(parent_id_utf8))
+        self.assertEqual({'notbxbfse':(parent_id_utf8,)},
+            self.applyDeprecated(one_four, vf.get_graph_with_ghosts))
+        self.assertTrue(self.applyDeprecated(one_four, vf.has_ghost,
+            parent_id_utf8))
         # if we add something that is a ghost of another, it should correct the
         # results of the prior apis
         vf.add_lines(parent_id_utf8, [], [])
@@ -667,8 +667,9 @@
         self.assertEqual({parent_id_utf8:(),
                           'notbxbfse':(parent_id_utf8,),
                           },
-                         vf.get_graph_with_ghosts())
-        self.assertFalse(vf.has_ghost(parent_id_utf8))
+            self.applyDeprecated(one_four, vf.get_graph_with_ghosts))
+        self.assertFalse(self.applyDeprecated(one_four, vf.has_ghost,
+            parent_id_utf8))
 
     def test_add_lines_with_ghosts_after_normal_revs(self):
         # some versioned file formats allow lines to be added with parent
@@ -678,10 +679,9 @@
         vf = self.get_file()
         # probe for ghost support
         try:
-            vf.has_ghost('hoo')
+            vf.add_lines_with_ghosts('base', [], ['line\n', 'line_b\n'])
         except NotImplementedError:
             return
-        vf.add_lines_with_ghosts('base', [], ['line\n', 'line_b\n'])
         vf.add_lines_with_ghosts('references_ghost',
                                  ['base', 'a_ghost'],
                                  ['line\n', 'line_b\n', 'line_c\n'])

=== modified file 'bzrlib/versionedfile.py'
--- a/bzrlib/versionedfile.py	2008-03-19 04:48:03 +0000
+++ b/bzrlib/versionedfile.py	2008-03-27 04:54:12 +0000
@@ -30,6 +30,7 @@
     revision,
     ui,
     )
+from bzrlib.graph import Graph
 from bzrlib.transport.memory import MemoryTransport
 """)
 
@@ -70,6 +71,7 @@
         """Return a unsorted list of versions."""
         raise NotImplementedError(self.versions)
 
+    @deprecated_method(one_four)
     def has_ghost(self, version_id):
         """Returns whether version is present as a ghost."""
         raise NotImplementedError(self.has_ghost)
@@ -383,6 +385,7 @@
                     pending.add(parent)
         return result
 
+    @deprecated_method(one_four)
     def get_graph_with_ghosts(self):
         """Return a graph for the entire versioned file.
         
@@ -775,8 +778,12 @@
             temp_source = self.target.create_empty("temp", MemoryTransport())
             target = temp_source
         version_ids = self._get_source_version_ids(version_ids, ignore_missing)
-        graph = self.source.get_graph(version_ids)
-        order = tsort.topo_sort(graph.items())
+        graph = Graph(self.source)
+        search = graph._make_breadth_first_searcher(version_ids)
+        transitive_ids = set()
+        map(transitive_ids.update, list(search))
+        parent_map = self.source.get_parent_map(transitive_ids)
+        order = tsort.topo_sort(parent_map.items())
         pb = ui.ui_factory.nested_progress_bar()
         parent_texts = {}
         try:
@@ -794,7 +801,6 @@
             # memory pressure reduction. RBC 20060313
             # pb.update('Converting versioned data', 0, len(order))
             total = len(order)
-            parent_map = self.source.get_parent_map(order)
             for index, version in enumerate(order):
                 pb.update('Converting versioned data', index, total)
                 _, _, parent_text = target.add_lines(version,




More information about the bazaar-commits mailing list