170
161
to_weave = self.to_weaves.get_weave_or_empty(file_id,
171
162
self.to_repository.get_transaction())
172
from_weave = self.from_weaves.get_weave(file_id,
173
self.from_repository.get_transaction())
175
if to_weave.numversions() > 0:
164
if to_weave.num_versions() > 0:
176
165
# destination has contents, must merge
178
to_weave.join(from_weave)
179
except errors.WeaveParentMismatch:
180
to_weave.reweave(from_weave)
166
from_weave = self.from_weaves.get_weave(file_id,
167
self.from_repository.get_transaction())
168
# we fetch all the texts, because texts do
169
# not reference anything, and its cheap enough
170
to_weave.join(from_weave)
182
# destination is empty, just replace it
183
to_weave = from_weave.copy()
185
self.to_weaves.put_weave(file_id, to_weave,
186
self.to_repository.get_transaction())
172
# destination is empty, just copy it.
173
# this copies all the texts, which is useful and
174
# on per-file basis quite cheap.
175
self.to_weaves.copy_multi(self.from_weaves, [file_id], self.pb,
176
self.from_repository.get_transaction(),
177
self.to_repository.get_transaction())
189
180
def _fetch_inventory_weave(self, revs):
190
181
self.pb.update("inventory fetch", 0, 2)
182
to_weave = self.to_control.get_weave('inventory',
183
self.to_repository.get_transaction())
185
# just merge, this is optimisable and its means we dont
186
# copy unreferenced data such as not-needed inventories.
187
self.pb.update("inventory fetch", 1, 2)
191
188
from_weave = self.from_repository.get_inventory_weave()
192
self.to_inventory_weave = self.to_repository.get_inventory_weave()
193
self.pb.update("inventory fetch", 1, 2)
194
self.to_inventory_weave = self.to_control.get_weave('inventory',
195
self.to_repository.get_transaction())
196
189
self.pb.update("inventory fetch", 2, 2)
198
if self.to_inventory_weave.numversions() > 0:
199
# destination has contents, must merge
190
# we fetch only the referenced inventories because we do not
191
# know for unselected inventories whether all their required
192
# texts are present in the other repository - it could be
194
to_weave.join(from_weave, pb=self.pb, msg='merge inventory',
199
class GenericRepoFetcher(RepoFetcher):
200
"""This is a generic repo to repo fetcher.
202
This makes minimal assumptions about repo layout and contents.
203
It triggers a reconciliation after fetching to ensure integrity.
206
def _fetch_revision_texts(self, revs):
207
self.to_transaction = self.to_repository.get_transaction()
211
self.pb.update('copying revisions', count, total)
201
self.to_inventory_weave.join(from_weave, pb=self.pb, msg='merge inventory')
202
except errors.WeaveParentMismatch:
203
self.to_inventory_weave.reweave(from_weave, pb=self.pb, msg='reweave inventory')
205
# destination is empty, just replace it
206
self.to_inventory_weave = from_weave.copy()
208
# must be written before pulling any revisions
209
self.to_control.put_weave('inventory', self.to_inventory_weave,
210
self.to_repository.get_transaction())
213
sig_text = self.from_repository.get_signature_text(rev)
214
self.to_repository._revision_store.add_revision_signature_text(
215
rev, sig_text, self.to_transaction)
216
except errors.NoSuchRevision:
219
self.to_repository._revision_store.add_revision(
220
self.from_repository.get_revision(rev),
223
self.pb.update('copying revisions', count, total)
224
# fixup inventory if needed:
225
# this is expensive because we have no inverse index to current ghosts.
226
# but on local disk its a few seconds and sftp push is already insane.
228
# FIXME: repository should inform if this is needed.
229
self.to_repository.reconcile()
232
class KnitRepoFetcher(RepoFetcher):
233
"""This is a knit format repository specific fetcher.
235
This differs from the GenericRepoFetcher by not doing a
236
reconciliation after copying, and using knit joining to
240
def _fetch_revision_texts(self, revs):
241
# may need to be a InterRevisionStore call here.
242
from_transaction = self.from_repository.get_transaction()
243
to_transaction = self.to_repository.get_transaction()
244
to_sf = self.to_repository._revision_store.get_signature_file(
246
from_sf = self.from_repository._revision_store.get_signature_file(
248
to_sf.join(from_sf, version_ids=revs, pb=self.pb, ignore_missing=True)
249
to_rf = self.to_repository._revision_store.get_revision_file(
251
from_rf = self.from_repository._revision_store.get_revision_file(
253
to_rf.join(from_rf, version_ids=revs, pb=self.pb)
215
256
class Fetcher(object):