/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/fetch.py

Merge bzr.dev and resolve conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
        )
41
41
from bzrlib.trace import mutter
42
42
import bzrlib.ui
43
 
 
44
 
from bzrlib.lazy_import import lazy_import
 
43
from bzrlib.versionedfile import filter_absent
45
44
 
46
45
# TODO: Avoid repeatedly opening weaves so many times.
47
46
 
112
111
                else:
113
112
                    self.to_repository.commit_write_group()
114
113
            finally:
115
 
                if self.nested_pb is not None:
116
 
                    self.nested_pb.finished()
117
 
                self.to_repository.unlock()
 
114
                try:
 
115
                    if self.nested_pb is not None:
 
116
                        self.nested_pb.finished()
 
117
                finally:
 
118
                    self.to_repository.unlock()
118
119
        finally:
119
120
            self.from_repository.unlock()
120
121
 
156
157
        pb = bzrlib.ui.ui_factory.nested_progress_bar()
157
158
        try:
158
159
            revs = search.get_keys()
159
 
            data_to_fetch = self.from_repository.item_keys_introduced_by(revs, pb)
 
160
            graph = self.from_repository.get_graph()
 
161
            revs = list(graph.iter_topo_order(revs))
 
162
            data_to_fetch = self.from_repository.item_keys_introduced_by(revs,
 
163
                                                                         pb)
160
164
            for knit_kind, file_id, revisions in data_to_fetch:
161
165
                if knit_kind != phase:
162
166
                    phase = knit_kind
212
216
            self.to_repository.get_transaction())
213
217
        from_weave = self.from_weaves.get_weave(file_id,
214
218
            self.from_repository.get_transaction())
215
 
        # we fetch all the texts, because texts do
216
 
        # not reference anything, and its cheap enough
217
 
        to_weave.join(from_weave, version_ids=required_versions)
 
219
        # Fetch all the texts.
 
220
        to_weave.insert_record_stream(from_weave.get_record_stream(
 
221
            required_versions, 'topological', False))
218
222
 
219
223
    def _fetch_inventory_weave(self, revs, pb):
220
224
        pb.update("fetch inventory", 0, 2)
230
234
            # know for unselected inventories whether all their required
231
235
            # texts are present in the other repository - it could be
232
236
            # corrupt.
233
 
            to_weave.join(from_weave, pb=child_pb, msg='merge inventory',
234
 
                          version_ids=revs)
 
237
            to_weave.insert_record_stream(from_weave.get_record_stream(revs,
 
238
                'topological', False))
235
239
        finally:
236
240
            child_pb.finished()
237
241
 
266
270
            except errors.NoSuchRevision:
267
271
                # not signed.
268
272
                pass
269
 
            to_store.add_revision(self.from_repository.get_revision(rev),
270
 
                                  to_txn)
 
273
            self._copy_revision(rev, to_txn)
271
274
            count += 1
272
275
        # fixup inventory if needed: 
273
276
        # this is expensive because we have no inverse index to current ghosts.
275
278
        # so we just-do-it.
276
279
        # FIXME: repository should inform if this is needed.
277
280
        self.to_repository.reconcile()
278
 
    
 
281
 
 
282
    def _copy_revision(self, rev, to_txn):
 
283
        to_store = self.to_repository._revision_store
 
284
        to_store.add_revision(self.from_repository.get_revision(rev), to_txn)
 
285
 
279
286
 
280
287
class KnitRepoFetcher(RepoFetcher):
281
288
    """This is a knit format repository specific fetcher.
293
300
            to_transaction)
294
301
        from_sf = self.from_repository._revision_store.get_signature_file(
295
302
            from_transaction)
296
 
        to_sf.join(from_sf, version_ids=revs, ignore_missing=True)
 
303
        # A missing signature is just skipped.
 
304
        to_sf.insert_record_stream(filter_absent(from_sf.get_record_stream(revs,
 
305
            'unordered', False)))
 
306
        self._fetch_just_revision_texts(revs, from_transaction, to_transaction)
 
307
 
 
308
    def _fetch_just_revision_texts(self, version_ids, from_transaction,
 
309
                                   to_transaction):
297
310
        to_rf = self.to_repository._revision_store.get_revision_file(
298
311
            to_transaction)
299
312
        from_rf = self.from_repository._revision_store.get_revision_file(
300
313
            from_transaction)
301
 
        to_rf.join(from_rf, version_ids=revs)
 
314
        to_rf.insert_record_stream(from_rf.get_record_stream(version_ids,
 
315
            'topological', False))
302
316
 
303
317
 
304
318
class Inter1and2Helper(object):
335
349
                yield tree
336
350
            revs = revs[100:]
337
351
 
 
352
    def _find_root_ids(self, revs, parent_map, graph):
 
353
        revision_root = {}
 
354
        planned_versions = {}
 
355
        for tree in self.iter_rev_trees(revs):
 
356
            revision_id = tree.inventory.root.revision
 
357
            root_id = tree.get_root_id()
 
358
            planned_versions.setdefault(root_id, []).append(revision_id)
 
359
            revision_root[revision_id] = root_id
 
360
        # Find out which parents we don't already know root ids for
 
361
        parents = set()
 
362
        for revision_parents in parent_map.itervalues():
 
363
            parents.update(revision_parents)
 
364
        parents.difference_update(revision_root.keys() + [NULL_REVISION])
 
365
        # Limit to revisions present in the versionedfile
 
366
        parents = graph.get_parent_map(parents).keys()
 
367
        for tree in self.iter_rev_trees(parents):
 
368
            root_id = tree.get_root_id()
 
369
            revision_root[tree.get_revision_id()] = root_id
 
370
        return revision_root, planned_versions
 
371
 
338
372
    def generate_root_texts(self, revs):
339
373
        """Generate VersionedFiles for all root ids.
