~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

Merge up bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
794
794
                (format, data_list, StringIO(knit_bytes).read))
795
795
 
796
796
    @needs_read_lock
797
 
    def missing_revision_ids(self, other, revision_id=None):
 
797
    def missing_revision_ids(self, other, revision_id=None, find_ghosts=True):
798
798
        """Return the revision ids that other has that this does not.
799
799
        
800
800
        These are returned in topological order.
801
801
 
802
802
        revision_id: only return revision ids included by revision_id.
803
803
        """
804
 
        return InterRepository.get(other, self).missing_revision_ids(revision_id)
 
804
        return InterRepository.get(other, self).missing_revision_ids(
 
805
            revision_id, find_ghosts)
805
806
 
806
807
    @staticmethod
807
808
    def open(base):
1053
1054
    @needs_write_lock
1054
1055
    def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
1055
1056
        signature = gpg_strategy.sign(plaintext)
 
1057
        self.add_signature_text(revision_id, signature)
 
1058
 
 
1059
    @needs_write_lock
 
1060
    def add_signature_text(self, revision_id, signature):
1056
1061
        self._revision_store.add_revision_signature_text(revision_id,
1057
1062
                                                         signature,
1058
1063
                                                         self.get_transaction())
1077
1082
        finally:
1078
1083
            pb.finished()
1079
1084
 
1080
 
 
1081
1085
    def _find_text_key_references_from_xml_inventory_lines(self,
1082
1086
        line_iterator):
1083
1087
        """Core routine for extracting references to texts from inventories.
1091
1095
            not part of the line_iterator's output then False will be given -
1092
1096
            even though it may actually refer to that key.
1093
1097
        """
1094
 
        assert self._serializer.support_altered_by_hack, \
1095
 
            ("_find_text_key_references_from_xml_inventory_lines only "
1096
 
             "supported for branches which store inventory as unnested xml, "
1097
 
             "not on %r" % self)
 
1098
        if not self._serializer.support_altered_by_hack:
 
1099
            raise AssertionError(
 
1100
                "_find_text_key_references_from_xml_inventory_lines only "
 
1101
                "supported for branches which store inventory as unnested xml"
 
1102
                ", not on %r" % self)
1098
1103
        result = {}
1099
1104
 
1100
1105
        # this code needs to read every new line in every inventory for the
1140
1145
                unescape_revid_cache[revision_id] = unescaped
1141
1146
                revision_id = unescaped
1142
1147
 
1143
 
            # Note that unescaping always means that on a fulltext cached
1144
 
            # inventory we deserialised every fileid, which for general 'pull'
1145
 
            # is not great, but we don't really want to have some many
1146
 
            # fulltexts that this matters anyway. RBC 20071114.
 
1148
            # Note that unconditionally unescaping means that we deserialise
 
1149
            # every fileid, which for general 'pull' is not great, but we don't
 
1150
            # really want to have some many fulltexts that this matters anyway.
 
1151
            # RBC 20071114.
1147
1152
            try:
1148
1153
                file_id = unescape_fileid_cache[file_id]
1149
1154
            except KeyError:
1784
1789
 
1785
1790
def install_revision(repository, rev, revision_tree):
1786
1791
    """Install all revision data into a repository."""
 
1792
    install_revisions(repository, [(rev, revision_tree, None)])
 
1793
 
 
1794
 
 
1795
def install_revisions(repository, iterable):
 
1796
    """Install all revision data into a repository.
 
1797
 
 
1798
    Accepts an iterable of revision, tree, signature tuples.  The signature
 
1799
    may be None.
 
1800
    """
1787
1801
    repository.start_write_group()
1788
1802
    try:
1789
 
        _install_revision(repository, rev, revision_tree)
 
1803
        for revision, revision_tree, signature in iterable:
 
1804
            _install_revision(repository, revision, revision_tree, signature)
1790
1805
    except:
1791
1806
        repository.abort_write_group()
1792
1807
        raise
1794
1809
        repository.commit_write_group()
1795
1810
 
1796
1811
 
1797
 
def _install_revision(repository, rev, revision_tree):
 
1812
def _install_revision(repository, rev, revision_tree, signature):
1798
1813
    """Install all revision data into a repository."""
1799
1814
    present_parents = []
1800
1815
    parent_trees = {}
1839
1854
        repository.add_inventory(rev.revision_id, inv, present_parents)
1840
1855
    except errors.RevisionAlreadyPresent:
1841
1856
        pass
 
1857
    if signature is not None:
 
1858
        repository.add_signature_text(rev.revision_id, signature)
1842
1859
    repository.add_revision(rev.revision_id, rev, inv)
1843
1860
 
1844
1861
 
2139
2156
    'RepositoryFormatKnit3',
2140
2157
    )
2141
2158
 
 
2159
format_registry.register_lazy(
 
2160
    'Bazaar Knit Repository Format 4 (bzr 1.0)\n',
 
2161
    'bzrlib.repofmt.knitrepo',
 
2162
    'RepositoryFormatKnit4',
 
2163
    )
 
2164
 
2142
2165
# Pack-based formats. There is one format for pre-subtrees, and one for
2143
2166
# post-subtrees to allow ease of testing.
2144
2167
# NOTE: These are experimental in 0.92.
2188
2211
        raise NotImplementedError(self.fetch)
