~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Jelmer Vernooij
  • Date: 2011-03-10 13:52:27 UTC
  • mto: (5712.4.5 bzrdir-weave)
  • mto: This revision was merged to the branch mainline in revision 5716.
  • Revision ID: jelmer@samba.org-20110310135227-ufcw0utlwsp8r6k6
Revert registry changes.

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
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):
2773
2770
                except UnicodeDecodeError:
2774
2771
                    raise errors.NonAsciiRevisionId(method, self)
2775
2772
 
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.
 
2773
    def revision_graph_can_have_wrong_parents(self):
 
2774
        """Is it possible for this repository to have a revision graph with
 
2775
        incorrect parents?
2779
2776
 
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).
 
2777
        If True, then this repository must also implement
 
2778
        _find_inconsistent_revision_parents so that check and reconcile can
 
2779
        check for inconsistencies before proceeding with other checks that may
 
2780
        depend on the revision index being consistent.
2784
2781
        """
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.")
 
2782
        raise NotImplementedError(self.revision_graph_can_have_wrong_parents)
2806
2783
 
2807
2784
 
2808
2785
def install_revision(repository, rev, revision_tree):
2867
2844
        for revision, tree in parent_trees.iteritems():
2868
2845
            if ie.file_id not in tree:
2869
2846
                continue
2870
 
            parent_id = tree.get_file_revision(ie.file_id)
 
2847
            parent_id = tree.inventory[ie.file_id].revision
2871
2848
            if parent_id in text_parents:
2872
2849
                continue
2873
2850
            text_parents.append((ie.file_id, parent_id))
3045
3022
    supports_leaving_lock = None
3046
3023
    # Does this format support the full VersionedFiles interface?
3047
3024
    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
3052
3025
 
3053
3026
    def __repr__(self):
3054
3027
        return "%s()" % self.__class__.__name__
3106
3079
        """Return the short description for this format."""
3107
3080
        raise NotImplementedError(self.get_format_description)
3108
3081
 
 
3082
    # TODO: this shouldn't be in the base class, it's specific to things that
 
3083
    # use weaves or knits -- mbp 20070207
 
3084
    def _get_versioned_file_store(self,
 
3085
                                  name,
 
3086
                                  transport,
 
3087
                                  control_files,
 
3088
                                  prefixed=True,
 
3089
                                  versionedfile_class=None,
 
3090
                                  versionedfile_kwargs={},
 
3091
                                  escaped=False):
 
3092
        if versionedfile_class is None:
 
3093
            versionedfile_class = self._versionedfile_class
 
3094
        weave_transport = control_files._transport.clone(name)
 
3095
        dir_mode = control_files._dir_mode
 
3096
        file_mode = control_files._file_mode
 
3097
        return VersionedFileStore(weave_transport, prefixed=prefixed,
 
3098
                                  dir_mode=dir_mode,
 
3099
                                  file_mode=file_mode,
 
3100
                                  versionedfile_class=versionedfile_class,
 
3101
                                  versionedfile_kwargs=versionedfile_kwargs,
 
3102
                                  escaped=escaped)
 
3103
 
3109
3104
    def initialize(self, a_bzrdir, shared=False):
