~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/fetch.py

  • Committer: Martin Pool
  • Date: 2008-05-02 02:31:14 UTC
  • mfrom: (3399 +trunk)
  • mto: (3408.1.1 doc)
  • mto: This revision was merged to the branch mainline in revision 3409.
  • Revision ID: mbp@sourcefrog.net-20080502023114-y2gcg3w3jc770j9m
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
158
158
        pb = bzrlib.ui.ui_factory.nested_progress_bar()
159
159
        try:
160
160
            revs = search.get_keys()
161
 
            data_to_fetch = self.from_repository.item_keys_introduced_by(revs, pb)
 
161
            graph = self.from_repository.get_graph()
 
162
            revs = list(graph.iter_topo_order(revs))
 
163
            data_to_fetch = self.from_repository.item_keys_introduced_by(revs,
 
164
                                                                         pb)
162
165
            for knit_kind, file_id, revisions in data_to_fetch:
163
166
                if knit_kind != phase:
164
167
                    phase = knit_kind
268
271
            except errors.NoSuchRevision:
269
272
                # not signed.
270
273
                pass
271
 
            to_store.add_revision(self.from_repository.get_revision(rev),
272
 
                                  to_txn)
 
274
            self._copy_revision(rev, to_txn)
273
275
            count += 1
274
276
        # fixup inventory if needed: 
275
277
        # this is expensive because we have no inverse index to current ghosts.
277
279
        # so we just-do-it.
278
280
        # FIXME: repository should inform if this is needed.
279
281
        self.to_repository.reconcile()
280
 
    
 
282
 
 
283
    def _copy_revision(self, rev, to_txn):
 
284
        to_store = self.to_repository._revision_store
 
285
        to_store.add_revision(self.from_repository.get_revision(rev), to_txn)
 
286
 
281
287
 
282
288
class KnitRepoFetcher(RepoFetcher):
283
289
    """This is a knit format repository specific fetcher.
296
302
        from_sf = self.from_repository._revision_store.get_signature_file(
297
303
            from_transaction)
298
304
        to_sf.join(from_sf, version_ids=revs, ignore_missing=True)
 
305
        self._fetch_just_revision_texts(revs, from_transaction, to_transaction)
 
306
 
 
307
    def _fetch_just_revision_texts(self, version_ids, from_transaction,
 
308
                                   to_transaction):
299
309
        to_rf = self.to_repository._revision_store.get_revision_file(
300
310
            to_transaction)
301
311
        from_rf = self.from_repository._revision_store.get_revision_file(
302
312
            from_transaction)
303
 
        to_rf.join(from_rf, version_ids=revs)
 
313
        to_rf.join(from_rf, version_ids=version_ids)
304
314
 
305
315
 
306
316
class Inter1and2Helper(object):
337
347
                yield tree
338
348
            revs = revs[100:]
339
349
 
 
350
    def _find_root_ids(self, revs, parent_map, graph):
 
351
        revision_root = {}
 
352
        planned_versions = {}
 
353
        for tree in self.iter_rev_trees(revs):
 
354
            revision_id = tree.inventory.root.revision
 
355
            root_id = tree.get_root_id()
 
356
            planned_versions.setdefault(root_id, []).append(revision_id)
 
357
            revision_root[revision_id] = root_id
 
358
        # Find out which parents we don't already know root ids for
 
359
        parents = set()
 
360
        for revision_parents in parent_map.itervalues():
 
361
            parents.update(revision_parents)
 
362
        parents.difference_update(revision_root.keys() + [NULL_REVISION])
 
363
        # Limit to revisions present in the versionedfile
 
364
        parents = graph.get_parent_map(parents).keys()
 
365
        for tree in self.iter_rev_trees(parents):
 
366
            root_id = tree.get_root_id()
 
367
            revision_root[tree.get_revision_id()] = root_id
 
368
        return revision_root, planned_versions
 
369
 
340
370
    def generate_root_texts(self, revs):
341
371
        """Generate VersionedFiles for all root ids.
342
 
        
 
372
 
343
373
        :param revs: the revisions to include
344
374
        """
345
 
        inventory_weave = self.source.get_inventory_weave()
346
 
        parent_texts = {}
347
 
        versionedfile = {}
348
375
        to_store = self.target.weave_store
349
 
        parent_map = self.source.get_graph().get_parent_map(revs)
350
 
        for tree in self.iter_rev_trees(revs):
351
 
            revision_id = tree.inventory.root.revision
352
 
            root_id = tree.get_root_id()
353
 
            parents = parent_map[revision_id]
354
 
            if parents[0] == NULL_REVISION:
355
 
                parents = ()
356
 
            if root_id not in versionedfile:
357
 
                versionedfile[root_id] = to_store.get_weave_or_empty(root_id,
358
 
                    self.target.get_transaction())
359
 
            _, _, parent_texts[root_id] = versionedfile[root_id].add_lines(
360
 
                revision_id, parents, [], parent_texts)
 
376
        graph = self.source.get_graph()
 
377
        parent_map = graph.get_parent_map(revs)
 
378
        revision_root, planned_versions = self._find_root_ids(
 
379
            revs, parent_map, graph)
 
380
        for root_id, versions in planned_versions.iteritems():
 
381
            versionedfile = to_store.get_weave_or_empty(root_id,
 
382
                self.target.get_transaction())
 
383
            parent_texts = {}
 
384
            for revision_id in versions:
 
385
                if revision_id in versionedfile:
 
386
                    continue
 
387
                parents = parent_map[revision_id]
 
388
                # We drop revision parents with different file-ids, because
 
389
                # a version cannot have a version with another file-id as its
 
390
                # parent.
 
391
                # When a parent revision is a ghost, we guess that its root id
 
392
                # was unchanged.
 
393
                parents = tuple(p for p in parents if p != NULL_REVISION
 
394
                    and revision_root.get(p, root_id) == root_id)
 
395
                result = versionedfile.add_lines_with_ghosts(
 
396
                    revision_id, parents, [], parent_texts)
 
397
                parent_texts[revision_id] = result[2]
361
398
 
362
399
    def regenerate_inventory(self, revs):
363
400
        """Generate a new inventory versionedfile in target, convertin data.
371
408
            self.target.add_inventory(tree.get_revision_id(), tree.inventory,
372
409
                                      parents)
373
410
 
 
411
    def fetch_revisions(self, revision_ids):
 
412
        for revision in self.source.get_revisions(revision_ids):
 
413
            self.target.add_revision(revision.revision_id, revision)
 
414
 
374
415
 
375
416
class Model1toKnit2Fetcher(GenericRepoFetcher):
376
417
    """Fetch from a Model1 repository into a Knit2 repository
386
427
 
387
428
    def _fetch_inventory_weave(self, revs, pb):
388
429
        self.helper.regenerate_inventory(revs)
389
 
 
 
430
 
 
431
    def _copy_revision(self, rev, to_txn):
 
432
        self.helper.fetch_revisions([rev])
 
433
 
390
434
 
391
435
class Knit1to2Fetcher(KnitRepoFetcher):
392
436
    """Fetch from a Knit1 repository into a Knit2 repository"""
403
447
    def _fetch_inventory_weave(self, revs, pb):
404
448
        self.helper.regenerate_inventory(revs)
405
449
 
 
450
    def _fetch_just_revision_texts(self, version_ids, from_transaction,
 
451
                                   to_transaction):
 
452
        self.helper.fetch_revisions(version_ids)
 
453
 
406
454
 
407
455
class RemoteToOtherFetcher(GenericRepoFetcher):
408
456