/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

  • Committer: Robert Collins
  • Date: 2006-03-03 02:09:49 UTC
  • mto: (1594.2.4 integration)
  • mto: This revision was merged to the branch mainline in revision 1596.
  • Revision ID: robertc@robertcollins.net-20060303020949-0ddc6f33d0a43943
Smoke test for RevisionStore factories creating revision stores.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
 
1
# Copyright (C) 2005 by 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
26
26
add a revision to the store until everything it refers to is also
27
27
stored, so that if a revision is present we can totally recreate it.
28
28
However, we can't know what files are included in a revision until we
29
 
read its inventory.  So we query the inventory store of the source for
30
 
the ids we need, and then pull those ids and finally actually join
31
 
the inventories.
 
29
read its inventory.  Therefore, we first pull the XML and hold it in
 
30
memory until we've updated all of the files referenced.
32
31
"""
33
32
 
34
33
import bzrlib
36
35
from bzrlib.errors import (InstallFailed, NoSuchRevision,
37
36
                           MissingText)
38
37
from bzrlib.trace import mutter
39
 
from bzrlib.progress import ProgressBar, ProgressPhase
40
 
from bzrlib.reconcile import RepoReconciler
 
38
from bzrlib.progress import ProgressBar
41
39
from bzrlib.revision import NULL_REVISION
42
40
from bzrlib.symbol_versioning import *
43
41
 
95
93
        # must not mutate self._last_revision as its potentially a shared instance
96
94
        self._last_revision = last_revision
97
95
        if pb is None:
98
 
            self.pb = bzrlib.ui.ui_factory.nested_progress_bar()
99
 
            self.nested_pb = self.pb
 
96
            self.pb = bzrlib.ui.ui_factory.progress_bar()
100
97
        else:
101
98
            self.pb = pb
102
 
            self.nested_pb = None
103
99
        self.from_repository.lock_read()
104
100
        try:
105
101
            self.to_repository.lock_write()
106
102
            try:
107
103
                self.__fetch()
108
104
            finally:
109
 
                if self.nested_pb is not None:
110
 
                    self.nested_pb.finished()
111
105
                self.to_repository.unlock()
112
106
        finally:
113
107
            self.from_repository.unlock()
124
118
        self.from_control = self.from_repository.control_weaves
125
119
        self.count_total = 0
126
120
        self.file_ids_names = {}
127
 
        pp = ProgressPhase('fetch phase', 4, self.pb)
128
121
        try:
129
122
            revs = self._revids_to_fetch()
130
 
            # something to do ?
131
 
            if revs:
132
 
                pp.next_phase()
 
123
            # nothing to do
 
124
            if revs: 
133
125
                self._fetch_weave_texts(revs)
134
 
                pp.next_phase()
135
126
                self._fetch_inventory_weave(revs)
136
 
                pp.next_phase()
137
127
                self._fetch_revision_texts(revs)
138
128
                self.count_copied += len(revs)
139
129
        finally:
140
130
            self.pb.clear()
141
131
 
142
132
    def _revids_to_fetch(self):
 
133
        self.pb.update('get destination history')
143
134
        mutter('fetch up to rev {%s}', self._last_revision)
144
135
        if self._last_revision is NULL_REVISION:
145
136
            # explicit limit of no revisions needed
154
145
        except errors.NoSuchRevision:
155
146
            raise InstallFailed([self._last_revision])
156
147
 
 
148
    def _fetch_revision_texts(self, revs):
 
149
        self.to_repository.revision_store.copy_multi(
 
150
            self.from_repository.revision_store,
 
151
            revs,
 
152
            pb=self.pb)
 
153
 
157
154
    def _fetch_weave_texts(self, revs):
158
 
        texts_pb = bzrlib.ui.ui_factory.nested_progress_bar()
159
 
        try:
160
 
            file_ids = self.from_repository.fileid_involved_by_set(revs)
161
 
            count = 0
162
 
            num_file_ids = len(file_ids)
163
 
            for file_id in file_ids:
164
 
                texts_pb.update("fetch texts", count, num_file_ids)
165
 
                count +=1
166
 
                try:
167
 
                    to_weave = self.to_weaves.get_weave(file_id,
168
 
                        self.to_repository.get_transaction())
169
 
                except errors.NoSuchFile:
170
 
                    # destination is empty, just copy it.
171
 
                    # this copies all the texts, which is useful and 
172
 
                    # on per-file basis quite cheap.
173
 
                    self.to_weaves.copy_multi(
174
 
                        self.from_weaves,
175
 
                        [file_id],
176
 
                        None,
177
 
                        self.from_repository.get_transaction(),
178
 
                        self.to_repository.get_transaction())
179
 
                else:
180
 
                    # destination has contents, must merge
181
 
                    from_weave = self.from_weaves.get_weave(file_id,
182
 
                        self.from_repository.get_transaction())
183
 
                    # we fetch all the texts, because texts do
184
 
                    # not reference anything, and its cheap enough
185
 
                    to_weave.join(from_weave)
186
 
        finally:
187
 
            texts_pb.finished()
 
155
        file_ids = self.from_repository.fileid_involved_by_set(revs)
 
156
        count = 0
 
157
        num_file_ids = len(file_ids)
 
158
        for file_id in file_ids:
 
159
            self.pb.update("merge weaves", count, num_file_ids)
 
160
            count +=1
 
161
            to_weave = self.to_weaves.get_weave_or_empty(file_id,
 
162
                self.to_repository.get_transaction())
 
163
 
 
164
            if to_weave.num_versions() > 0:
 
165
                # destination has contents, must merge
 
166
                from_weave = self.from_weaves.get_weave(file_id,
 
167
                    self.from_repository.get_transaction())
 
168
                to_weave.join(from_weave)
 
169
            else:
 
170
                # destination is empty, just replace it
 
171
                self.to_weaves.copy_multi(self.from_weaves, [file_id], self.pb,
 
172
                                          self.from_repository.get_transaction())
 
173
        self.pb.clear()
188
174
 
189
175
    def _fetch_inventory_weave(self, revs):
190
 
        pb = bzrlib.ui.ui_factory.nested_progress_bar()
191
 
        try:
192
 
            pb.update("fetch inventory", 0, 2)
193
 
            to_weave = self.to_control.get_weave('inventory',
194
 
                    self.to_repository.get_transaction())
195
 
    
196
 
            child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
197
 
            try:
198
 
                # just merge, this is optimisable and its means we dont
199
 
                # copy unreferenced data such as not-needed inventories.
200
 
                pb.update("fetch inventory", 1, 3)
201
 
                from_weave = self.from_repository.get_inventory_weave()
202
 
                pb.update("fetch inventory", 2, 3)
203
 
                # we fetch only the referenced inventories because we do not
204
 
                # know for unselected inventories whether all their required
205
 
                # texts are present in the other repository - it could be
206
 
                # corrupt.
207
 
                to_weave.join(from_weave, pb=child_pb, msg='merge inventory',
208
 
                              version_ids=revs)
209
 
            finally:
210
 
                child_pb.finished()
211
 
        finally:
212
 
            pb.finished()
213
 
 
214
 
 
215
 
class GenericRepoFetcher(RepoFetcher):
216
 
    """This is a generic repo to repo fetcher.
