/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Robert Collins
  • Date: 2009-02-24 08:09:17 UTC
  • mfrom: (4037 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4038.
  • Revision ID: robertc@robertcollins.net-20090224080917-9k7ib4oj1godlp3k
Merge bzr (resolve conflicts).

Show diffs side-by-side

added added

removed removed

Lines of Context:
199
199
 
200
200
    def _generate_revision_if_needed(self):
201
201
        """Create a revision id if None was supplied.
202
 
        
 
202
 
203
203
        If the repository can not support user-specified revision ids
204
204
        they should override this function and raise CannotSetRevisionId
205
205
        if _new_revision_id is not None.
301
301
        :param parent_invs: The inventories of the parent revisions of the
302
302
            commit.
303
303
        :param path: The path the entry is at in the tree.
304
 
        :param tree: The tree which contains this entry and should be used to 
 
304
        :param tree: The tree which contains this entry and should be used to
305
305
            obtain content.
306
306
        :param content_summary: Summary data from the tree about the paths
307
307
            content - stat, length, exec, sha/link target. This is only
514
514
 
515
515
class RootCommitBuilder(CommitBuilder):
516
516
    """This commitbuilder actually records the root id"""
517
 
    
 
517
 
518
518
    # the root entry gets versioned properly by this builder.
519
519
    _versioned_root = True
520
520
 
613
613
 
614
614
    def _abort_write_group(self):
615
615
        """Template method for per-repository write group cleanup.
616
 
        
617
 
        This is called during abort before the write group is considered to be 
 
616
 
 
617
        This is called during abort before the write group is considered to be
618
618
        finished and should cleanup any internal state accrued during the write
619
619
        group. There is no requirement that data handed to the repository be
620
620
        *not* made available - this is not a rollback - but neither should any
626
626
 
627
627
    def add_fallback_repository(self, repository):
628
628
        """Add a repository to use for looking up data not held locally.
629
 
        
 
629
 
630
630
        :param repository: A repository.
631
631
        """
632
632
        if not self._format.supports_external_lookups:
643
643
        """Check that this repository can fallback to repository safely.
644
644
 
645
645
        Raise an error if not.
646
 
        
 
646
 
647
647
        :param repository: A repository to fallback to.
648
648
        """
649
649
        return InterRepository._assert_same_model(self, repository)
650
650
 
651
651
    def add_inventory(self, revision_id, inv, parents):
652
652
        """Add the inventory inv to the repository as revision_id.
653
 
        
 
653
 
654
654
        :param parents: The revision ids of the parents that revision_id
655
655
                        is known to have and are in the repository already.
656
656
 
758
758
        self.revisions.add_lines(key, parents, osutils.split_lines(text))
759
759
 
760
760
    def all_revision_ids(self):
761
 
        """Returns a list of all the revision ids in the repository. 
 
761
        """Returns a list of all the revision ids in the repository.
762
762
 
763
763
        This is conceptually deprecated because code should generally work on
764
764
        the graph reachable from a particular revision, and ignore any other
770
770
        return self._all_revision_ids()
771
771
 
772
772
    def _all_revision_ids(self):
773
 
        """Returns a list of all the revision ids in the repository. 
 
773
        """Returns a list of all the revision ids in the repository.
774
774
 
775
 
        These are in as much topological order as the underlying store can 
 
775
        These are in as much topological order as the underlying store can
776
776
        present.
777
777
        """
778
778
        raise NotImplementedError(self._all_revision_ids)
823
823
        self._reconcile_does_inventory_gc = True
824
824
        self._reconcile_fixes_text_parents = False
825
825
        self._reconcile_backsup_inventory = True
826
 
        # not right yet - should be more semantically clear ? 
827
 
        # 
 
826
        # not right yet - should be more semantically clear ?
 
827
        #
828
828
        # TODO: make sure to construct the right store classes, etc, depending
829
829
        # on whether escaping is required.
830
830
        self._warn_if_deprecated()
881
881
        This causes caching within the repository obejct to start accumlating
882
882
        data during reads, and allows a 'write_group' to be obtained. Write
883
883
        groups must be used for actual data insertion.
884
 
        
 
884
 
885
885
        :param token: if this is already locked, then lock_write will fail
886
886
            unless the token matches the existing lock.
887
887
        :returns: a token if this instance supports tokens, otherwise None.
916
916
    def leave_lock_in_place(self):
917
917
        """Tell this repository not to release the physical lock when this
918
918
        object is unlocked.
919
 
        
 
919
 
920
920
        If lock_write doesn't return a token, then this method is not supported.
921
921
        """
922
922
        self.control_files.leave_in_place()
1028
1028
    @needs_read_lock
1029
1029
    def search_missing_revision_ids(self, other, revision_id=None, find_ghosts=True):
1030
1030
        """Return the revision ids that other has that this does not.
1031
 
        
 
1031
 
1032
1032
        These are returned in topological order.
1033
1033
 
1034
1034
        revision_id: only return revision ids included by revision_id.
1040
1040
    @needs_read_lock
1041
1041
    def missing_revision_ids(self, other, revision_id=None, find_ghosts=True):
1042
1042
        """Return the revision ids that other has that this does not.
1043
 
        
 
1043
 
1044
1044
        These are returned in topological order.
1045
1045
 
1046
1046
        revision_id: only return revision ids included by revision_id.
1066
1066
 
1067
1067
    def copy_content_into(self, destination, revision_id=None):
1068
1068
        """Make a complete copy of the content in self into destination.
1069
 
        
1070
 
        This is a destructive operation! Do not use it on existing 
 
1069
 
 
1070
        This is a destructive operation! Do not use it on existing
1071
1071
        repositories.
1072
1072
        """
1073
1073
        return InterRepository.get(self, destination).copy_content(revision_id)
1087
1087
 
1088
1088
    def _commit_write_group(self):
1089
1089
        """Template method for per-repository write group cleanup.
1090
 
        
1091
 
        This is called before the write group is considered to be 
 
1090
 
 
1091
        This is called before the write group is considered to be
1092
1092
        finished and should ensure that all data handed to the repository
1093
 
        for writing during the write group is safely committed (to the 
 
1093
        for writing during the write group is safely committed (to the
1094
1094
        extent possible considering file system caching etc).
1095
1095
        """
1096
1096
 
1105
1105
        self._resume_write_group(tokens)
1106
1106
        # so we can detect unlock/relock - the write group is now entered.
1107
1107
        self._write_group = self.get_transaction()
1108
 
    
 
1108
 
1109
1109
    def _resume_write_group(self, tokens):
1110
1110
        raise errors.UnsuspendableWriteGroup(self)
1111
1111
 
1139
1139
                           timezone=None, committer=None, revprops=None,
1140
1140
                           revision_id=None):
