46
43
self._inv_delta = inv_delta
47
44
self._new_info_by_id = dict([(file_id, (new_path, ie))
48
45
for _, new_path, file_id, ie in inv_delta])
46
self._new_info_by_path = {new_path: ie
47
for _, new_path, file_id, ie in inv_delta}
50
49
def id2path(self, file_id):
51
50
if file_id in self._new_info_by_id:
61
60
# need more than just root, is to defer to basis_inv.path2id() and then
62
61
# check if the file_id is in our _new_info_by_id dict. And in that
63
62
# case, return _new_info_by_id[file_id][0]
65
raise NotImplementedError(_TreeShim.path2id)
66
# TODO: Handle root renames?
67
return self._basis_inv.root.file_id
64
return self._new_info_by_path[path].file_id
66
return self._basis_inv.path2id(path)
69
def get_file_with_stat(self, path, file_id=None):
70
content = self.get_file_text(path, file_id)
68
def get_file_with_stat(self, path):
69
content = self.get_file_text(path)
71
70
sio = BytesIO(content)
74
def get_file_text(self, path, file_id=None):
76
file_id = self.path2id(path)
73
def get_file_text(self, path):
74
file_id = self.path2id(path)
78
76
return self._content_provider(file_id)
86
84
return next(stream).get_bytes_as('fulltext')
88
def get_symlink_target(self, path, file_id=None):
86
def get_symlink_target(self, path):
88
ie = self._new_info_by_path[path]
90
90
file_id = self.path2id(path)
91
if file_id in self._new_info_by_id:
92
ie = self._new_info_by_id[file_id][1]
91
return self._basis_inv.get_entry(file_id).symlink_target
93
93
return ie.symlink_target
94
return self._basis_inv.get_entry(file_id).symlink_target
96
def get_reference_revision(self, path, file_id=None):
95
def get_reference_revision(self, path):
97
96
raise NotImplementedError(_TreeShim.get_reference_revision)
99
98
def _delta_to_iter_changes(self):
121
120
raise AssertionError('How is both old and new None?')
122
121
change = (file_id,
123
(old_path, new_path),
122
(old_path, new_path),
131
130
change = (file_id,
132
(old_path, new_path),
135
(None, ie.parent_id),
138
(None, ie.executable),
131
(old_path, new_path),
134
(None, ie.parent_id),
137
(None, ie.executable),
142
141
change = (file_id,
143
(old_path, new_path),
146
(old_ie.parent_id, None),
149
(old_ie.executable, None),
142
(old_path, new_path),
145
(old_ie.parent_id, None),
148
(old_ie.executable, None),
152
content_modified = (ie.text_sha1 != old_ie.text_sha1
153
or ie.text_size != old_ie.text_size)
151
content_modified = (ie.text_sha1 != old_ie.text_sha1 or
152
ie.text_size != old_ie.text_size)
154
153
# TODO: ie.kind != old_ie.kind
155
154
# TODO: symlinks changing targets, content_modified?
156
155
change = (file_id,
157
(old_path, new_path),
160
(old_ie.parent_id, ie.parent_id),
161
(old_ie.name, ie.name),
162
(old_ie.kind, ie.kind),
163
(old_ie.executable, ie.executable),
156
(old_path, new_path),
159
(old_ie.parent_id, ie.parent_id),
160
(old_ie.name, ie.name),
161
(old_ie.kind, ie.kind),
162
(old_ie.executable, ie.executable),
213
212
inv.id_to_entry = chk_map.CHKMap(chk_store, None, search_key_func)
214
213
inv.id_to_entry._root_node.set_maximum_size(maximum_size)
215
214
inv.parent_id_basename_to_file_id = chk_map.CHKMap(chk_store,
216
None, search_key_func)
215
None, search_key_func)
217
216
inv.parent_id_basename_to_file_id._root_node.set_maximum_size(
219
218
inv.parent_id_basename_to_file_id._root_node._key_width = 2
227
226
"""Get the text stored for a file in a given revision."""
228
227
revtree = self.repo.revision_tree(revision_id)
229
228
path = revtree.id2path(file_id)
230
return revtree.get_file_text(path, file_id)
229
return revtree.get_file_text(path)
232
231
def get_file_lines(self, revision_id, file_id):
233
232
"""Get the lines stored for a file in a given revision."""
234
233
revtree = self.repo.revision_tree(revision_id)
235
234
path = revtree.id2path(file_id)
236
return osutils.split_lines(revtree.get_file_text(path, file_id))
235
return osutils.split_lines(revtree.get_file_text(path))
238
237
def start_new_revision(self, revision, parents, parent_invs):
239
238
"""Init the metadata needed for get_parents_and_revision_for_entry().
252
251
# new write group. We want one write group around a batch of imports
253
252
# where the default batch size is currently 10000. IGC 20090312
254
253
self._commit_builder = self.repo._commit_builder_class(self.repo,
255
parents, config, timestamp=revision.timestamp,
256
timezone=revision.timezone, committer=revision.committer,
257
revprops=revision.properties, revision_id=revision.revision_id)
254
parents, config, timestamp=revision.timestamp,
255
timezone=revision.timezone, committer=revision.committer,
256
revprops=revision.properties, revision_id=revision.revision_id)
259
258
def get_parents_and_revision_for_entry(self, ie):
260
259
"""Get the parents and revision for an inventory entry.
267
266
# Check for correct API usage
268
267
if self._current_rev_id is None:
269
268
raise AssertionError("start_new_revision() must be called"
270
" before get_parents_and_revision_for_entry()")
269
" before get_parents_and_revision_for_entry()")
271
270
if ie.revision != self._current_rev_id:
272
271
raise AssertionError("start_new_revision() registered a different"
273
" revision (%s) to that in the inventory entry (%s)" %
274
(self._current_rev_id, ie.revision))
272
" revision (%s) to that in the inventory entry (%s)" %
273
(self._current_rev_id, ie.revision))
276
275
# Find the heads. This code is lifted from
277
276
# repository.CommitBuilder.record_entry_contents().
278
277
parent_candidate_entries = ie.parent_candidates(self._rev_parent_invs)
279
278
head_set = self._commit_builder._heads(ie.file_id,
280
list(parent_candidate_entries))
279
list(parent_candidate_entries))
282
281
for inv in self._rev_parent_invs:
299
298
if len(heads) > 1:
301
elif (parent_entry.name != ie.name or parent_entry.kind != ie.kind or
302
parent_entry.parent_id != ie.parent_id):
300
elif (parent_entry.name != ie.name or parent_entry.kind != ie.kind
301
or parent_entry.parent_id != ie.parent_id):
304
303
elif ie.kind == 'file':
305
if (parent_entry.text_sha1 != ie.text_sha1 or
306
parent_entry.executable != ie.executable):
304
if (parent_entry.text_sha1 != ie.text_sha1
305
or parent_entry.executable != ie.executable):
308
307
elif ie.kind == 'symlink':
309
308
if parent_entry.symlink_target != ie.symlink_target:
315
314
return tuple(heads), rev_id
317
316
def load_using_delta(self, rev, basis_inv, inv_delta, signature,
318
text_provider, parents_provider, inventories_provider=None):
317
text_provider, parents_provider, inventories_provider=None):
319
318
"""Load a revision by applying a delta to a (CHK)Inventory.
321
320
:param rev: the Revision
336
335
# TODO: set revision_id = rev.revision_id
337
336
builder = self.repo._commit_builder_class(self.repo,
338
parents=rev.parent_ids, config=None, timestamp=rev.timestamp,
339
timezone=rev.timezone, committer=rev.committer,
340
revprops=rev.properties, revision_id=rev.revision_id)
337
parents=rev.parent_ids, config=None, timestamp=rev.timestamp,
338
timezone=rev.timezone, committer=rev.committer,
339
revprops=rev.properties, revision_id=rev.revision_id)
341
340
if self._graph is None and self._use_known_graph:
342
if (getattr(_mod_graph, 'GraphThunkIdsToKeys', None) and
343
getattr(_mod_graph.GraphThunkIdsToKeys, "add_node", None) and
344
getattr(self.repo, "get_known_graph_ancestry", None)):
341
if (getattr(_mod_graph, 'GraphThunkIdsToKeys', None)
342
and getattr(_mod_graph.GraphThunkIdsToKeys, "add_node", None)
343
and getattr(self.repo, "get_known_graph_ancestry", None)):
345
344
self._graph = self.repo.get_known_graph_ancestry(
348
347
self._use_known_graph = False
349
348
if self._graph is not None:
350
349
orig_heads = builder._heads
351
351
def thunked_heads(file_id, revision_ids):
352
352
# self._graph thinks in terms of keys, not ids, so translate
367
367
basis_rev_id = _mod_revision.NULL_REVISION
368
368
tree = _TreeShim(self.repo, basis_inv, inv_delta, text_provider)
369
369
changes = tree._delta_to_iter_changes()
370
for (file_id, path, fs_hash) in builder.record_iter_changes(
370
for (path, fs_hash) in builder.record_iter_changes(
371
371
tree, basis_rev_id, changes):
372
372
# So far, we don't *do* anything with the result
384
384
rev.inv_sha1 = builder.inv_sha1
385
385
config = builder._config_stack
386
386
builder.repository.add_revision(builder._new_revision_id, rev,
387
builder.revision_tree().root_inventory)
387
builder.revision_tree().root_inventory)
388
388
if self._graph is not None:
389
389
# TODO: Use StaticTuple and .intern() for these things
390
390
self._graph.add_node(builder._new_revision_id, rev.parent_ids)
397
397
def get_file_lines(self, revision_id, file_id):
398
398
record = next(self.repo.texts.get_record_stream([(file_id, revision_id)],
400
400
if record.storage_kind == 'absent':
401
401
raise errors.RevisionNotPresent(record.key, self.repo)
402
402
return osutils.split_lines(record.get_bytes_as('fulltext'))