~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Jelmer Vernooij
  • Date: 2011-02-21 15:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 5675.
  • Revision ID: jelmer@samba.org-20110221150919-v7nnbontcuhi1dmu
Move Repository._find_text_key_references_from_xml_inventory_lines onto the serializer.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
from bzrlib.lazy_import import lazy_import
18
18
lazy_import(globals(), """
 
19
import cStringIO
 
20
import re
19
21
import time
20
22
 
21
23
from bzrlib import (
22
24
    bzrdir,
23
25
    check,
 
26
    chk_map,
24
27
    config,
25
28
    controldir,
26
29
    debug,
29
32
    generate_ids,
30
33
    gpg,
31
34
    graph,
 
35
    inventory,
32
36
    inventory_delta,
33
37
    lockable_files,
34
38
    lockdir,
35
39
    lru_cache,
36
40
    osutils,
 
41
    pyutils,
37
42
    revision as _mod_revision,
38
43
    static_tuple,
 
44
    trace,
39
45
    tsort,
40
46
    versionedfile,
41
47
    )
42
48
from bzrlib.bundle import serializer
43
 
from bzrlib.recordcounter import RecordCounter
44
 
from bzrlib.revisiontree import InventoryRevisionTree
 
49
from bzrlib.revisiontree import RevisionTree
45
50
from bzrlib.store.versioned import VersionedFileStore
46
51
from bzrlib.testament import Testament
47
52
""")
60
65
    ROOT_ID,
61
66
    entry_factory,
62
67
    )
 
68
from bzrlib.recordcounter import RecordCounter
63
69
from bzrlib.lock import _RelockDebugMixin, LogicalLockResult
64
70
from bzrlib.trace import (
65
71
    log_exception_quietly, note, mutter, mutter_callsite, warning)
88
94
    record_root_entry = True
89
95
    # the default CommitBuilder does not manage trees whose root is versioned.
90
96
    _versioned_root = False
91
 
    # this commit builder supports the record_entry_contents interface
92
 
    supports_record_entry_contents = True
93
97
 
94
98
    def __init__(self, repository, parents, config, timestamp=None,
95
99
                 timezone=None, committer=None, revprops=None,
96
 
                 revision_id=None, lossy=False):
 
100
                 revision_id=None):
97
101
        """Initiate a CommitBuilder.
98
102
 
99
103
        :param repository: Repository to commit to.
100
104
        :param parents: Revision ids of the parents of the new revision.
 
105
        :param config: Configuration to use.
101
106
        :param timestamp: Optional timestamp recorded for commit.
102
107
        :param timezone: Optional timezone for timestamp.
103
108
        :param committer: Optional committer to set for commit.
104
109
        :param revprops: Optional dictionary of revision properties.
105
110
        :param revision_id: Optional revision id.
106
 
        :param lossy: Whether to discard data that can not be natively
107
 
            represented, when pushing to a foreign VCS 
108
111
        """
109
112
        self._config = config
110
 
        self._lossy = lossy
111
113
 
112
114
        if committer is None:
113
115
            self._committer = self._config.username()
236
238
    def revision_tree(self):
237
239
        """Return the tree that was just committed.
238
240
 
239
 
        After calling commit() this can be called to get a
240
 
        InventoryRevisionTree representing the newly committed tree. This is
241
 
        preferred to calling Repository.revision_tree() because that may
242
 
        require deserializing the inventory, while we already have a copy in
 
241
        After calling commit() this can be called to get a RevisionTree
 
242
        representing the newly committed tree. This is preferred to
 
243
        calling Repository.revision_tree() because that may require
 
244
        deserializing the inventory, while we already have a copy in
243
245
        memory.
244
246
        """
245
247
        if self.new_inventory is None:
246
248
            self.new_inventory = self.repository.get_inventory(
247
249
                self._new_revision_id)
