67
67
class CommitBuilder(object):
68
68
"""Provides an interface to build up a commit.
70
This allows describing a tree to be committed without needing to
70
This allows describing a tree to be committed without needing to
71
71
know the internals of the format of the repository.
74
74
# all clients should supply tree roots.
75
75
record_root_entry = True
76
76
# the default CommitBuilder does not manage trees whose root is versioned.
120
120
self._generate_revision_if_needed()
121
121
self.__heads = graph.HeadsCache(repository.get_graph()).heads
122
self.basis_delta = []
122
self._basis_delta = []
123
# API compatibility, older code that used CommitBuilder did not call
124
# .record_delete(), which means the delta that is computed would not be
125
# valid. Callers that will call record_delete() should call
126
# .will_record_deletes() to indicate that.
123
127
self._recording_deletes = False
125
129
def _validate_unicode_text(self, text, context):
233
237
if ie.file_id not in basis_inv:
235
239
result = (None, path, ie.file_id, ie)
236
self.basis_delta.append(result)
240
self._basis_delta.append(result)
238
242
elif ie != basis_inv[ie.file_id]:
239
243
# common but altered
240
244
# TODO: avoid tis id2path call.
241
245
result = (basis_inv.id2path(ie.file_id), path, ie.file_id, ie)
242
self.basis_delta.append(result)
246
self._basis_delta.append(result)
245
249
# common, unaltered
252
def get_basis_delta(self):
253
"""Return the complete inventory delta versus the basis inventory.
255
This has been built up with the calls to record_delete and
256
record_entry_contents. The client must have already called
257
will_record_deletes() to indicate that they will be generating a
260
:return: An inventory delta, suitable for use with apply_delta, or
261
Repository.add_inventory_by_delta, etc.
263
if not self._recording_deletes:
264
raise AssertionError("recording deletes not activated.")
265
return self._basis_delta
248
267
def record_delete(self, path, file_id):
249
268
"""Record that a delete occured against a basis tree.
251
270
This is an optional API - when used it adds items to the basis_delta
252
271
being accumulated by the commit builder. It cannot be called unless the
253
method recording_deletes() has been called to inform the builder that a
254
delta is being supplied.
272
method will_record_deletes() has been called to inform the builder that
273
a delta is being supplied.
256
275
:param path: The path of the thing deleted.
257
276
:param file_id: The file id that was deleted.
259
278
if not self._recording_deletes:
260
279
raise AssertionError("recording deletes not activated.")
261
self.basis_delta.append((path, None, file_id, None))
280
self._basis_delta.append((path, None, file_id, None))
263
def recording_deletes(self):
282
def will_record_deletes(self):
264
283
"""Tell the commit builder that deletes are being notified.
266
285
This enables the accumulation of an inventory delta; for the resulting
267
commit to be valid deletes against the basis MUST be recorded via
286
commit to be valid, deletes against the basis MUST be recorded via
268
287
builder.record_delete().
270
289
self._recording_deletes = True
340
359
delta = (None, path, ie.file_id, ie)
341
self.basis_delta.append(delta)
360
self._basis_delta.append(delta)
342
361
return delta, False, None
344
363
# we don't need to commit this, because the caller already