1141
1141
        """Obtain a CommitBuilder for this repository.
1142
 
        
 
1142
 
1143
1143
        :param branch: Branch to commit to.
1144
1144
        :param parents: Revision ids of the parents of the new revision.
1145
1145
        :param config: Configuration to use.
1207
1207
 
1208
1208
    def _start_write_group(self):
1209
1209
        """Template method for per-repository write group startup.
1210
 
        
1211
 
        This is called before the write group is considered to be 
 
1210
 
 
1211
        This is called before the write group is considered to be
1212
1212
        entered.
1213
1213
        """
1214
1214
 
1267
1267
    @needs_read_lock
1268
1268
    def get_revision_reconcile(self, revision_id):
1269
1269
        """'reconcile' helper routine that allows access to a revision always.
1270
 
        
 
1270
 
1271
1271
        This variant of get_revision does not cross check the weave graph
1272
1272
        against the revision one as get_revision does: but it should only
1273
1273
        be used by reconcile, or reconcile-alike commands that are correcting
1311
1311
 
1312
1312
    def get_deltas_for_revisions(self, revisions):
1313
1313
        """Produce a generator of revision deltas.
1314
 
        
 
1314
 
1315
1315
        Note that the input is a sequence of REVISIONS, not revision_ids.
1316
1316
        Trees will be held in memory until the generator exits.
1317
1317
        Each delta is relative to the revision's lefthand predecessor.
1320
1320
        for revision in revisions:
1321
1321
            required_trees.add(revision.revision_id)
1322
1322
            required_trees.update(revision.parent_ids[:1])
1323
 
        trees = dict((t.get_revision_id(), t) for 
 
1323
        trees = dict((t.get_revision_id(), t) for
1324
1324
                     t in self.revision_trees(required_trees))
1325
1325
        for revision in revisions:
1326
1326
            if not revision.parent_ids:
1391
1391
 
1392
1392
        # this code needs to read every new line in every inventory for the
1393
1393
        # inventories [revision_ids]. Seeing a line twice is ok. Seeing a line
1394
 
        # not present in one of those inventories is unnecessary but not 
 
1394
        # not present in one of those inventories is unnecessary but not
1395
1395
        # harmful because we are filtering by the revision id marker in the
1396
 
        # inventory lines : we only select file ids altered in one of those  
 
1396
        # inventory lines : we only select file ids altered in one of those
1397
1397
        # revisions. We don't need to see all lines in the inventory because
1398
1398
        # only those added in an inventory in rev X can contain a revision=X
1399
1399
        # line.
1714
1714
            yield ''.join(chunks), key[-1]
1715
1715
 
1716
1716
    def deserialise_inventory(self, revision_id, xml):
1717
 
        """Transform the xml into an inventory object. 
 