3110
3105
        """Initialize a repository of this format in a_bzrdir.
3111
3106
 
3223
3218
        return self.get_format_string()
3224
3219
 
3225
3220
 
 
3221
# Pre-0.8 formats that don't have a disk format string (because they are
 
3222
# versioned by the matching control directory). We use the control directories
 
3223
# disk format string as a key for the network_name because they meet the
 
3224
# constraints (simple string, unique, immutable).
 
3225
network_format_registry.register_lazy(
 
3226
    "Bazaar-NG branch, format 5\n",
 
3227
    'bzrlib.repofmt.weaverepo',
 
3228
    'RepositoryFormat5',
 
3229
)
 
3230
network_format_registry.register_lazy(
 
3231
    "Bazaar-NG branch, format 6\n",
 
3232
    'bzrlib.repofmt.weaverepo',
 
3233
    'RepositoryFormat6',
 
3234
)
 
3235
 
 
3236
format_registry.register_extra_lazy(
 
3237
    'bzrlib.repofmt.weaverepo',
 
3238
    'RepositoryFormat4')
 
3239
format_registry.register_extra_lazy(
 
3240
    'bzrlib.repofmt.weaverepo',
 
3241
    'RepositoryFormat5')
 
3242
format_registry.register_extra_lazy(
 
3243
    'bzrlib.repofmt.weaverepo',
 
3244
    'RepositoryFormat6')
 
3245
 
3226
3246
# formats which have no format string are not discoverable or independently
3227
3247
# 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
 
3248
# all in bzrlib.repofmt.weaverepo now.  When an instance of one of these is
3229
3249
# needed, it's constructed directly by the BzrDir.  Non-native formats where
3230
3250
# the repository is not separately opened are similar.
3231
3251
 
3232
3252
format_registry.register_lazy(
 
3253
    'Bazaar-NG Repository format 7',
 
3254
    'bzrlib.repofmt.weaverepo',
 
3255
    'RepositoryFormat7'
 
3256
    )
 
3257
 
 
3258
format_registry.register_lazy(
3233
3259
    'Bazaar-NG Knit Repository Format 1',
3234
3260
    'bzrlib.repofmt.knitrepo',
3235
3261
    'RepositoryFormatKnit1',
3252
3278
# NOTE: These are experimental in 0.92. Stable in 1.0 and above
3253
3279
format_registry.register_lazy(
3254
3280
    'Bazaar pack repository format 1 (needs bzr 0.92)\n',
3255
 
    'bzrlib.repofmt.knitpack_repo',
 
3281
    'bzrlib.repofmt.pack_repo',
3256
3282
    'RepositoryFormatKnitPack1',
3257
3283
    )
3258
3284
format_registry.register_lazy(
3259
3285
    'Bazaar pack repository format 1 with subtree support (needs bzr 0.92)\n',
3260
 
    'bzrlib.repofmt.knitpack_repo',
 
3286
    'bzrlib.repofmt.pack_repo',
3261
3287
    'RepositoryFormatKnitPack3',
3262
3288
    )
3263
3289
format_registry.register_lazy(
3264
3290
    'Bazaar pack repository format 1 with rich root (needs bzr 1.0)\n',
3265
 
    'bzrlib.repofmt.knitpack_repo',
 
3291
    'bzrlib.repofmt.pack_repo',
3266
3292
    'RepositoryFormatKnitPack4',
3267
3293
    )
3268
3294
format_registry.register_lazy(
3269
3295
    'Bazaar RepositoryFormatKnitPack5 (bzr 1.6)\n',
3270
 
    'bzrlib.repofmt.knitpack_repo',
 
3296
    'bzrlib.repofmt.pack_repo',
3271
3297
    'RepositoryFormatKnitPack5',
3272
3298
    )
3273
3299
format_registry.register_lazy(
3274
3300
    'Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6.1)\n',
3275
 
    'bzrlib.repofmt.knitpack_repo',
 
3301
    'bzrlib.repofmt.pack_repo',
3276
3302
    'RepositoryFormatKnitPack5RichRoot',
3277
3303
    )
3278
3304
format_registry.register_lazy(
3279
3305
    'Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6)\n',
3280
 
    'bzrlib.repofmt.knitpack_repo',
 
3306
    'bzrlib.repofmt.pack_repo',
3281
3307
    'RepositoryFormatKnitPack5RichRootBroken',
3282
3308
    )
3283
3309
format_registry.register_lazy(
3284
3310
    'Bazaar RepositoryFormatKnitPack6 (bzr 1.9)\n',
3285
 
    'bzrlib.repofmt.knitpack_repo',
 
3311
    'bzrlib.repofmt.pack_repo',
3286
3312
    'RepositoryFormatKnitPack6',
3287
3313
    )
3288
3314
format_registry.register_lazy(
3289
3315
    'Bazaar RepositoryFormatKnitPack6RichRoot (bzr 1.9)\n',
3290
 
    'bzrlib.repofmt.knitpack_repo',
 
3316
    'bzrlib.repofmt.pack_repo',
3291
3317
    'RepositoryFormatKnitPack6RichRoot',
3292
3318
    )
3293
3319
format_registry.register_lazy(
3301
3327
format_registry.register_lazy(
3302
3328
    ("Bazaar development format 2 with subtree support "
3303
3329
        "(needs bzr.dev from before 1.8)\n"),
3304
 
    'bzrlib.repofmt.knitpack_repo',
 
3330
    'bzrlib.repofmt.pack_repo',
3305
3331
    'RepositoryFormatPackDevelopment2Subtree',
3306
3332
    )
3307
3333
format_registry.register_lazy(
3998
4024
        return wrong_parents, unused_keys
3999
4025
 
4000
4026
 
 
4027
def _old_get_graph(repository, revision_id):
 
4028
    """DO NOT USE. That is all. I'm serious."""
 
4029
    graph = repository.get_graph()
 
4030
    revision_graph = dict(((key, value) for key, value in
 
4031
        graph.iter_ancestry([revision_id]) if value is not None))
 
4032
    return _strip_NULL_ghosts(revision_graph)
 
4033
 
 
4034
 
4001
4035
def _strip_NULL_ghosts(revision_graph):
4002
4036
    """Also don't use this. more compatibility code for unmigrated clients."""
4003
4037
    # Filter ghosts, and null:
4176
4210
                parse_result = deserialiser.parse_text_bytes(
4177
4211
                    inventory_delta_bytes)
4178
4212
            except inventory_delta.IncompatibleInventoryDelta, err:
4179
 
                mutter("Incompatible delta: %s", err.msg)
 
4213
                trace.mutter("Incompatible delta: %s", err.msg)
4180
4214
                raise errors.IncompatibleRevision(self.target_repo._format)
4181
4215
            basis_id, new_id, rich_root, tree_refs, inv_delta = parse_result
4182
4216
            revision_id = new_id
4517
4551
    except StopIteration:
4518
4552
        # No more history
4519
4553
        return
 
4554
 
 
4555
 
 
4556