2189
2212
   
2190
2213
    @needs_read_lock
2191
 
    def missing_revision_ids(self, revision_id=None):
 
2214
    def missing_revision_ids(self, revision_id=None, find_ghosts=True):
2192
2215
        """Return the revision ids that source has that target does not.
2193
2216
        
2194
2217
        These are returned in topological order.
2355
2378
        return f.count_copied, f.failed_revisions
2356
2379
 
2357
2380
    @needs_read_lock
2358
 
    def missing_revision_ids(self, revision_id=None):
 
2381
    def missing_revision_ids(self, revision_id=None, find_ghosts=True):
2359
2382
        """See InterRepository.missing_revision_ids()."""
2360
2383
        # we want all revisions to satisfy revision_id in source.
2361
2384
        # but we don't want to stat every file here and there.
2433
2456
        return f.count_copied, f.failed_revisions
2434
2457
 
2435
2458
    @needs_read_lock
2436
 
    def missing_revision_ids(self, revision_id=None):
 
2459
    def missing_revision_ids(self, revision_id=None, find_ghosts=True):
2437
2460
        """See InterRepository.missing_revision_ids()."""
2438
2461
        if revision_id is not None:
2439
2462
            source_ids = self.source.get_ancestry(revision_id)
2510
2533
            # sensibly detect 'new revisions' without doing a full index scan.
2511
2534
        elif _mod_revision.is_null(revision_id):
2512
2535
            # nothing to do:
2513
 
            return
 
2536
            return (0, [])
2514
2537
        else:
2515
2538
            try:
2516
2539
                revision_ids = self.missing_revision_ids(revision_id,
2526
2549
            # a pack creation, but for now it is simpler to think about as
2527
2550
            # 'upload data, then repack if needed'.
2528
2551
            self.target._pack_collection.autopack()
2529
 
            return pack.get_revision_count()
 
2552
            return (pack.get_revision_count(), [])
2530
2553
        else:
2531
 
            return 0
 
2554
            return (0, [])
2532
2555
 
2533
2556
    @needs_read_lock
2534
2557
    def missing_revision_ids(self, revision_id=None, find_ghosts=True):
2555
2578
                    target_index.iter_entries(target_keys))
2556
2579
                missing_revs.update(next_revs - have_revs)
2557
2580
                searcher.stop_searching_any(have_revs)
 
2581
            if next_revs - have_revs == set([revision_id]):
 
2582
                # we saw the start rev itself, but no parents from it (or
 
2583
                # next_revs would have been updated to e.g. set(). We remove
 
2584
                # have_revs because if we found revision_id locally we
 
2585
                # stop_searching at the first time around.
 
2586
                raise errors.NoSuchRevision(self.source, revision_id)
2558
2587
            return missing_revs
2559
2588
        elif revision_id is not None:
2560
2589
            source_ids = self.source.get_ancestry(revision_id)
2651
2680
        return f.count_copied, f.failed_revisions
2652
2681
 
2653
2682
 
 
2683
class InterDifferingSerializer(InterKnitRepo):
 
2684
 
 
2685
    @classmethod
 
2686
    def _get_repo_format_to_test(self):
 
2687
        return None
 
2688
 
 
2689
    @staticmethod
 
2690
    def is_compatible(source, target):
 
2691
        """Be compatible with Knit2 source and Knit3 target"""
 
2692
        if source.supports_rich_root() != target.supports_rich_root():
 
2693
            return False
 
2694
        # Ideally, we'd support fetching if the source had no tree references
 
2695
        # even if it supported them...
 
2696
        if (getattr(source, '_format.supports_tree_reference', False) and
 
2697
            not getattr(target, '_format.supports_tree_reference', False)):
 
2698
            return False
 
2699
        return True
 
2700
 
 
2701
    @needs_write_lock
 
2702
    def fetch(self, revision_id=None, pb=None, find_ghosts=False):
 
2703
        """See InterRepository.fetch()."""
 
2704
        revision_ids = self.target.missing_revision_ids(self.source,
 
2705
                                                        revision_id)
 
2706
        def revisions_iterator():
 
2707
            for current_revision_id in revision_ids:
 
2708
                revision = self.source.get_revision(current_revision_id)
 
2709
                tree = self.source.revision_tree(current_revision_id)
 
2710
                try:
 
2711
                    signature = self.source.get_signature_text(
 
2712
                        current_revision_id)
 
2713
                except errors.NoSuchRevision:
 
2714
                    signature = None
 
2715
                yield revision, tree, signature
 
2716
        install_revisions(self.target, revisions_iterator())
 
2717
        return len(revision_ids), 0
 
2718
 
 
2719
 
2654
2720
class InterRemoteToOther(InterRepository):
2655
2721
 
2656
2722
    def __init__(self, source, target):
2720
2786
        return None
2721
2787
 
2722
2788
 
 
2789
InterRepository.register_optimiser(InterDifferingSerializer)
2723
2790
InterRepository.register_optimiser(InterSameDataRepository)
2724
2791
InterRepository.register_optimiser(InterWeaveRepo)
2725
2792
InterRepository.register_optimiser(InterKnitRepo)