1
# Copyright (C) 2005-2010 Canonical Ltd
1
# Copyright (C) 2005-2011 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
176
176
self._validate_unicode_text(value,
177
177
'revision property (%s)' % (key,))
179
def _ensure_fallback_inventories(self):
180
"""Ensure that appropriate inventories are available.
182
This only applies to repositories that are stacked, and is about
183
enusring the stacking invariants. Namely, that for any revision that is
184
present, we either have all of the file content, or we have the parent
185
inventory and the delta file content.
187
if not self.repository._fallback_repositories:
189
if not self.repository._format.supports_chks:
190
raise errors.BzrError("Cannot commit directly to a stacked branch"
191
" in pre-2a formats. See "
192
"https://bugs.launchpad.net/bzr/+bug/375013 for details.")
193
# This is a stacked repo, we need to make sure we have the parent
194
# inventories for the parents.
195
parent_keys = [(p,) for p in self.parents]
196
parent_map = self.repository.inventories._index.get_parent_map(parent_keys)
197
missing_parent_keys = set([pk for pk in parent_keys
198
if pk not in parent_map])
199
fallback_repos = list(reversed(self.repository._fallback_repositories))
200
missing_keys = [('inventories', pk[0])
201
for pk in missing_parent_keys]
203
while missing_keys and fallback_repos:
204
fallback_repo = fallback_repos.pop()
205
source = fallback_repo._get_source(self.repository._format)
206
sink = self.repository._get_sink()
207
stream = source.get_stream_for_missing_keys(missing_keys)
208
missing_keys = sink.insert_stream_without_locking(stream,
209
self.repository._format)
211
raise errors.BzrError('Unable to fill in parent inventories for a'
179
214
def commit(self, message):
180
215
"""Make the actual commit.
193
228
rev.parent_ids = self.parents
194
229
self.repository.add_revision(self._new_revision_id, rev,
195
230
self.new_inventory, self._config)
231
self._ensure_fallback_inventories()
196
232
self.repository.commit_write_group()
197
233
return self._new_revision_id
1761
1797
:param revprops: Optional dictionary of revision properties.
1762
1798
:param revision_id: Optional revision id.
1764
if self._fallback_repositories:
1765
raise errors.BzrError("Cannot commit from a lightweight checkout "
1766
"to a stacked branch. See "
1800
if self._fallback_repositories and not self._format.supports_chks:
1801
raise errors.BzrError("Cannot commit directly to a stacked branch"
1802
" in pre-2a formats. See "
1767
1803
"https://bugs.launchpad.net/bzr/+bug/375013 for details.")
1768
1804
result = self._commit_builder_class(self, parents, config,
1769
1805
timestamp, timezone, committer, revprops, revision_id)
4054
4090
is_resume = False
4056
4092
# locked_insert_stream performs a commit|suspend.
4057
return self._locked_insert_stream(stream, src_format,
4093
missing_keys = self.insert_stream_without_locking(stream,
4094
src_format, is_resume)
4096
# suspend the write group and tell the caller what we is
4097
# missing. We know we can suspend or else we would not have
4098
# entered this code path. (All repositories that can handle
4099
# missing keys can handle suspending a write group).
4100
write_group_tokens = self.target_repo.suspend_write_group()
4101
return write_group_tokens, missing_keys
4102
hint = self.target_repo.commit_write_group()
4103
to_serializer = self.target_repo._format._serializer
4104
src_serializer = src_format._serializer
4105
if (to_serializer != src_serializer and
4106
self.target_repo._format.pack_compresses):
4107
self.target_repo.pack(hint=hint)
4060
4110
self.target_repo.abort_write_group(suppress_errors=True)
4063
4113
self.target_repo.unlock()
4065
def _locked_insert_stream(self, stream, src_format, is_resume):
4115
def insert_stream_without_locking(self, stream, src_format,
4117
"""Insert a stream's content into the target repository.
4119
This assumes that you already have a locked repository and an active
4122
:param src_format: a bzr repository format.
4123
:param is_resume: Passed down to get_missing_parent_inventories to
4124
indicate if we should be checking for missing texts at the same
4127
:return: A set of keys that are missing.
4129
if not self.target_repo.is_write_locked():
4130
raise errors.ObjectNotLocked(self)
4131
if not self.target_repo.is_in_write_group():
4132
raise errors.BzrError('you must already be in a write group')
4066
4133
to_serializer = self.target_repo._format._serializer
4067
4134
src_serializer = src_format._serializer
4068
4135
new_pack = None
4147
4214
# cannot even attempt suspending, and missing would have failed
4148
4215
# during stream insertion.
4149
4216
missing_keys = set()
4152
# suspend the write group and tell the caller what we is
4153
# missing. We know we can suspend or else we would not have
4154
# entered this code path. (All repositories that can handle
4155
# missing keys can handle suspending a write group).
4156
write_group_tokens = self.target_repo.suspend_write_group()
4157
return write_group_tokens, missing_keys
4158
hint = self.target_repo.commit_write_group()
4159
if (to_serializer != src_serializer and
4160
self.target_repo._format.pack_compresses):
4161
self.target_repo.pack(hint=hint)
4164
4219
def _extract_and_insert_inventory_deltas(self, substream, serializer):
4165
4220
target_rich_root = self.target_repo._format.rich_root_data