~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/fetch.py

Merge in InterRepository api to have it available.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
from copy import copy
18
 
import os
19
 
from cStringIO import StringIO
20
 
 
21
 
import bzrlib
22
 
import bzrlib.errors as errors
23
 
from bzrlib.errors import (InstallFailed, NoSuchRevision, WeaveError,
24
 
                           MissingText)
25
 
from bzrlib.trace import mutter, note, warning
26
 
from bzrlib.branch import Branch
27
 
from bzrlib.progress import ProgressBar
28
 
from bzrlib.revision import NULL_REVISION
29
 
from bzrlib.xml5 import serializer_v5
30
 
from bzrlib.osutils import sha_string, split_lines
31
17
 
32
18
"""Copying of history from one branch to another.
33
19
 
44
30
memory until we've updated all of the files referenced.
45
31
"""
46
32
 
 
33
import bzrlib
 
34
import bzrlib.errors as errors
 
35
from bzrlib.errors import (InstallFailed, NoSuchRevision, WeaveError,
 
36
                           MissingText)
 
37
from bzrlib.trace import mutter
 
38
from bzrlib.progress import ProgressBar
 
39
from bzrlib.revision import NULL_REVISION
 
40
from bzrlib.symbol_versioning import *
 
41
 
 
42
 
47
43
# TODO: Avoid repeatedly opening weaves so many times.
48
44
 
49
45
# XXX: This doesn't handle ghost (not present in branch) revisions at
62
58
#   and add in all file versions
63
59
 
64
60
 
65
 
 
 
61
@deprecated_function(zero_eight)
66
62
def greedy_fetch(to_branch, from_branch, revision=None, pb=None):
 
63
    """Legacy API, please see branch.fetch(from_branch, last_revision, pb)."""
67
64
    f = Fetcher(to_branch, from_branch, revision, pb)
68
65
    return f.count_copied, f.failed_revisions
69
66
 
 
67
fetch = greedy_fetch
 
68
 
70
69
 
71
70
class RepoFetcher(object):
72
71
    """Pull revisions and texts from one repository to another.
76
75
 
77
76
    after running:
78
77
    count_copied -- number of revisions copied
79
 
    count_weaves -- number of file weaves copied
 
78
 
 
79
    This should not be used directory, its essential a object to encapsulate
 
80
    the logic in InterRepository.fetch().
80
81
    """
81
82
    def __init__(self, to_repository, from_repository, last_revision=None, pb=None):
 
83
        # result variables.
 
84
        self.failed_revisions = []
 
85
        self.count_copied = 0
82
86
        if to_repository.bzrdir.transport.base == from_repository.bzrdir.transport.base:
83
87
            # check that last_revision is in 'from' and then return a no-operation.
84
88
            if last_revision not in (None, NULL_REVISION):
112
116
        self.to_control = self.to_repository.control_weaves
113
117
        self.from_weaves = self.from_repository.weave_store
114
118
        self.from_control = self.from_repository.control_weaves
115
 
        self.failed_revisions = []
116
 
        self.count_copied = 0
117
119
        self.count_total = 0
118
 
        self.count_weaves = 0
119
 
        self.copied_file_ids = set()
120
120
        self.file_ids_names = {}
121
121
        try:
122
122
            revs = self._revids_to_fetch()
130
130
            self.pb.clear()
131
131
 
132
132
    def _revids_to_fetch(self):
 
133
        self.pb.update('get destination history')
133
134
        mutter('fetch up to rev {%s}', self._last_revision)
134
135
        if self._last_revision is NULL_REVISION:
135
136
            # explicit limit of no revisions needed
202
203
 
203
204
 
204
205
class Fetcher(object):
205
 
    """Pull revisions and texts from one branch to another.
206
 
 
207
 
    This doesn't update the destination's history; that can be done
208
 
    separately if desired.  
209
 
 
210
 
    revision_limit
211
 
        If set, pull only up to this revision_id.
212
 
 
213
 
    After running:
214
 
 
215
 
    last_revision -- if last_revision
216
 
        is given it will be that, otherwise the last revision of
217
 
        from_branch
218
 
 
219
 
    count_copied -- number of revisions copied
220
 
 
221
 
    count_weaves -- number of file weaves copied
222
 
    """
 
206
    """Backwards compatability glue for branch.fetch()."""
 
207
 
 
208
    @deprecated_method(zero_eight)
223
209
    def __init__(self, to_branch, from_branch, last_revision=None, pb=None):
224
 
        if to_branch.base == from_branch.base:
225
 
            raise Exception("can't fetch from a branch to itself %s, %s" % 
226
 
                            (from_branch.base, to_branch.base))
227
 
        
228
 
        self.to_branch = to_branch
229
 
        self.from_branch = from_branch
230
 
        self._last_revision = last_revision
231
 
        if pb is None:
232
 
            self.pb = bzrlib.ui.ui_factory.progress_bar()
233
 
        else:
234
 
            self.pb = pb
235
 
        self.from_branch.lock_read()
236
 
        try:
237
 
            self.to_branch.lock_write()
238
 
            try:
239
 
                self.__fetch()
240
 
            finally:
241
 
                self.to_branch.unlock()
242
 
        finally:
243
 
            self.from_branch.unlock()
244
 
 
245
 
    def __fetch(self):
246
 
        self._find_last_revision()
247
 
        repo_fetcher = RepoFetcher(to_repository=self.to_branch.repository,
248
 
                                   from_repository=self.from_branch.repository,
249
 
                                   pb=self.pb,
250
 
                                   last_revision=self._last_revision)
251
 
        self.failed_revisions = repo_fetcher.failed_revisions
252
 
        self.count_copied = repo_fetcher.count_copied
253
 
        self.count_total = repo_fetcher.count_total
254
 
        self.count_weaves = repo_fetcher.count_weaves
255
 
        self.copied_file_ids = repo_fetcher.copied_file_ids
256
 
 
257
 
    def _find_last_revision(self):
258
 
        """Find the limiting source revision.
259
 
 
260
 
        Every ancestor of that revision will be merged across.
261
 
 
262
 
        Returns the revision_id, or returns None if there's no history
263
 
        in the source branch."""
264
 
        if self._last_revision:
265
 
            return
266
 
        self.pb.update('get source history')
267
 
        from_history = self.from_branch.revision_history()
268
 
        self.pb.update('get destination history')
269
 
        if from_history:
270
 
            self._last_revision = from_history[-1]
271
 
        else:
272
 
            # no history in the source branch
273
 
            self._last_revision = NULL_REVISION
274
 
 
275
 
fetch = Fetcher
 
210
        """Please see branch.fetch()."""
 
211
        to_branch.fetch(from_branch, last_revision, pb)