1717
        """Transform the xml into an inventory object.
1718
1718
 
1719
1719
        :param revision_id: The expected revision id of the inventory.
1720
1720
        :param xml: A serialised inventory.
1822
1822
        # TODO: refactor this to use an existing revision object
1823
1823
        # so we don't need to read it in twice.
1824
1824
        if revision_id == _mod_revision.NULL_REVISION:
1825
 
            return RevisionTree(self, Inventory(root_id=None), 
 
1825
            return RevisionTree(self, Inventory(root_id=None),
1826
1826
                                _mod_revision.NULL_REVISION)
1827
1827
        else:
1828
1828
            inv = self.get_revision_inventory(revision_id)
1840
1840
    def get_ancestry(self, revision_id, topo_sorted=True):
1841
1841
        """Return a list of revision-ids integrated by a revision.
1842
1842
 
1843
 
        The first element of the list is always None, indicating the origin 
1844
 
        revision.  This might change when we have history horizons, or 
 
1843
        The first element of the list is always None, indicating the origin
 
1844
        revision.  This might change when we have history horizons, or
1845
1845
        perhaps we should have a new API.
1846
 
        
 
1846
 
1847
1847
        This is topologically sorted.
1848
1848
        """
1849
1849
        if _mod_revision.is_null(revision_id):
1873
1873
        types it should be a no-op that just returns.
1874
1874
 
1875
1875
        This stub method does not require a lock, but subclasses should use
1876
 
        @needs_write_lock as this is a long running call its reasonable to 
 
1876
        @needs_write_lock as this is a long running call its reasonable to
1877
1877
        implicitly lock for the user.
1878
1878
        """
1879
1879
 
1881
1881
    @deprecated_method(one_six)
1882
1882
    def print_file(self, file, revision_id):
1883
1883
        """Print `file` to stdout.
1884
 
        
 
1884
 
1885
1885
        FIXME RBC 20060125 as John Meinel points out this is a bad api
1886
1886
        - it writes to stdout, it assumes that that is valid etc. Fix
1887
1887
        by creating a new more flexible convenience function.
1967
1967
                          working trees.
1968
1968
        """
1969
1969
        raise NotImplementedError(self.set_make_working_trees)
1970
 
    
 
1970
 
1971
1971
    def make_working_trees(self):
1972
1972
        """Returns the policy for making working trees on new branches."""
1973
1973
        raise NotImplementedError(self.make_working_trees)
2038
2038
                    revision_id.decode('ascii')
2039
2039
                except UnicodeDecodeError:
