120
120
"Mismatch between inventory revision" \
121
121
" id and insertion revid (%r, %r)" % (inv.revision_id, revision_id)
122
122
assert inv.root is not None
123
inv_text = self.serialise_inventory(inv)
124
inv_sha1 = osutils.sha_string(inv_text)
125
inv_vf = self.control_weaves.get_weave('inventory',
126
self.get_transaction())
127
self._inventory_add_lines(inv_vf, revision_id, parents,
128
osutils.split_lines(inv_text))
123
inv_lines = self._serialise_inventory_to_lines(inv)
124
inv_vf = self.get_inventory_weave()
125
return self._inventory_add_lines(inv_vf, revision_id, parents,
126
inv_lines, check_content=False)
131
def _inventory_add_lines(self, inv_vf, revision_id, parents, lines):
128
def _inventory_add_lines(self, inv_vf, revision_id, parents, lines,
130
"""Store lines in inv_vf and return the sha1 of the inventory."""
132
131
final_parents = []
133
132
for parent in parents:
134
133
if parent in inv_vf:
135
134
final_parents.append(parent)
137
inv_vf.add_lines(revision_id, final_parents, lines)
135
return inv_vf.add_lines(revision_id, final_parents, lines,
136
check_content=check_content)[0]
139
138
@needs_write_lock
140
139
def add_revision(self, revision_id, rev, inv=None, config=None):
447
446
def create_bundle(self, target, base, fileobj, format=None):
448
447
return serializer.write_bundle(self, target, base, fileobj, format)
450
def get_commit_builder(self, branch, parents, config, timestamp=None,
451
timezone=None, committer=None, revprops=None,
449
def get_commit_builder(self, branch, parents, config, timestamp=None,
450
timezone=None, committer=None, revprops=None,
452
451
revision_id=None):
453
452
"""Obtain a CommitBuilder for this repository.
2184
2193
if self._new_revision_id is None:
2185
2194
self._new_revision_id = self._gen_revision_id()
2187
def record_entry_contents(self, ie, parent_invs, path, tree):
2188
"""Record the content of ie from tree into the commit if needed.
2190
Side effect: sets ie.revision when unchanged
2192
:param ie: An inventory entry present in the commit.
2195
self.random_revid = True
2197
self.random_revid = False
2199
def _check_root(self, ie, parent_invs, tree):
2200
"""Helper for record_entry_contents.
2202
:param ie: An entry being added.
2193
2203
:param parent_invs: The inventories of the parent revisions of the
2195
:param path: The path the entry is at in the tree.
2196
:param tree: The tree which contains this entry and should be used to
2205
:param tree: The tree that is being committed.
2199
if self.new_inventory.root is None and ie.parent_id is not None:
2207
if ie.parent_id is not None:
2208
# if ie is not root, add a root automatically.
2200
2209
symbol_versioning.warn('Root entry should be supplied to'
2201
2210
' record_entry_contents, as of bzr 0.10.',
2202
2211
DeprecationWarning, stacklevel=2)
2203
2212
self.record_entry_contents(tree.inventory.root.copy(), parent_invs,
2205
self.new_inventory.add(ie)
2207
# ie.revision is always None if the InventoryEntry is considered
2208
# for committing. ie.snapshot will record the correct revision
2209
# which may be the sole parent if it is untouched.
2210
if ie.revision is not None:
2213
# In this revision format, root entries have no knit or weave
2214
if ie is self.new_inventory.root:
2215
# When serializing out to disk and back in
2216
# root.revision is always _new_revision_id
2215
# In this revision format, root entries have no knit or weave When
2216
# serializing out to disk and back in root.revision is always
2217
2218
ie.revision = self._new_revision_id
2220
def record_entry_contents(self, ie, parent_invs, path, tree):
2221
"""Record the content of ie from tree into the commit if needed.
2223
Side effect: sets ie.revision when unchanged
2225
:param ie: An inventory entry present in the commit.
2226
:param parent_invs: The inventories of the parent revisions of the
2228
:param path: The path the entry is at in the tree.
2229
:param tree: The tree which contains this entry and should be used to
2232
if self.new_inventory.root is None:
2233
self._check_root(ie, parent_invs, tree)
2234
self.new_inventory.add(ie)
2236
# ie.revision is always None if the InventoryEntry is considered
2237
# for committing. ie.snapshot will record the correct revision
2238
# which may be the sole parent if it is untouched.
2239
if ie.revision is not None:
2219
previous_entries = ie.find_previous_heads(
2221
self.repository.weave_store,
2222
self.repository.get_transaction())
2223
# we are creating a new revision for ie in the history store
2242
parent_candiate_entries = ie.parent_candidates(parent_invs)
2243
heads = self.repository.get_graph().heads(parent_candiate_entries.keys())
2244
# XXX: Note that this is unordered - and this is tolerable because
2245
# the previous code was also unordered.
2246
previous_entries = dict((head, parent_candiate_entries[head]) for head
2248
# we are creating a new revision for ie in the history store and
2225
2250
ie.snapshot(self._new_revision_id, path, previous_entries, tree, self)
2227
2252
def modified_directory(self, file_id, file_parents):
2282
2307
def _add_text_to_weave(self, file_id, new_lines, parents):
2283
2308
versionedfile = self.repository.weave_store.get_weave_or_empty(
2284
2309
file_id, self.repository.get_transaction())
2285
result = versionedfile.add_lines(
2286
self._new_revision_id, parents, new_lines)[0:2]
2310
# Don't change this to add_lines - add_lines_with_ghosts is cheaper
2311
# than add_lines, and allows committing when a parent is ghosted for
2313
# Note: as we read the content directly from the tree, we know its not
2314
# been turned into unicode or badly split - but a broken tree
2315
# implementation could give us bad output from readlines() so this is
2316
# not a guarantee of safety. What would be better is always checking
2317
# the content during test suite execution. RBC 20070912
2318
result = versionedfile.add_lines_with_ghosts(
2319
self._new_revision_id, parents, new_lines,
2320
random_id=self.random_revid, check_content=False)[0:2]
2287
2321
versionedfile.clear_cache()
2291
class _CommitBuilder(CommitBuilder):
2292
"""Temporary class so old CommitBuilders are detected properly
2294
Note: CommitBuilder works whether or not root entry is recorded.
2297
record_root_entry = True
2300
2325
class RootCommitBuilder(CommitBuilder):
2301
2326
"""This commitbuilder actually records the root id"""
2303
record_root_entry = True
2305
def record_entry_contents(self, ie, parent_invs, path, tree):
2306
"""Record the content of ie from tree into the commit if needed.
2308
Side effect: sets ie.revision when unchanged
2310
:param ie: An inventory entry present in the commit.
2328
def _check_root(self, ie, parent_invs, tree):
2329
"""Helper for record_entry_contents.
2331
:param ie: An entry being added.
2311
2332
:param parent_invs: The inventories of the parent revisions of the
2313
:param path: The path the entry is at in the tree.
2314
:param tree: The tree which contains this entry and should be used to
2334
:param tree: The tree that is being committed.
2317
assert self.new_inventory.root is not None or ie.parent_id is None
2318
self.new_inventory.add(ie)
2320
# ie.revision is always None if the InventoryEntry is considered
2321
# for committing. ie.snapshot will record the correct revision
2322
# which may be the sole parent if it is untouched.
2323
if ie.revision is not None:
2326
previous_entries = ie.find_previous_heads(
2328
self.repository.weave_store,
2329
self.repository.get_transaction())
2330
# we are creating a new revision for ie in the history store
2332
ie.snapshot(self._new_revision_id, path, previous_entries, tree, self)
2336
# ie must be root for this builder
2337
assert ie.parent_id is None
2335
2340
_unescape_map = {