217
 
 
218
 
    This makes minimal assumptions about repo layout and contents.
219
 
    It triggers a reconciliation after fetching to ensure integrity.
220
 
    """
221
 
 
222
 
    def _fetch_revision_texts(self, revs):
223
 
        """Fetch revision object texts"""
224
 
        rev_pb = bzrlib.ui.ui_factory.nested_progress_bar()
225
 
        try:
226
 
            to_txn = self.to_transaction = self.to_repository.get_transaction()
227
 
            count = 0
228
 
            total = len(revs)
229
 
            to_store = self.to_repository._revision_store
230
 
            for rev in revs:
231
 
                pb = bzrlib.ui.ui_factory.nested_progress_bar()
232
 
                try:
233
 
                    pb.update('copying revisions', count, total)
234
 
                    try:
235
 
                        sig_text = self.from_repository.get_signature_text(rev)
236
 
                        to_store.add_revision_signature_text(rev, sig_text, to_txn)
237
 
                    except errors.NoSuchRevision:
238
 
                        # not signed.
239
 
                        pass
240
 
                    to_store.add_revision(self.from_repository.get_revision(rev),
241
 
                                          to_txn)
242
 
                    count += 1
243
 
                finally:
244
 
                    pb.finished()
245
 
            # fixup inventory if needed: 
246
 
            # this is expensive because we have no inverse index to current ghosts.
247
 
            # but on local disk its a few seconds and sftp push is already insane.
248
 
            # so we just-do-it.
249
 
            # FIXME: repository should inform if this is needed.
250
 
            self.to_repository.reconcile()
251
 
        finally:
252
 
            rev_pb.finished()
253
 
    
254
 
 
255
 
class KnitRepoFetcher(RepoFetcher):
256
 
    """This is a knit format repository specific fetcher.
257
 
 
258
 
    This differs from the GenericRepoFetcher by not doing a 
259
 
    reconciliation after copying, and using knit joining to
260
 
    copy revision texts.
261
 
    """
262
 
 
263
 
    def _fetch_revision_texts(self, revs):
264
 
        # may need to be a InterRevisionStore call here.
265
 
        from_transaction = self.from_repository.get_transaction()
266
 
        to_transaction = self.to_repository.get_transaction()
267
 
        to_sf = self.to_repository._revision_store.get_signature_file(
268
 
            to_transaction)
269
 
        from_sf = self.from_repository._revision_store.get_signature_file(
270
 
            from_transaction)
271
 
        to_sf.join(from_sf, version_ids=revs, ignore_missing=True)
272
 
        to_rf = self.to_repository._revision_store.get_revision_file(
273
 
            to_transaction)
274
 
        from_rf = self.from_repository._revision_store.get_revision_file(
275
 
            from_transaction)
276
 
        to_rf.join(from_rf, version_ids=revs)
 
176
        self.pb.update("inventory fetch", 0, 2)
 
177
        to_weave = self.to_control.get_weave('inventory',
 
178
                self.to_repository.get_transaction())
 
179
 
 
180
        if to_weave.num_versions() > 0:
 
181
            # destination has contents, must merge
 
182
            self.pb.update("inventory fetch", 1, 2)
 
183
            from_weave = self.from_repository.get_inventory_weave()
 
184
            self.pb.update("inventory fetch", 2, 2)
 
185
            to_weave.join(from_weave, pb=self.pb, msg='merge inventory')
 
186
        else:
 
187
            # destination is empty, just replace it
 
188
            self.to_control.copy_multi(self.from_control,
 
189
                                       ['inventory'],
 
190
                                       self.pb,
 
191
                                       self.from_repository.get_transaction())
 
192
 
 
193
        self.pb.clear()
277
194
 
278
195
 
279
196
class Fetcher(object):