~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/fetch.py

Merged bzr.dev and updated NEWS with a better description of changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
35
35
import bzrlib.errors as errors
36
36
from bzrlib.errors import (InstallFailed,
37
37
                           )
38
 
from bzrlib.trace import mutter
39
38
from bzrlib.progress import ProgressPhase
40
39
from bzrlib.revision import NULL_REVISION
41
40
from bzrlib.symbol_versioning import (deprecated_function,
42
41
        deprecated_method,
43
42
        zero_eight,
44
43
        )
 
44
from bzrlib.trace import mutter
 
45
import bzrlib.ui
45
46
 
 
47
from bzrlib.lazy_import import lazy_import
46
48
 
47
49
# TODO: Avoid repeatedly opening weaves so many times.
48
50
 
90
92
        if to_repository.control_files._transport.base == from_repository.control_files._transport.base:
91
93
            # check that last_revision is in 'from' and then return a no-operation.
92
94
            if last_revision not in (None, NULL_REVISION):
93
 
                from_repository.get_revision(last_revision)
 
95
                to_repository.get_revision(last_revision)
94
96
            return
95
97
        self.to_repository = to_repository
96
98
        self.from_repository = from_repository
106
108
        try:
107
109
            self.to_repository.lock_write()
108
110
            try:
109
 
                self.__fetch()
 
111
                self.to_repository.start_write_group()
 
112
                try:
 
113
                    self.__fetch()
 
114
                except:
 
115
                    self.to_repository.abort_write_group()
 
116
                    raise
 
117
                else:
 
118
                    self.to_repository.commit_write_group()
110
119
            finally:
111
120
                if self.nested_pb is not None:
112
121
                    self.nested_pb.finished()
147
156
        if self._last_revision is NULL_REVISION:
148
157
            # explicit limit of no revisions needed
149
158
            return None
150
 
        if (self._last_revision != None and
 
159
        if (self._last_revision is not None and
151
160
            self.to_repository.has_revision(self._last_revision)):
152
161
            return None
153
162
            
281
290
        to_rf.join(from_rf, version_ids=revs)
282
291
 
283
292
 
 
293
class Inter1and2Helper(object):
 
294
    """Helper for operations that convert data from model 1 and 2
 
295
    
 
296
    This is for use by fetchers and converters.
 
297
    """
 
298
 
 
299
    def __init__(self, source, target):
 
300
        """Constructor.
 
301
 
 
302
        :param source: The repository data comes from
 
303
        :param target: The repository data goes to
 
304
        """
 
305
        self.source = source
 
306
        self.target = target
 
307
 
 
308
    def iter_rev_trees(self, revs):
 
309
        """Iterate through RevisionTrees efficiently.
 
310
 
 
311
        Additionally, the inventory's revision_id is set if unset.
 
312
 
 
313
        Trees are retrieved in batches of 100, and then yielded in the order
 
314
        they were requested.
 
315
 
 
316
        :param revs: A list of revision ids
 
317
        """
 
318
        while revs:
 
319
            for tree in self.source.revision_trees(revs[:100]):
 
320
                if tree.inventory.revision_id is None:
 
321
                    tree.inventory.revision_id = tree.get_revision_id()
 
322
                yield tree
 
323
            revs = revs[100:]
 
324
 
 
325
    def generate_root_texts(self, revs):
 
326
        """Generate VersionedFiles for all root ids.
 
327
        
 
328
        :param revs: the revisions to include
 
329
        """
 
330
        inventory_weave = self.source.get_inventory_weave()
 
331
        parent_texts = {}
 
332
        versionedfile = {}
 
333
        to_store = self.target.weave_store
 
334
        for tree in self.iter_rev_trees(revs):
 
335
            revision_id = tree.inventory.root.revision
 
336
            root_id = tree.inventory.root.file_id
 
337
            parents = inventory_weave.get_parents(revision_id)
 
338
            if root_id not in versionedfile:
 
339
                versionedfile[root_id] = to_store.get_weave_or_empty(root_id, 
 
340
                    self.target.get_transaction())
 
341
            parent_texts[root_id] = versionedfile[root_id].add_lines(
 
342
                revision_id, parents, [], parent_texts)
 
343
 
 
344
    def regenerate_inventory(self, revs):
 
345
        """Generate a new inventory versionedfile in target, convertin data.
 
346
        
 
347
        The inventory is retrieved from the source, (deserializing it), and
 
348
        stored in the target (reserializing it in a different format).
 
349
        :param revs: The revisions to include
 
350
        """
 
351
        inventory_weave = self.source.get_inventory_weave()
 
352
        for tree in self.iter_rev_trees(revs):
 
353
            parents = inventory_weave.get_parents(tree.get_revision_id())
 
354
            self.target.add_inventory(tree.get_revision_id(), tree.inventory,
 
355
                                      parents)
 
356
 
 
357
 
 
358
class Model1toKnit2Fetcher(GenericRepoFetcher):
 
359
    """Fetch from a Model1 repository into a Knit2 repository
 
360
    """
 
361
    def __init__(self, to_repository, from_repository, last_revision=None, 
 
362
                 pb=None):
 
363
        self.helper = Inter1and2Helper(from_repository, to_repository)
 
364
        GenericRepoFetcher.__init__(self, to_repository, from_repository,
 
365
                                    last_revision, pb)
 
366
 
 
367
    def _fetch_weave_texts(self, revs):
 
368
        GenericRepoFetcher._fetch_weave_texts(self, revs)
 
369
        # Now generate a weave for the tree root
 
370
        self.helper.generate_root_texts(revs)
 
371
 
 
372
    def _fetch_inventory_weave(self, revs):
 
373
        self.helper.regenerate_inventory(revs)
 
374
 
 
375
 
 
376
class Knit1to2Fetcher(KnitRepoFetcher):
 
377
    """Fetch from a Knit1 repository into a Knit2 repository"""
 
378
 
 
379
    def __init__(self, to_repository, from_repository, last_revision=None, 
 
380
                 pb=None):
 
381
        self.helper = Inter1and2Helper(from_repository, to_repository)
 
382
        KnitRepoFetcher.__init__(self, to_repository, from_repository,
 
383
                                 last_revision, pb)
 
384
 
 
385
    def _fetch_weave_texts(self, revs):
 
386
        KnitRepoFetcher._fetch_weave_texts(self, revs)
 
387
        # Now generate a weave for the tree root
 
388
        self.helper.generate_root_texts(revs)
 
389
 
 
390
    def _fetch_inventory_weave(self, revs):
 
391
        self.helper.regenerate_inventory(revs)
 
392
        
 
393
 
284
394
class Fetcher(object):
285
395
    """Backwards compatibility glue for branch.fetch()."""
286
396