143
143
what_to_do = self.from_repository.get_data_about_revision_ids(revs)
144
for knit_kind, file_id, revisions in what_to_do:
145
if knit_kind == "file":
146
self._fetch_weave_text(file_id, revisions)
147
elif knit_kind == "inventory":
149
# Once we've processed all the files, then we generate the root
150
# texts (if necessary), then we process the inventory. It's a
151
# bit distasteful to have knit_kind == "inventory" mean this,
152
# perhaps it should happen on the first non-"file" knit, in case
153
# it's not always inventory?
154
self._generate_root_texts(revs)
155
self._fetch_inventory_weave(revs)
156
elif knit_kind == "revisions":
157
self._fetch_revision_texts(revs)
159
raise AssertionError("Unknown knit kind %r" % knit_kind)
148
for knit_kind, file_id, revisions in what_to_do:
149
if knit_kind != phase:
152
# Make a new progress bar for this phase (and finish the
153
# previous one, if any).
156
pb = bzrlib.ui.ui_factory.nested_progress_bar()
157
if knit_kind == "file":
158
pb.update("fetch texts", count)
160
self._fetch_weave_text(file_id, revisions)
161
elif knit_kind == "inventory":
163
# Once we've processed all the files, then we generate the root
164
# texts (if necessary), then we process the inventory. It's a
165
# bit distasteful to have knit_kind == "inventory" mean this,
166
# perhaps it should happen on the first non-"file" knit, in case
167
# it's not always inventory?
168
self._generate_root_texts(revs)
169
self._fetch_inventory_weave(revs, pb)
170
elif knit_kind == "revisions":
171
self._fetch_revision_texts(revs, pb)
173
raise AssertionError("Unknown knit kind %r" % knit_kind)
160
177
self.count_copied += len(revs)
162
179
def _revids_to_fetch(self):
180
"""Determines the exact revisions needed from self.from_repository to
181
install self._last_revision in self.to_repository.
183
If no revisions need to be fetched, then this just returns None.
163
185
mutter('fetch up to rev {%s}', self._last_revision)
164
186
if self._last_revision is NULL_REVISION:
165
187
# explicit limit of no revisions needed
174
196
except errors.NoSuchRevision:
175
197
raise InstallFailed([self._last_revision])
177
def _fetch_weave_texts(self, revs):
178
texts_pb = bzrlib.ui.ui_factory.nested_progress_bar()
180
# fileids_altered_by_revision_ids requires reading the inventory
181
# weave, we will need to read the inventory weave again when
182
# all this is done, so enable caching for that specific weave
183
inv_w = self.from_repository.get_inventory_weave()
185
file_ids = self.from_repository.fileids_altered_by_revision_ids(revs)
187
num_file_ids = len(file_ids)
188
for file_id, required_versions in file_ids.items():
189
texts_pb.update("fetch texts", count, num_file_ids)
191
self._fetch_weave_text(file_id, required_versions)
195
199
def _fetch_weave_text(self, file_id, required_versions):
196
200
to_weave = self.to_weaves.get_weave_or_empty(file_id,
197
201
self.to_repository.get_transaction())
210
214
from_weave.clear_cache()
211
215
to_weave.clear_cache()
213
def _fetch_inventory_weave(self, revs):
214
pb = bzrlib.ui.ui_factory.nested_progress_bar()
217
def _fetch_inventory_weave(self, revs, pb):
218
pb.update("fetch inventory", 0, 2)
219
to_weave = self.to_control.get_weave('inventory',
220
self.to_repository.get_transaction())
222
child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
216
pb.update("fetch inventory", 0, 2)
217
to_weave = self.to_control.get_weave('inventory',
218
self.to_repository.get_transaction())
220
child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
222
# just merge, this is optimisable and its means we don't
223
# copy unreferenced data such as not-needed inventories.
224
pb.update("fetch inventory", 1, 3)
225
from_weave = self.from_repository.get_inventory_weave()
226
pb.update("fetch inventory", 2, 3)
227
# we fetch only the referenced inventories because we do not
228
# know for unselected inventories whether all their required
229
# texts are present in the other repository - it could be
231
to_weave.join(from_weave, pb=child_pb, msg='merge inventory',
233
from_weave.clear_cache()
224
# just merge, this is optimisable and its means we don't
225
# copy unreferenced data such as not-needed inventories.
226
pb.update("fetch inventory", 1, 3)
227
from_weave = self.from_repository.get_inventory_weave()
228
pb.update("fetch inventory", 2, 3)
229
# we fetch only the referenced inventories because we do not
230
# know for unselected inventories whether all their required
231
# texts are present in the other repository - it could be
233
to_weave.join(from_weave, pb=child_pb, msg='merge inventory',
235
from_weave.clear_cache()
239
239
def _generate_root_texts(self, revs):
240
240
"""This will be called by __fetch between fetching weave texts and
253
253
It triggers a reconciliation after fetching to ensure integrity.
256
def _fetch_revision_texts(self, revs):
256
def _fetch_revision_texts(self, revs, pb):
257
257
"""Fetch revision object texts"""
258
rev_pb = bzrlib.ui.ui_factory.nested_progress_bar()
260
to_txn = self.to_transaction = self.to_repository.get_transaction()
263
to_store = self.to_repository._revision_store
265
pb = bzrlib.ui.ui_factory.nested_progress_bar()
267
pb.update('copying revisions', count, total)
269
sig_text = self.from_repository.get_signature_text(rev)
270
to_store.add_revision_signature_text(rev, sig_text, to_txn)
271
except errors.NoSuchRevision:
274
to_store.add_revision(self.from_repository.get_revision(rev),
279
# fixup inventory if needed:
280
# this is expensive because we have no inverse index to current ghosts.
281
# but on local disk its a few seconds and sftp push is already insane.
283
# FIXME: repository should inform if this is needed.
284
self.to_repository.reconcile()
258
to_txn = self.to_transaction = self.to_repository.get_transaction()
261
to_store = self.to_repository._revision_store
263
pb.update('copying revisions', count, total)
265
sig_text = self.from_repository.get_signature_text(rev)
266
to_store.add_revision_signature_text(rev, sig_text, to_txn)
267
except errors.NoSuchRevision:
270
to_store.add_revision(self.from_repository.get_revision(rev),
273
# fixup inventory if needed:
274
# this is expensive because we have no inverse index to current ghosts.
275
# but on local disk its a few seconds and sftp push is already insane.
277
# FIXME: repository should inform if this is needed.
278
self.to_repository.reconcile()
289
281
class KnitRepoFetcher(RepoFetcher):
294
286
copy revision texts.
297
def _fetch_revision_texts(self, revs):
289
def _fetch_revision_texts(self, revs, pb):
298
290
# may need to be a InterRevisionStore call here.
299
291
from_transaction = self.from_repository.get_transaction()
300
292
to_transaction = self.to_repository.get_transaction()
384
376
GenericRepoFetcher.__init__(self, to_repository, from_repository,
385
377
last_revision, pb)
387
def _fetch_weave_texts(self, revs):
388
GenericRepoFetcher._fetch_weave_texts(self, revs)
389
self._generate_root_texts(revs)
391
379
def _generate_root_texts(self, revs):
392
# Now generate a weave for the tree root
393
380
self.helper.generate_root_texts(revs)
395
def _fetch_inventory_weave(self, revs):
382
def _fetch_inventory_weave(self, revs, pb):
396
383
self.helper.regenerate_inventory(revs)
405
392
KnitRepoFetcher.__init__(self, to_repository, from_repository,
406
393
last_revision, pb)
408
def _fetch_weave_texts(self, revs):
409
KnitRepoFetcher._fetch_weave_texts(self, revs)
410
self._generate_root_texts(revs)
412
395
def _generate_root_texts(self, revs):
413
# Now generate a weave for the tree root
414
396
self.helper.generate_root_texts(revs)
416
def _fetch_inventory_weave(self, revs):
398
def _fetch_inventory_weave(self, revs, pb):
417
399
self.helper.regenerate_inventory(revs)