340
 
        
 
374
 
341
375
        :param revs: the revisions to include
342
376
        """
343
 
        inventory_weave = self.source.get_inventory_weave()
344
 
        parent_texts = {}
345
 
        versionedfile = {}
346
377
        to_store = self.target.weave_store
347
 
        parent_map = self.source.get_graph().get_parent_map(revs)
348
 
        for tree in self.iter_rev_trees(revs):
349
 
            revision_id = tree.inventory.root.revision
350
 
            root_id = tree.get_root_id()
351
 
            parents = parent_map[revision_id]
352
 
            if parents[0] == NULL_REVISION:
353
 
                parents = ()
354
 
            if root_id not in versionedfile:
355
 
                versionedfile[root_id] = to_store.get_weave_or_empty(root_id,
356
 
                    self.target.get_transaction())
357
 
            _, _, parent_texts[root_id] = versionedfile[root_id].add_lines(
358
 
                revision_id, parents, [], parent_texts)
 
378
        graph = self.source.get_graph()
 
379
        parent_map = graph.get_parent_map(revs)
 
380
        revision_root, planned_versions = self._find_root_ids(
 
381
            revs, parent_map, graph)
 
382
        for root_id, versions in planned_versions.iteritems():
 
383
            versionedfile = to_store.get_weave_or_empty(root_id,
 
384
                self.target.get_transaction())
 
385
            parent_texts = {}
 
386
            for revision_id in versions:
 
387
                if revision_id in versionedfile:
 
388
                    continue
 
389
                parents = parent_map[revision_id]
 
390
                # We drop revision parents with different file-ids, because
 
391
                # a version cannot have a version with another file-id as its
 
392
                # parent.
 
393
                # When a parent revision is a ghost, we guess that its root id
 
394
                # was unchanged.
 
395
                parents = tuple(p for p in parents if p != NULL_REVISION
 
396
                    and revision_root.get(p, root_id) == root_id)
 
397
                result = versionedfile.add_lines_with_ghosts(
 
398
                    revision_id, parents, [], parent_texts)
 
399
                parent_texts[revision_id] = result[2]
359
400
 
360
401
    def regenerate_inventory(self, revs):
361
402
        """Generate a new inventory versionedfile in target, convertin data.
369
410
            self.target.add_inventory(tree.get_revision_id(), tree.inventory,
370
411
                                      parents)
371
412
 
 
413
    def fetch_revisions(self, revision_ids):
 
414
        for revision in self.source.get_revisions(revision_ids):
 
415
            self.target.add_revision(revision.revision_id, revision)
 
416
 
372
417
 
373
418
class Model1toKnit2Fetcher(GenericRepoFetcher):
374
419
    """Fetch from a Model1 repository into a Knit2 repository
384
429
 
385
430
    def _fetch_inventory_weave(self, revs, pb):
386
431
        self.helper.regenerate_inventory(revs)
387
 
 
 
432
 
 
433
    def _copy_revision(self, rev, to_txn):
 
434
        self.helper.fetch_revisions([rev])
 
435
 
388
436
 
389
437
class Knit1to2Fetcher(KnitRepoFetcher):
390
438
    """Fetch from a Knit1 repository into a Knit2 repository"""
401
449
    def _fetch_inventory_weave(self, revs, pb):
402
450
        self.helper.regenerate_inventory(revs)
403
451
 
 
452
    def _fetch_just_revision_texts(self, version_ids, from_transaction,
 
453
                                   to_transaction):
 
454
        self.helper.fetch_revisions(version_ids)
 
455
 
404
456
 
405
457
class RemoteToOtherFetcher(GenericRepoFetcher):
406
458