248
 
        return InventoryRevisionTree(self.repository, self.new_inventory,
 
250
        return RevisionTree(self.repository, self.new_inventory,
249
251
            self._new_revision_id)
250
252
 
251
253
    def finish_inventory(self):
1163
1165
        if config is not None and config.signature_needed():
1164
1166
            if inv is None:
1165
1167
                inv = self.get_inventory(revision_id)
1166
 
            tree = InventoryRevisionTree(self, inv, revision_id)
1167
 
            testament = Testament(rev, tree)
1168
 
            plaintext = testament.as_short_text()
 
1168
            plaintext = Testament(rev, inv).as_short_text()
1169
1169
            self.store_revision_signature(
1170
1170
                gpg.GPGStrategy(config), plaintext, revision_id)
1171
1171
        # check inventory present
1738
1738
    def _resume_write_group(self, tokens):
1739
1739
        raise errors.UnsuspendableWriteGroup(self)
1740
1740
 
1741
 
    def fetch(self, source, revision_id=None, find_ghosts=False,
 
1741
    def fetch(self, source, revision_id=None, pb=None, find_ghosts=False,
1742
1742
            fetch_spec=None):
1743
1743
        """Fetch the content required to construct revision_id from source.
1744
1744
 
1779
1779
                self.get_revision(revision_id)
1780
1780
            return 0, []
1781
1781
        inter = InterRepository.get(source, self)
1782
 
        return inter.fetch(revision_id=revision_id,
 
1782
        return inter.fetch(revision_id=revision_id, pb=pb,
1783
1783
            find_ghosts=find_ghosts, fetch_spec=fetch_spec)
1784
1784
 
1785
1785
    def create_bundle(self, target, base, fileobj, format=None):
1787
1787
 
1788
1788
    def get_commit_builder(self, branch, parents, config, timestamp=None,
1789
1789
                           timezone=None, committer=None, revprops=None,
1790
 
                           revision_id=None, lossy=False):
 
1790
                           revision_id=None):
1791
1791
        """Obtain a CommitBuilder for this repository.
1792
1792
 
1793
1793
        :param branch: Branch to commit to.
1798
1798
        :param committer: Optional committer to set for commit.
1799
1799
        :param revprops: Optional dictionary of revision properties.
1800
1800
        :param revision_id: Optional revision id.
1801
 
        :param lossy: Whether to discard data that can not be natively
1802
 
            represented, when pushing to a foreign VCS
1803
1801
        """
1804
1802
        if self._fallback_repositories and not self._format.supports_chks:
1805
1803
            raise errors.BzrError("Cannot commit directly to a stacked branch"
1806
1804
                " in pre-2a formats. See "
1807
1805
                "https://bugs.launchpad.net/bzr/+bug/375013 for details.")
1808
1806
        result = self._commit_builder_class(self, parents, config,
1809
 
            timestamp, timezone, committer, revprops, revision_id,
1810
 
            lossy)
 
1807
            timestamp, timezone, committer, revprops, revision_id)
1811
1808
        self.start_write_group()
1812
1809
        return result
1813
1810
 
2515
2512
        # TODO: refactor this to use an existing revision object
2516
2513
        # so we don't need to read it in twice.
2517
2514
        if revision_id == _mod_revision.NULL_REVISION:
2518
 
            return InventoryRevisionTree(self,
2519
 
                Inventory(root_id=None), _mod_revision.NULL_REVISION)
 
2515
            return RevisionTree(self, Inventory(root_id=None),
 
2516
                                _mod_revision.NULL_REVISION)
2520
2517
        else:
2521
2518
            inv = self.get_inventory(revision_id)
2522
 
            return InventoryRevisionTree(self, inv, revision_id)
 
2519
            return RevisionTree(self, inv, revision_id)
2523
2520
 
2524
2521
    def revision_trees(self, revision_ids):
2525
2522
        """Return Trees for revisions in this repository.
2529
2526
        """
2530
2527
        inventories = self.iter_inventories(revision_ids)
2531
2528
        for inv in inventories:
2532
 
            yield InventoryRevisionTree(self, inv, inv.revision_id)
 
2529
            yield RevisionTree(self, inv, inv.revision_id)
2533
2530
 
2534
2531
    def _filtered_revision_trees(self, revision_ids, file_ids):
2535
2532
        """Return Tree for a revision on this branch with only some files.
2545
2542
            # Should we introduce a FilteredRevisionTree class rather
2546
2543
            # than pre-filter the inventory here?
2547
2544
            filtered_inv = inv.filter(file_ids)
2548
 
            yield InventoryRevisionTree(self, filtered_inv, filtered_inv.revision_id)
 
2545
            yield RevisionTree(self, filtered_inv, filtered_inv.revision_id)
2549
2546
 
2550
2547
    @needs_read_lock
2551
2548
    def get_ancestry(self, revision_id, topo_sorted=True):
2736
2733
        return result
2737
2734
 
2738
2735
    def _warn_if_deprecated(self, branch=None):
2739
 
        if not self._format.is_deprecated():
2740
 
            return
2741
2736
        global _deprecation_warning_done
2742
2737
        if _deprecation_warning_done:
2743
2738
            return
2773
2768
                except UnicodeDecodeError:
2774
2769
                    raise errors.NonAsciiRevisionId(method, self)
2775
2770
 
2776
 
    def _find_inconsistent_revision_parents(self, revisions_iterator=None):
2777
 
        """Find revisions with different parent lists in the revision object
2778
 
        and in the index graph.
 
2771
    def revision_graph_can_have_wrong_parents(self):
 
2772
        """Is it possible for this repository to have a revision graph with
 
2773
        incorrect parents?
2779
2774
 
2780
 
        :param revisions_iterator: None, or an iterator of (revid,
2781
 
            Revision-or-None). This iterator controls the revisions checked.
2782
 
        :returns: an iterator yielding tuples of (revison-id, parents-in-index,
2783
 
            parents-in-revision).
 
2775
        If True, then this repository must also implement
 
2776
        _find_inconsistent_revision_parents so that check and reconcile can
 
2777
        check for inconsistencies before proceeding with other checks that may
 
2778
        depend on the revision index being consistent.
2784
2779
        """
2785
 
        if not self.is_locked():
2786
 
            raise AssertionError()
2787
 
        vf = self.revisions
2788
 
        if revisions_iterator is None:
2789
 
            revisions_iterator = self._iter_revisions(None)
2790
 
        for revid, revision in revisions_iterator:
2791
 
            if revision is None:
2792
 
                pass
2793
 
            parent_map = vf.get_parent_map([(revid,)])
2794
 
            parents_according_to_index = tuple(parent[-1] for parent in
2795
 
                parent_map[(revid,)])
2796
 
            parents_according_to_revision = tuple(revision.parent_ids)
2797
 
            if parents_according_to_index != parents_according_to_revision:
2798
 
                yield (revid, parents_according_to_index,
2799
 
                    parents_according_to_revision)
2800
 
 
2801
 
    def _check_for_inconsistent_revision_parents(self):
2802
 
        inconsistencies = list(self._find_inconsistent_revision_parents())
2803
 
        if inconsistencies:
2804
 
            raise errors.BzrCheckError(
2805
 
                "Revision knit has inconsistent parents.")
 
2780
        raise NotImplementedError(self.revision_graph_can_have_wrong_parents)
2806
2781
 
2807
2782
 
2808
2783
def install_revision(repository, rev, revision_tree):
2867
2842
        for revision, tree in parent_trees.iteritems():
2868
2843
            if ie.file_id not in tree:
2869
2844
                continue
2870
 
            parent_id = tree.get_file_revision(ie.file_id)
 
2845
            parent_id = tree.inventory[ie.file_id].revision
2871
2846
            if parent_id in text_parents:
2872
2847
                continue
2873
2848
            text_parents.append((ie.file_id, parent_id))
2942
2917
            control_files)
2943
2918
 
2944
2919
 
2945
 
class RepositoryFormatRegistry(controldir.ControlComponentFormatRegistry):
 
2920
class RepositoryFormatRegistry(registry.FormatRegistry):
2946
2921
    """Repository format registry."""
2947
2922
 
 
2923
    def __init__(self, other_registry=None):
 
2924
        super(RepositoryFormatRegistry, self).__init__(other_registry)
 
2925
        self._extra_formats = []
 
2926
 
 
2927
    def register(self, format):
 
2928
        """Register a new repository format."""
 
2929
        super(RepositoryFormatRegistry, self).register(
 
2930
            format.get_format_string(), format)
 
2931
 
 
2932
    def remove(self, format):
 
2933
        """Remove a registered repository format."""
 
2934
        super(RepositoryFormatRegistry, self).remove(
 
2935
            format.get_format_string())
 
2936
 
 
2937
    def register_extra(self, format):
 
2938
        """Register a repository format that can not be used in a metadir.
 
2939
 
 
2940
        This is mainly useful to allow custom repository formats, such as older
 
2941
        Bazaar formats and foreign formats, to be tested.
 
2942
        """
 
2943
        self._extra_formats.append(registry._ObjectGetter(format))
 
2944
 
 
2945
    def remove_extra(self, format):
 
2946
        """Remove an extra repository format.
 
2947
        """
 
2948
        self._extra_formats.remove(registry._ObjectGetter(format))
 
2949
 
 
2950
    def register_extra_lazy(self, module_name, member_name):
 
2951
        """Register a repository format lazily.
 
2952
        """
 
2953
        self._extra_formats.append(
 
2954
            registry._LazyObjectGetter(module_name, member_name))
 
2955
 
2948
2956
    def get_default(self):
2949
2957
        """Return the current default format."""
2950
2958
        from bzrlib import bzrdir
2951
2959
        return bzrdir.format_registry.make_bzrdir('default').repository_format
2952
2960
 
 
2961
    def _get_extra(self):
 
2962
        result = []
 
2963
        for getter in self._extra_formats:
 
2964
            f = getter.get_obj()
 
2965
            if callable(f):
 
2966
                f = f()
 
2967
            result.append(f)
 
2968
        return result
 
2969
 
 
2970
    def _get_all(self):
 
2971
        """Return all repository formats, even those not usable in metadirs.
 
2972
        """
 
2973
        return [self.get(k) for k in self.keys()] + self._get_extra()
 
2974
 
2953
2975
 
2954
2976
network_format_registry = registry.FormatRegistry()
2955
2977
"""Registry of formats indexed by their network name.
2971
2993
#####################################################################
2972
2994
# Repository Formats
2973
2995
 
2974
 
class RepositoryFormat(controldir.ControlComponentFormat):
 
2996
class RepositoryFormat(object):
2975
2997
    """A repository format.
2976
2998
 
2977
2999
    Formats provide four things:
3040
3062
    experimental = False
3041
3063
    # Does this repository format escape funky characters, or does it create files with
3042
3064
    # similar names as the versioned files in its contents on disk ?
3043
 
    supports_funky_characters = None
3044
 
    # Does this repository format support leaving locks?
3045
 
    supports_leaving_lock = None
3046
 
    # Does this format support the full VersionedFiles interface?
3047
 
    supports_full_versioned_files = None
3048
 
    # Does this format support signing revision signatures?
3049
 
    supports_revision_signatures = True
3050
 
    # Can the revision graph have incorrect parents?
3051
 
    revision_graph_can_have_wrong_parents = None
 
3065
    supports_funky_characters = True
3052
3066
 
3053
3067
    def __repr__(self):
3054
3068
        return "%s()" % self.__class__.__name__
3106
3120
        """Return the short description for this format."""
3107
3121
        raise NotImplementedError(self.get_format_description)
3108
3122
 
 
3123
    # TODO: this shouldn't be in the base class, it's specific to things that
 
3124
    # use weaves or knits -- mbp 20070207
 
3125
    def _get_versioned_file_store(self,
 
3126
                                  name,
 
3127
                                  transport,
 
3128
                                  control_files,
 
3129
                                  prefixed=True,
 
3130
                                  versionedfile_class=None,
 
3131
                                  versionedfile_kwargs={},
 
3132
                                  escaped=False):
 
3133
        if versionedfile_class is None:
 
3134
            versionedfile_class = self._versionedfile_class
 
3135
        weave_transport = control_files._transport.clone(name)
 
3136
        dir_mode = control_files._dir_mode
 
3137
        file_mode = control_files._file_mode
 
3138
        return VersionedFileStore(weave_transport, prefixed=prefixed,
 
3139
                                  dir_mode=dir_mode,
 
3140
                                  file_mode=file_mode,
 
3141
                                  versionedfile_class=versionedfile_class,
 
3142
                                  versionedfile_kwargs=versionedfile_kwargs,
 
3143
                                  escaped=escaped)
 
3144
 
3109
3145
    def initialize(self, a_bzrdir, shared=False):
3110
3146
        """Initialize a repository of this format in a_bzrdir.
3111
3147
 
3127
3163
        """
3128
3164
        return True
3129
3165
 
3130
 
    def is_deprecated(self):
3131
 
        """Is this format deprecated?
3132
 
 
3133
 
        Deprecated formats may trigger a user-visible warning recommending
3134
 
        the user to upgrade. They are still fully supported.
3135
 
        """
3136
 
        return False
3137
 
 
3138
3166
    def network_name(self):
3139
3167
        """A simple byte string uniquely identifying this format for RPC calls.
3140
3168
 
3179
3207
    rich_root_data = False
3180
3208
    supports_tree_reference = False
3181
3209
    supports_external_lookups = False
3182
 
    supports_leaving_lock = True
3183
3210
 
3184
3211
    @property
3185
3212
    def _matchingbzrdir(self):
3223
3250
        return self.get_format_string()
3224
3251
 
3225
3252
 
 
3253
# Pre-0.8 formats that don't have a disk format string (because they are
 
3254
# versioned by the matching control directory). We use the control directories
 
3255
# disk format string as a key for the network_name because they meet the
 
3256
# constraints (simple string, unique, immutable).
 
3257
network_format_registry.register_lazy(
 
3258
    "Bazaar-NG branch, format 5\n",
 
3259
    'bzrlib.repofmt.weaverepo',
 
3260
    'RepositoryFormat5',
 
3261
)
 
3262
network_format_registry.register_lazy(
 
3263
    "Bazaar-NG branch, format 6\n",
 
3264
    'bzrlib.repofmt.weaverepo',
 
3265
    'RepositoryFormat6',
 
3266
)
 
3267
 
 
3268
format_registry.register_extra_lazy(
 
3269
    'bzrlib.repofmt.weaverepo',
 
3270
    'RepositoryFormat4')
 
3271
format_registry.register_extra_lazy(
 
3272
    'bzrlib.repofmt.weaverepo',
 
3273
    'RepositoryFormat5')
 
3274
format_registry.register_extra_lazy(
 
3275
    'bzrlib.repofmt.weaverepo',
 
3276
    'RepositoryFormat6')
 
3277
 
3226
3278
# formats which have no format string are not discoverable or independently
3227
3279
# creatable on disk, so are not registered in format_registry.  They're
3228
 
# all in bzrlib.repofmt.knitreponow.  When an instance of one of these is
 
3280
# all in bzrlib.repofmt.weaverepo now.  When an instance of one of these is
3229
3281
# needed, it's constructed directly by the BzrDir.  Non-native formats where
3230
3282
# the repository is not separately opened are similar.
3231
3283
 
3232
3284
format_registry.register_lazy(
 
3285
    'Bazaar-NG Repository format 7',
 
3286
    'bzrlib.repofmt.weaverepo',
 
3287
    'RepositoryFormat7'
 
3288
    )
 
3289
 
 
3290
format_registry.register_lazy(
3233
3291
    'Bazaar-NG Knit Repository Format 1',
3234
3292
    'bzrlib.repofmt.knitrepo',
3235
3293
    'RepositoryFormatKnit1',
3252
3310
# NOTE: These are experimental in 0.92. Stable in 1.0 and above
3253
3311
format_registry.register_lazy(
3254
3312
    'Bazaar pack repository format 1 (needs bzr 0.92)\n',
3255
 
    'bzrlib.repofmt.knitpack_repo',
 
3313
    'bzrlib.repofmt.pack_repo',
3256
3314
    'RepositoryFormatKnitPack1',
3257
3315
    )
3258
3316
format_registry.register_lazy(
3259
3317
    'Bazaar pack repository format 1 with subtree support (needs bzr 0.92)\n',
3260
 
    'bzrlib.repofmt.knitpack_repo',
 
3318
    'bzrlib.repofmt.pack_repo',
3261
3319
    'RepositoryFormatKnitPack3',
3262
3320
    )
3263
3321
format_registry.register_lazy(
3264
3322
    'Bazaar pack repository format 1 with rich root (needs bzr 1.0)\n',
3265
 
    'bzrlib.repofmt.knitpack_repo',
 
3323
    'bzrlib.repofmt.pack_repo',
3266
3324
    'RepositoryFormatKnitPack4',
3267
3325
    )
3268
3326
format_registry.register_lazy(
3269
3327
    'Bazaar RepositoryFormatKnitPack5 (bzr 1.6)\n',
3270
 
    'bzrlib.repofmt.knitpack_repo',
 
3328
    'bzrlib.repofmt.pack_repo',
3271
3329
    'RepositoryFormatKnitPack5',
3272
3330
    )
3273
3331
format_registry.register_lazy(
3274
3332
    'Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6.1)\n',
3275
 
    'bzrlib.repofmt.knitpack_repo',
 
3333
    'bzrlib.repofmt.pack_repo',
3276
3334
    'RepositoryFormatKnitPack5RichRoot',
3277
3335
    )
3278
3336
format_registry.register_lazy(
3279
3337
    'Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6)\n',
3280
 
    'bzrlib.repofmt.knitpack_repo',
 
3338
    'bzrlib.repofmt.pack_repo',
3281
3339
    'RepositoryFormatKnitPack5RichRootBroken',
3282
3340
    )
3283
3341
format_registry.register_lazy(
3284
3342
    'Bazaar RepositoryFormatKnitPack6 (bzr 1.9)\n',
3285
 
    'bzrlib.repofmt.knitpack_repo',
 
3343
    'bzrlib.repofmt.pack_repo',
3286
3344
    'RepositoryFormatKnitPack6',
3287
3345
    )
3288
3346
format_registry.register_lazy(
3289
3347
    'Bazaar RepositoryFormatKnitPack6RichRoot (bzr 1.9)\n',
3290
 
    'bzrlib.repofmt.knitpack_repo',
 
3348
    'bzrlib.repofmt.pack_repo',
3291
3349
    'RepositoryFormatKnitPack6RichRoot',
3292
3350
    )
3293
3351
format_registry.register_lazy(
3301
3359
format_registry.register_lazy(
3302
3360
    ("Bazaar development format 2 with subtree support "
3303
3361
        "(needs bzr.dev from before 1.8)\n"),
3304
 
    'bzrlib.repofmt.knitpack_repo',
 
3362
    'bzrlib.repofmt.pack_repo',
3305
3363
    'RepositoryFormatPackDevelopment2Subtree',
3306
3364
    )
3307
3365
format_registry.register_lazy(
3344
3402
        self.target.fetch(self.source, revision_id=revision_id)
3345
3403
 
3346
3404
    @needs_write_lock
3347
 
    def fetch(self, revision_id=None, find_ghosts=False,
 
3405
    def fetch(self, revision_id=None, pb=None, find_ghosts=False,
3348
3406
            fetch_spec=None):
3349
3407
        """Fetch the content required to construct revision_id.
3350
3408
 
3352
3410
 
3353
3411
        :param revision_id: if None all content is copied, if NULL_REVISION no
3354
3412
                            content is copied.
 
3413
        :param pb: ignored.
3355
3414
        :return: None.
3356
3415
        """
3357
3416
        ui.ui_factory.warn_experimental_format_fetch(self)
3816
3875
                  len(revision_ids))
3817
3876
 
3818
3877
    @needs_write_lock
3819
 
    def fetch(self, revision_id=None, find_ghosts=False,
 
3878
    def fetch(self, revision_id=None, pb=None, find_ghosts=False,
3820
3879
            fetch_spec=None):
3821
3880
        """See InterRepository.fetch()."""
3822
3881
        if fetch_spec is not None:
3852
3911
        # Walk though all revisions; get inventory deltas, copy referenced
3853
3912
        # texts that delta references, insert the delta, revision and
3854
3913
        # signature.
3855
 
        pb = ui.ui_factory.nested_progress_bar()
 
3914
        if pb is None:
 
3915
            my_pb = ui.ui_factory.nested_progress_bar()
 
3916
            pb = my_pb
 
3917
        else:
 
3918
            symbol_versioning.warn(
 
3919
                symbol_versioning.deprecated_in((1, 14, 0))
 
3920
                % "pb parameter to fetch()")
 
3921
            my_pb = None
3856
3922
        try:
3857
3923
            self._fetch_all_revisions(revision_ids, pb)
3858
3924
        finally:
3859
 
            pb.finished()
 
3925
            if my_pb is not None:
 
3926
                my_pb.finished()
3860
3927
        return len(revision_ids), 0
3861
3928
 
3862
3929
    def _get_basis(self, first_revision_id):
3998
4065
        return wrong_parents, unused_keys
3999
4066
 
4000
4067
 
 
4068
def _old_get_graph(repository, revision_id):
 
4069
    """DO NOT USE. That is all. I'm serious."""
 
4070
    graph = repository.get_graph()
 
4071
    revision_graph = dict(((key, value) for key, value in
 
4072
        graph.iter_ancestry([revision_id]) if value is not None))
 
4073
    return _strip_NULL_ghosts(revision_graph)
 
4074
 
 
4075
 
4001
4076
def _strip_NULL_ghosts(revision_graph):
4002
4077
    """Also don't use this. more compatibility code for unmigrated clients."""
4003
4078
    # Filter ghosts, and null:
4176
4251
                parse_result = deserialiser.parse_text_bytes(
4177
4252
                    inventory_delta_bytes)
4178
4253
            except inventory_delta.IncompatibleInventoryDelta, err:
4179
 
                mutter("Incompatible delta: %s", err.msg)
 
4254
                trace.mutter("Incompatible delta: %s", err.msg)
4180
4255
                raise errors.IncompatibleRevision(self.target_repo._format)
4181
4256
            basis_id, new_id, rich_root, tree_refs, inv_delta = parse_result
4182
4257
            revision_id = new_id
4517
4592
    except StopIteration:
4518
4593
        # No more history
4519
4594
        return
 
4595