~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/fetch.py

  • Committer: Martin Pool
  • Date: 2006-01-13 08:12:22 UTC
  • mfrom: (1185.63.5 bzr.patches)
  • Revision ID: mbp@sourcefrog.net-20060113081222-6b572004a2ade0cc
[merge] test_hashcache_raise from Denys

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
17
18
import os
18
19
from cStringIO import StringIO
19
20
 
20
21
import bzrlib
21
22
import bzrlib.errors as errors
22
 
from bzrlib.errors import InstallFailed, NoSuchRevision, WeaveError
 
23
from bzrlib.errors import (InstallFailed, NoSuchRevision, WeaveError,
 
24
                           MissingText)
23
25
from bzrlib.trace import mutter, note, warning
24
26
from bzrlib.branch import Branch
25
27
from bzrlib.progress import ProgressBar
99
101
        self.count_total = 0
100
102
        self.count_weaves = 0
101
103
        self.copied_file_ids = set()
 
104
        self.file_ids_names = {}
102
105
        if pb is None:
103
106
            self.pb = bzrlib.ui.ui_factory.progress_bar()
104
107
        else:
111
114
            self.pb.clear()
112
115
 
113
116
    def _fetch_revisions(self, last_revision):
114
 
        try:
115
 
            self.last_revision = self._find_last_revision(last_revision)
116
 
        except NoSuchRevision, e:
117
 
            mutter('failed getting last revision: %s', e)
118
 
            raise InstallFailed([last_revision])
 
117
        self.last_revision = self._find_last_revision(last_revision)
119
118
        mutter('fetch up to rev {%s}', self.last_revision)
120
119
        if (self.last_revision is not None and 
121
120
            self.to_branch.has_revision(self.last_revision)):
134
133
 
135
134
        Returns the revision_id, or returns None if there's no history
136
135
        in the source branch."""
 
136
        if last_revision:
 
137
            return last_revision
137
138
        self.pb.update('get source history')
138
139
        from_history = self.from_branch.revision_history()
139
140
        self.pb.update('get destination history')
140
 
        if last_revision:
141
 
            self.from_branch.get_revision(last_revision)
142
 
            return last_revision
143
 
        elif from_history:
 
141
        if from_history:
144
142
            return from_history[-1]
145
143
        else:
146
144
            return None                 # no history in the source branch
178
176
                continue
179
177
            if self.to_branch.has_revision(rev_id):
180
178
                continue
181
 
            self.pb.update('fetch revision', i, self.count_total)
 
179
            self.pb.update('copy revision', i, self.count_total)
182
180
            self._copy_one_revision(rev_id)
183
181
            self.count_copied += 1
184
182
 
197
195
               len(rev.parent_ids))
198
196
        self._copy_new_texts(rev_id, inv)
199
197
        parents = rev.parent_ids
 
198
        new_parents = copy(parents)
200
199
        for parent in parents:
201
200
            if not self.to_branch.has_revision(parent):
202
 
                parents.pop(parents.index(parent))
203
 
        self._copy_inventory(rev_id, inv_xml, parents)
 
201
                new_parents.pop(new_parents.index(parent))
 
202
        self._copy_inventory(rev_id, inv_xml, new_parents)
204
203
        self.to_branch.revision_store.add(StringIO(rev_xml), rev_id)
205
204
        mutter('copied revision %s', rev_id)
206
205
 
207
 
 
208
206
    def _copy_inventory(self, rev_id, inv_xml, parent_ids):
209
207
        self.to_control.add_text('inventory', rev_id,
210
208
                                split_lines(inv_xml), parent_ids,
216
214
        # in memory until everything's done?  But this way is nicer
217
215
        # if it's interrupted.
218
216
        for path, ie in inv.iter_entries():
219
 
            if ie.revision != rev_id:
220
 
                continue
221
 
            mutter('%s {%s} is changed in this revision',
222
 
                   path, ie.file_id)
223
 
            self._copy_one_weave(rev_id, ie.file_id)
224
 
 
225
 
 
226
 
    def _copy_one_weave(self, rev_id, file_id):
227
 
        """Copy one file weave."""
228
 
        mutter('copy file {%s} modified in {%s}', file_id, rev_id)
229
 
        if file_id in self.copied_file_ids:
230
 
            mutter('file {%s} already copied', file_id)
 
217
            self._copy_one_weave(rev_id, ie.file_id, ie.revision)
 
218
 
 
219
    def _copy_one_weave(self, rev_id, file_id, text_revision):
 
220
        """Copy one file weave, esuring the result contains text_revision."""
 
221
        # check if the revision is already there
 
222
        if file_id in self.file_ids_names.keys( ) and \
 
223
            text_revision in self.file_ids_names[file_id]:
 
224
                return        
 
225
        to_weave = self.to_weaves.get_weave_or_empty(file_id,
 
226
            self.to_branch.get_transaction())
 
227
        if not file_id in self.file_ids_names.keys( ):
 
228
            self.file_ids_names[file_id] = to_weave.names( )
 
229
        if text_revision in to_weave:
231
230
            return
232
231
        from_weave = self.from_weaves.get_weave(file_id,
233
232
            self.from_branch.get_transaction())
234
 
        to_weave = self.to_weaves.get_weave_or_empty(file_id,
235
 
            self.to_branch.get_transaction())
236
 
        try:
237
 
            to_weave.join(from_weave)
238
 
        except errors.WeaveParentMismatch:
239
 
            to_weave.reweave(from_weave)
 
233
        if text_revision not in from_weave:
 
234
            raise MissingText(self.from_branch, text_revision, file_id)
 
235
        mutter('copy file {%s} modified in {%s}', file_id, rev_id)
 
236
 
 
237
        if to_weave.numversions() > 0:
 
238
            # destination has contents, must merge
 
239
            try:
 
240
                to_weave.join(from_weave)
 
241
            except errors.WeaveParentMismatch:
 
242
                to_weave.reweave(from_weave)
 
243
        else:
 
244
            # destination is empty, just replace it
 
245
            to_weave = from_weave.copy( )
240
246
        self.to_weaves.put_weave(file_id, to_weave,
241
247
            self.to_branch.get_transaction())
242
248
        self.count_weaves += 1
243
249
        self.copied_file_ids.add(file_id)
 
250
        self.file_ids_names[file_id] = to_weave.names()
244
251
        mutter('copied file {%s}', file_id)
245
252
 
246
253