2040
2040
                    raise errors.NonAsciiRevisionId(method, self)
2041
 
    
 
2041
 
2042
2042
    def revision_graph_can_have_wrong_parents(self):
2043
2043
        """Is it possible for this repository to have a revision graph with
2044
2044
        incorrect parents?
2162
2162
 
2163
2163
class MetaDirRepository(Repository):
2164
2164
    """Repositories in the new meta-dir layout.
2165
 
    
 
2165
 
2166
2166
    :ivar _transport: Transport for access to repository control files,
2167
2167
        typically pointing to .bzr/repository.
2168
2168
    """
2193
2193
        else:
2194
2194
            self._transport.put_bytes('no-working-trees', '',
2195
2195
                mode=self.bzrdir._get_file_mode())
2196
 
    
 
2196
 
2197
2197
    def make_working_trees(self):
2198
2198
        """Returns the policy for making working trees on new branches."""
2199
2199
        return not self._transport.has('no-working-trees')
2248
2248
    consistency.
2249
2249
 
2250
2250
    Once a format is deprecated, just deprecate the initialize and open
2251
 
    methods on the format class. Do not deprecate the object, as the 
 
2251
    methods on the format class. Do not deprecate the object, as the
2252
2252
    object may be created even when a repository instnace hasn't been
2253
2253
    created.
2254
2254
 
2279
2279
    @classmethod
2280
2280
    def find_format(klass, a_bzrdir):
2281
2281
        """Return the format for the repository object in a_bzrdir.
2282
 
        
 
2282
 
2283
2283
        This is used by bzr native formats that have a "format" file in
2284
 
        the repository.  Other methods may be used by different types of 
 
2284
        the repository.  Other methods may be used by different types of
2285
2285
        control directory.
2286
2286
        """
2287
2287
        try:
2301
2301
    @classmethod
2302
2302
    def unregister_format(klass, format):
2303
2303
        format_registry.remove(format.get_format_string())
2304
 
    
 
2304
 
2305
2305
    @classmethod
2306
2306
    def get_default_format(klass):
2307
2307
        """Return the current default format."""
2310
2310
 
2311
2311
    def get_format_string(self):
2312
2312
        """Return the ASCII format string that identifies this format.
2313
 
        
2314
 
        Note that in pre format ?? repositories the format string is 
 
2313
 
 
2314
        Note that in pre format ?? repositories the format string is
2315
2315
        not permitted nor written to disk.
2316
2316
        """
2317
2317
        raise NotImplementedError(self.get_format_string)
2348
2348
        :param a_bzrdir: The bzrdir to put the new repository in it.
2349
2349
        :param shared: The repository should be initialized as a sharable one.
2350
2350
        :returns: The new repository object.
2351
 
        
 
2351
 
2352
2352
        This may raise UninitializableFormat if shared repository are not
2353
2353
        compatible the a_bzrdir.
2354
2354
        """
2358
2358
        """Is this format supported?
2359
2359
 
2360
2360
        Supported formats must be initializable and openable.
2361
 
        Unsupported formats may not support initialization or committing or 
 
2361
        Unsupported formats may not support initialization or committing or
2362
2362
        some other features depending on the reason for not being supported.
2363
2363
        """
2364
2364
        return True
2378
2378
 
2379
2379
    def open(self, a_bzrdir, _found=False):
2380
2380
        """Return an instance of this format for the bzrdir a_bzrdir.
2381
 
        
 
2381
 
2382
2382
        _found is a private parameter, do not use it.
2383
2383
        """
2384
2384
        raise NotImplementedError(self.open)
2449
2449
)
2450
2450
 
2451
2451
# formats which have no format string are not discoverable or independently
2452
 
# creatable on disk, so are not registered in format_registry.  They're 
 
2452
# creatable on disk, so are not registered in format_registry.  They're
2453
2453
# all in bzrlib.repofmt.weaverepo now.  When an instance of one of these is
2454
2454
# needed, it's constructed directly by the BzrDir.  Non-native formats where
2455
2455
# the repository is not separately opened are similar.
2522
2522
    'RepositoryFormatKnitPack6RichRoot',
