100
94
def __init__(self, repository, parents, config, timestamp=None,
101
95
timezone=None, committer=None, revprops=None,
96
revision_id=None, lossy=False):
103
97
"""Initiate a CommitBuilder.
105
99
:param repository: Repository to commit to.
106
100
:param parents: Revision ids of the parents of the new revision.
107
:param config: Configuration to use.
108
101
:param timestamp: Optional timestamp recorded for commit.
109
102
:param timezone: Optional timezone for timestamp.
110
103
:param committer: Optional committer to set for commit.
111
104
:param revprops: Optional dictionary of revision properties.
112
105
: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
114
109
self._config = config
116
112
if committer is None:
117
113
self._committer = self._config.username()
240
236
def revision_tree(self):
241
237
"""Return the tree that was just committed.
243
After calling commit() this can be called to get a RevisionTree
244
representing the newly committed tree. This is preferred to
245
calling Repository.revision_tree() because that may require
246
deserializing the inventory, while we already have a copy in
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
249
245
if self.new_inventory is None:
250
246
self.new_inventory = self.repository.get_inventory(
251
247
self._new_revision_id)
252
return RevisionTree(self.repository, self.new_inventory,
248
return InventoryRevisionTree(self.repository, self.new_inventory,
253
249
self._new_revision_id)
255
251
def finish_inventory(self):
1167
1163
if config is not None and config.signature_needed():
1168
1164
if inv is None:
1169
1165
inv = self.get_inventory(revision_id)
1170
plaintext = Testament(rev, inv).as_short_text()
1166
tree = InventoryRevisionTree(self, inv, revision_id)
1167
testament = Testament(rev, tree)
1168
plaintext = testament.as_short_text()
1171
1169
self.store_revision_signature(
1172
1170
gpg.GPGStrategy(config), plaintext, revision_id)
1173
1171
# check inventory present
1790
1788
def get_commit_builder(self, branch, parents, config, timestamp=None,
1791
1789
timezone=None, committer=None, revprops=None,
1790
revision_id=None, lossy=False):
1793
1791
"""Obtain a CommitBuilder for this repository.
1795
1793
:param branch: Branch to commit to.
1800
1798
:param committer: Optional committer to set for commit.
1801
1799
:param revprops: Optional dictionary of revision properties.
1802
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
1804
1804
if self._fallback_repositories and not self._format.supports_chks:
1805
1805
raise errors.BzrError("Cannot commit directly to a stacked branch"
1806
1806
" in pre-2a formats. See "
1807
1807
"https://bugs.launchpad.net/bzr/+bug/375013 for details.")
1808
1808
result = self._commit_builder_class(self, parents, config,
1809
timestamp, timezone, committer, revprops, revision_id)
1809
timestamp, timezone, committer, revprops, revision_id,
1810
1811
self.start_write_group()
2514
2515
# TODO: refactor this to use an existing revision object
2515
2516
# so we don't need to read it in twice.
2516
2517
if revision_id == _mod_revision.NULL_REVISION:
2517
return RevisionTree(self, Inventory(root_id=None),
2518
_mod_revision.NULL_REVISION)
2518
return InventoryRevisionTree(self,
2519
Inventory(root_id=None), _mod_revision.NULL_REVISION)
2520
2521
inv = self.get_inventory(revision_id)
2521
return RevisionTree(self, inv, revision_id)
2522
return InventoryRevisionTree(self, inv, revision_id)
2523
2524
def revision_trees(self, revision_ids):
2524
2525
"""Return Trees for revisions in this repository.
2529
2530
inventories = self.iter_inventories(revision_ids)
2530
2531
for inv in inventories:
2531
yield RevisionTree(self, inv, inv.revision_id)
2532
yield InventoryRevisionTree(self, inv, inv.revision_id)
2533
2534
def _filtered_revision_trees(self, revision_ids, file_ids):
2534
2535
"""Return Tree for a revision on this branch with only some files.
2544
2545
# Should we introduce a FilteredRevisionTree class rather
2545
2546
# than pre-filter the inventory here?
2546
2547
filtered_inv = inv.filter(file_ids)
2547
yield RevisionTree(self, filtered_inv, filtered_inv.revision_id)
2548
yield InventoryRevisionTree(self, filtered_inv, filtered_inv.revision_id)
2549
2550
@needs_read_lock
2550
2551
def get_ancestry(self, revision_id, topo_sorted=True):
2772
2773
except UnicodeDecodeError:
2773
2774
raise errors.NonAsciiRevisionId(method, self)
2775
def revision_graph_can_have_wrong_parents(self):
2776
"""Is it possible for this repository to have a revision graph with
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.
2779
If True, then this repository must also implement
2780
_find_inconsistent_revision_parents so that check and reconcile can
2781
check for inconsistencies before proceeding with other checks that may
2782
depend on the revision index being consistent.
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).
2784
raise NotImplementedError(self.revision_graph_can_have_wrong_parents)
2785
if not self.is_locked():
2786
raise AssertionError()
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:
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)
2801
def _check_for_inconsistent_revision_parents(self):
2802
inconsistencies = list(self._find_inconsistent_revision_parents())
2804
raise errors.BzrCheckError(
2805
"Revision knit has inconsistent parents.")
2787
2808
def install_revision(repository, rev, revision_tree):
3024
3045
supports_leaving_lock = None
3025
3046
# Does this format support the full VersionedFiles interface?
3026
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
3028
3053
def __repr__(self):
3029
3054
return "%s()" % self.__class__.__name__
3249
3274
# NOTE: These are experimental in 0.92. Stable in 1.0 and above
3250
3275
format_registry.register_lazy(
3251
3276
'Bazaar pack repository format 1 (needs bzr 0.92)\n',
3252
'bzrlib.repofmt.pack_repo',
3277
'bzrlib.repofmt.knitpack_repo',
3253
3278
'RepositoryFormatKnitPack1',
3255
3280
format_registry.register_lazy(
3256
3281
'Bazaar pack repository format 1 with subtree support (needs bzr 0.92)\n',
3257
'bzrlib.repofmt.pack_repo',
3282
'bzrlib.repofmt.knitpack_repo',
3258
3283
'RepositoryFormatKnitPack3',
3260
3285
format_registry.register_lazy(
3261
3286
'Bazaar pack repository format 1 with rich root (needs bzr 1.0)\n',
3262
'bzrlib.repofmt.pack_repo',
3287
'bzrlib.repofmt.knitpack_repo',
3263
3288
'RepositoryFormatKnitPack4',
3265
3290
format_registry.register_lazy(
3266
3291
'Bazaar RepositoryFormatKnitPack5 (bzr 1.6)\n',
3267
'bzrlib.repofmt.pack_repo',
3292
'bzrlib.repofmt.knitpack_repo',
3268
3293
'RepositoryFormatKnitPack5',
3270
3295
format_registry.register_lazy(
3271
3296
'Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6.1)\n',
3272
'bzrlib.repofmt.pack_repo',
3297
'bzrlib.repofmt.knitpack_repo',
3273
3298
'RepositoryFormatKnitPack5RichRoot',
3275
3300
format_registry.register_lazy(
3276
3301
'Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6)\n',
3277
'bzrlib.repofmt.pack_repo',
3302
'bzrlib.repofmt.knitpack_repo',
3278
3303
'RepositoryFormatKnitPack5RichRootBroken',
3280
3305
format_registry.register_lazy(
3281
3306
'Bazaar RepositoryFormatKnitPack6 (bzr 1.9)\n',
3282
'bzrlib.repofmt.pack_repo',
3307
'bzrlib.repofmt.knitpack_repo',
3283
3308
'RepositoryFormatKnitPack6',
3285
3310
format_registry.register_lazy(
3286
3311
'Bazaar RepositoryFormatKnitPack6RichRoot (bzr 1.9)\n',
3287
'bzrlib.repofmt.pack_repo',
3312
'bzrlib.repofmt.knitpack_repo',
3288
3313
'RepositoryFormatKnitPack6RichRoot',
3290
3315
format_registry.register_lazy(
3298
3323
format_registry.register_lazy(
3299
3324
("Bazaar development format 2 with subtree support "
3300
3325
"(needs bzr.dev from before 1.8)\n"),
3301
'bzrlib.repofmt.pack_repo',
3326
'bzrlib.repofmt.knitpack_repo',
3302
3327
'RepositoryFormatPackDevelopment2Subtree',
3304
3329
format_registry.register_lazy(
4173
4198
parse_result = deserialiser.parse_text_bytes(
4174
4199
inventory_delta_bytes)
4175
4200
except inventory_delta.IncompatibleInventoryDelta, err:
4176
trace.mutter("Incompatible delta: %s", err.msg)
4201
mutter("Incompatible delta: %s", err.msg)
4177
4202
raise errors.IncompatibleRevision(self.target_repo._format)
4178
4203
basis_id, new_id, rich_root, tree_refs, inv_delta = parse_result
4179
4204
revision_id = new_id