2523
2523
    )
2524
2524
 
2525
 
# Development formats. 
 
2525
# Development formats.
2526
2526
# 1.7->1.8 go below here
2527
2527
format_registry.register_lazy(
2528
2528
    "Bazaar development format 2 (needs bzr.dev from before 1.8)\n",
2541
2541
    """This class represents operations taking place between two repositories.
2542
2542
 
2543
2543
    Its instances have methods like copy_content and fetch, and contain
2544
 
    references to the source and target repositories these operations can be 
 
2544
    references to the source and target repositories these operations can be
2545
2545
    carried out on.
2546
2546
 
2547
2547
    Often we will provide convenience methods on 'repository' which carry out
2647
2647
    @needs_read_lock
2648
2648
    def missing_revision_ids(self, revision_id=None, find_ghosts=True):
2649
2649
        """Return the revision ids that source has that target does not.
2650
 
        
 
2650
 
2651
2651
        These are returned in topological order.
2652
2652
 
2653
2653
        :param revision_id: only return revision ids included by this
2661
2661
    @needs_read_lock
2662
2662
    def search_missing_revision_ids(self, revision_id=None, find_ghosts=True):
2663
2663
        """Return the revision ids that source has that target does not.
2664
 
        
 
2664
 
2665
2665
        :param revision_id: only return revision ids included by this
2666
2666
                            revision_id.
2667
2667
        :param find_ghosts: If True find missing revisions in deep history
2686
2686
    @staticmethod
2687
2687
    def _same_model(source, target):
2688
2688
        """True if source and target have the same data representation.
2689
 
        
 
2689
 
2690
2690
        Note: this is always called on the base class; overriding it in a
2691
2691
        subclass will have no effect.
2692
2692
        """
2710
2710
 
2711
2711
class InterSameDataRepository(InterRepository):
2712
2712
    """Code for converting between repositories that represent the same data.
2713
 
    
 
2713
 
2714
2714
    Data format and model must match for this to work.
2715
2715
    """
2716
2716
 
2717
2717
    @classmethod
2718
2718
    def _get_repo_format_to_test(self):
2719
2719
        """Repository format for testing with.
2720
 
        
 
2720
 
2721
2721
        InterSameData can pull from subtree to subtree and from non-subtree to
2722
2722
        non-subtree, so we test this with the richest repository format.
2723
2723
        """
2734
2734
 
2735
2735
        This copies both the repository's revision data, and configuration information
2736
2736
        such as the make_working_trees setting.
2737
 
        
2738
 
        This is a destructive operation! Do not use it on existing 
 
2737
 
 
2738
        This is a destructive operation! Do not use it on existing
2739
2739
        repositories.
2740
2740
 
2741
2741
        :param revision_id: Only copy the content needed to construct
2746
2746
        except NotImplementedError:
2747
2747
            pass
2748
2748
        # but don't bother fetching if we have the needed data now.
2749
 
        if (revision_id not in (None, _mod_revision.NULL_REVISION) and 
 
2749
        if (revision_id not in (None, _mod_revision.NULL_REVISION) and
2750
2750
            self.target.has_revision(revision_id)):
2751
2751
            return
2752
2752
        self.target.fetch(self.source, revision_id=revision_id)
2767
2767
 
2768
2768
class InterWeaveRepo(InterSameDataRepository):
2769
2769
    """Optimised code paths between Weave based repositories.
2770
 
    
 
2770
 
2771
2771
    This should be in bzrlib/repofmt/weaverepo.py but we have not yet
2772
2772
    implemented lazy inter-object optimisation.
2773
2773
    """
2780
2780
    @staticmethod
2781
2781
    def is_compatible(source, target):
2782
2782
        """Be compatible with known Weave formats.
2783
 
        
 
2783
 
2784
2784
        We don't test for the stores being of specific types because that
2785
 
        could lead to confusing results, and there is no need to be 
 
2785
        could lead to confusing results, and there is no need to be
2786
2786
        overly general.
2787
2787
        """
2788
2788
        from bzrlib.repofmt.weaverepo import (
2799
2799
                                                RepositoryFormat7)))
2800
2800
        except AttributeError:
2801
2801
            return False
2802
 
    
 
2802
 
2803
2803
    @needs_write_lock
2804
2804
    def copy_content(self, revision_id=None):
2805
2805
        """See InterRepository.copy_content()."""
2849
2849
        """See InterRepository.missing_revision_ids()."""
2850
2850
        # we want all revisions to satisfy revision_id in source.
2851
2851
        # but we don't want to stat every file here and there.
2852
 
        # we want then, all revisions other needs to satisfy revision_id 
 
2852
        # we want then, all revisions other needs to satisfy revision_id
2853
2853
        # checked, but not those that we have locally.
2854
 
        # so the first thing is to get a subset of the revisions to 
 
2854
        # so the first thing is to get a subset of the revisions to
2855
2855
        # satisfy revision_id in source, and then eliminate those that
2856
 
        # we do already have. 
 
2856
        # we do already have.
2857
2857
        # this is slow on high latency connection to self, but as as this
2858
 
        # disk format scales terribly for push anyway due to rewriting 
 
2858
        # disk format scales terribly for push anyway due to rewriting
2859
2859
        # inventory.weave, this is considered acceptable.
2860
2860
        # - RBC 20060209
2861
2861
        if revision_id is not None:
2881
2881
            # and the tip revision was validated by get_ancestry.
2882
2882
            result_set = required_revisions
2883
2883
        else:
2884
 
            # if we just grabbed the possibly available ids, then 
 
2884
            # if we just grabbed the possibly available ids, then
2885
2885
            # we only have an estimate of whats available and need to validate
2886
2886
            # that against the revision records.
2887
2887
            result_set = set(
2900
2900
    @staticmethod
2901
2901
    def is_compatible(source, target):
2902
2902
        """Be compatible with known Knit formats.
2903
 
        
 
2903
 
2904
2904
        We don't test for the stores being of specific types because that
2905
 
        could lead to confusing results, and there is no need to be 
 
2905
        could lead to confusing results, and there is no need to be
2906
2906
        overly general.
2907
2907
        """
2908
2908
        from bzrlib.repofmt.knitrepo import RepositoryFormatKnit
2951
2951
            # and the tip revision was validated by get_ancestry.
2952
2952
            result_set = required_revisions
2953
2953
        else:
2954
 
            # if we just grabbed the possibly available ids, then 
 
2954
            # if we just grabbed the possibly available ids, then
2955
2955
            # we only have an estimate of whats available and need to validate
2956
2956
            # that against the revision records.
2957
2957
            result_set = set(
2970
2970
    @staticmethod
2971
2971
    def is_compatible(source, target):
2972
2972
        """Be compatible with known Pack formats.
2973
 
        
 
2973
 
2974
2974
        We don't test for the stores being of specific types because that
2975
 
        could lead to confusing results, and there is no need to be 
 
2975
        could lead to confusing results, and there is no need to be
2976
2976
        overly general.
2977
2977
        """
2978
2978
        from bzrlib.repofmt.pack_repo import RepositoryFormatPack
3053
3053
 
3054
3054
    def _autopack(self):
3055
3055
        self.target._pack_collection.autopack()
3056
 
        
 
3056
 
3057
3057
    def _get_target_pack_collection(self):
3058
3058
        return self.target._pack_collection
3059
3059
 
3060
3060
    @needs_read_lock
3061
3061
    def search_missing_revision_ids(self, revision_id=None, find_ghosts=True):
3062
3062
        """See InterRepository.missing_revision_ids().
3063
 
        
 
3063
 
3064
3064
        :param find_ghosts: Find ghosts throughout the ancestry of
3065
3065
            revision_id.
3066
3066
        """
3123
3123
    @needs_write_lock
3124
3124
    def copy_content(self, revision_id=None):
3125
3125
        """Make a complete copy of the content in self into destination.
3126
 
        
3127
 
        This is a destructive operation! Do not use it on existing 
 
3126
 
 
3127
        This is a destructive operation! Do not use it on existing
3128
3128
        repositories.
3129
3129
 
3130
3130
        :param revision_id: Only copy the content needed to construct
3135
3135
        except NotImplementedError:
3136
3136
            pass
3137
3137
        # but don't bother fetching if we have the needed data now.
3138
 
        if (revision_id not in (None, _mod_revision.NULL_REVISION) and 
 
3138
        if (revision_id not in (None, _mod_revision.NULL_REVISION) and
3139
3139
            self.target.has_revision(revision_id)):
3140
3140
            return
3141
3141
        self.target.fetch(self.source, revision_id=revision_id)
3205
3205
        """See InterRepository.fetch()."""
3206
3206
        from bzrlib.fetch import Knit1to2Fetcher
3207
3207
        mutter("Using fetch logic to copy between %s(%s) and %s(%s)",
3208
 
               self.source, self.source._format, self.target, 
 
3208
               self.source, self.source._format, self.target,
3209
3209
               self.target._format)
3210
3210
        f = Knit1to2Fetcher(to_repository=self.target,
3211
3211
                            from_repository=self.source,
3384
3384
            # Make _real_inter use the RemoteRepository for get_parent_map
3385
3385
            self._real_inter.target_get_graph = self.target.get_graph
3386
3386
            self._real_inter.target_get_parent_map = self.target.get_parent_map
3387
 
    
 
3387
 
3388
3388
    def copy_content(self, revision_id=None):
3389
3389
        self._ensure_real_inter()
3390
3390
        self._real_inter.copy_content(revision_id=revision_id)
3422
3422
            self.source._ensure_real()
3423
3423
            real_source = self.source._real_repository
3424
3424
            self._real_inter = InterRepository.get(real_source, self.target)
3425
 
    
 
3425
 
3426
3426
    def fetch(self, revision_id=None, pb=None, find_ghosts=False):
3427
3427
        self._ensure_real_inter()
3428
3428
        return self._real_inter.fetch(revision_id=revision_id, pb=pb,
3459
3459
                    if InterRepository._same_model(source, target):
3460
3460
                        return True
3461
3461
        return False
3462
 
    
 
3462
 
3463
3463
    def _autopack(self):
3464
3464
        self.target.autopack()
3465
3465
 
3472
3472
        fetcher = RepoFetcher(self.target, self.source, revision_id,
3473
3473
                              pb, find_ghosts)
3474
3474
        return fetcher.count_copied, fetcher.failed_revisions
3475
 
        
 
3475
 
3476
3476
    def _get_target_pack_collection(self):
3477
3477
        return self.target._real_repository._pack_collection
3478
3478
 
3495
3495
 
3496
3496
class CopyConverter(object):
3497
3497
    """A repository conversion tool which just performs a copy of the content.
3498
 
    
 
3498
 
3499
3499
    This is slow but quite reliable.
3500
3500
    """
3501
3501
 
3505
3505
        :param target_format: The format the resulting repository should be.
3506
3506
        """
3507
3507
        self.target_format = target_format
3508
 
        
 
3508
 
3509
3509
    def convert(self, repo, pb):
3510
3510
        """Perform the conversion of to_convert, giving feedback via pb.
3511
3511
 
3580
3580
    def __init__(self, repository):
3581
3581
        self.repository = repository
3582
3582
        self.text_index = self.repository._generate_text_key_index()
3583
 
    
 
3583
 
3584
3584
    def calculate_file_version_parents(self, text_key):
3585
3585
        """Calculate the correct parents for a file version according to
3586
3586
        the inventories.
3700
3700
 
3701
3701
    def _extract_and_insert_inventories(self, substream, serializer):
3702
3702
        """Generate a new inventory versionedfile in target, converting data.
3703
 
        
 
3703
 
3704
3704
        The inventory is retrieved from the source, (deserializing it), and
3705
3705
        stored in the target (reserializing it in a different format).
3706
3706
        """