~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/upgrade.py

  • Committer: Martin Pool
  • Date: 2005-09-22 13:32:02 UTC
  • Revision ID: mbp@sourcefrog.net-20050922133202-347cfd35d2941dd5
- simple weave-based annotate code (not complete)

Show diffs side-by-side

added added

removed removed

Lines of Context:
78
78
 
79
79
import os
80
80
import tempfile
 
81
import hotshot, hotshot.stats
81
82
import sys
82
83
import logging
83
84
import shutil
102
103
        self.absent_revisions = set()
103
104
        self.text_count = 0
104
105
        self.revisions = {}
 
106
        self.inventories = {}
105
107
        self.convert()
106
108
 
107
109
 
108
110
    def convert(self):
109
111
        if not self._open_branch():
110
112
            return
111
 
        note('starting upgrade of %s', os.path.abspath(self.base))
 
113
        note('starting upgrade of %s', self.base)
112
114
        self._backup_control_dir()
113
115
        note('starting upgrade')
114
116
        note('note: upgrade may be faster if all store files are ungzipped first')
149
151
 
150
152
 
151
153
    def _open_branch(self):
152
 
        self.branch = Branch.open_downlevel(self.base)
 
154
        self.branch = Branch(self.base, relax_version_check=True)
153
155
        if self.branch._branch_format == 5:
154
156
            note('this branch is already in the most current format')
155
157
            return False
181
183
    def _backup_control_dir(self):
182
184
        orig = self.base + '/.bzr'
183
185
        backup = orig + '.backup'
184
 
        note('making backup of tree history')
185
186
        shutil.copytree(orig, backup)
186
187
        note('%s has been backed up to %s', orig, backup)
187
188
        note('if conversion fails, you can move this directory back to .bzr')
245
246
                self.known_revisions.add(parent_id)
246
247
                self.to_read.append(parent_id)
247
248
            self.revisions[rev_id] = rev
248
 
 
249
 
 
250
 
    def _load_old_inventory(self, rev_id):
251
 
        assert rev_id not in self.converted_revs
252
 
        old_inv_xml = self.branch.inventory_store[rev_id].read()
253
 
        inv = serializer_v4.read_inventory_from_string(old_inv_xml)
254
 
        rev = self.revisions[rev_id]
255
 
        if rev.inventory_sha1:
256
 
            assert rev.inventory_sha1 == sha_string(old_inv_xml), \
257
 
                'inventory sha mismatch for {%s}' % rev_id
258
 
        return inv
 
249
            old_inv_xml = self.branch.inventory_store[rev_id].read()
 
250
            inv = serializer_v4.read_inventory_from_string(old_inv_xml)
 
251
            assert rev.inventory_sha1 == sha_string(old_inv_xml)
 
252
            self.inventories[rev_id] = inv
259
253
        
260
254
 
261
 
    def _load_updated_inventory(self, rev_id):
262
 
        assert rev_id in self.converted_revs
263
 
        inv_xml = self.inv_weave.get_text(rev_id)
264
 
        inv = serializer_v5.read_inventory_from_string(inv_xml)
265
 
        return inv
266
 
 
267
 
 
268
255
    def _convert_one_rev(self, rev_id):
269
256
        """Convert revision and all referenced objects to new format."""
270
257
        rev = self.revisions[rev_id]
271
 
        inv = self._load_old_inventory(rev_id)
 
258
        inv = self.inventories[rev_id]
272
259
        for parent_id in rev.parent_ids[:]:
273
260
            if parent_id in self.absent_revisions:
274
261
                rev.parent_ids.remove(parent_id)
275
262
                self.pb.clear()
276
263
                note('remove {%s} as parent of {%s}', parent_id, rev_id)
277
264
        self._convert_revision_contents(rev, inv)
278
 
        self._store_new_weave(rev, inv)
279
 
        self._make_rev_ancestry(rev)
280
 
        self.converted_revs.add(rev_id)
281
 
 
282
 
 
283
 
    def _store_new_weave(self, rev, inv):
284
265
        # the XML is now updated with text versions
285
 
        if __debug__:
286
 
            for file_id in inv:
287
 
                ie = inv[file_id]
288
 
                if ie.kind == 'root_directory':
289
 
                    continue
290
 
                assert hasattr(ie, 'name_version'), \
291
 
                    'no name_version on {%s} in {%s}' % \
292
 
                    (file_id, rev.revision_id)
293
 
                if ie.kind == 'file':
294
 
                    assert hasattr(ie, 'text_version')
295
 
 
296
266
        new_inv_xml = serializer_v5.write_inventory_to_string(inv)
297
267
        new_inv_sha1 = sha_string(new_inv_xml)
298
 
        self.inv_weave.add(rev.revision_id, rev.parent_ids,
 
268
        self.inv_weave.add(rev_id, rev.parent_ids,
299
269
                           new_inv_xml.splitlines(True),
300
270
                           new_inv_sha1)
 
271
        # TODO: Upgrade revision XML and write that out
301
272
        rev.inventory_sha1 = new_inv_sha1
 
273
        self._make_rev_ancestry(rev)
 
274
        self.converted_revs.add(rev_id)
302
275
 
303
276
 
304
277
    def _make_rev_ancestry(self, rev):
325
298
        rev_id = rev.revision_id
326
299
        mutter('converting texts of revision {%s}',
327
300
               rev_id)
328
 
        parent_invs = map(self._load_updated_inventory, rev.parent_ids)
329
301
        for file_id in inv:
330
302
            ie = inv[file_id]
331
 
            self._set_name_version(rev, ie, parent_invs)
 
303
            self._set_name_version(rev, ie)
332
304
            if ie.kind != 'file':
333
305
                continue
334
 
            self._convert_file_version(rev, ie, parent_invs)
335
 
 
336
 
 
337
 
    def _set_name_version(self, rev, ie, parent_invs):
 
306
            self._convert_file_version(rev, ie)
 
307
 
 
308
 
 
309
    def _set_name_version(self, rev, ie):
338
310
        """Set name version for a file.
339
311
 
340
312
        Done in a slightly lazy way: if the file is renamed or in a merge revision
341
313
        it gets a new version, otherwise the same as before.
342
314
        """
343
315
        file_id = ie.file_id
344
 
        if ie.kind == 'root_directory':
345
 
            return
346
 
        if len(parent_invs) != 1:
 
316
        if len(rev.parent_ids) != 1:
347
317
            ie.name_version = rev.revision_id
348
318
        else:
349
 
            old_inv = parent_invs[0]
 
319
            old_inv = self.inventories[rev.parent_ids[0]]
350
320
            if not old_inv.has_id(file_id):
351
321
                ie.name_version = rev.revision_id
352
322
            else:
359
329
 
360
330
 
361
331
 
362
 
    def _convert_file_version(self, rev, ie, parent_invs):
 
332
    def _convert_file_version(self, rev, ie):
363
333
        """Convert one version of one file.
364
334
 
365
335
        The file needs to be added into the weave if it is a merge
373
343
            self.text_weaves[file_id] = w
374
344
        file_parents = []
375
345
        text_changed = False
376
 
        for parent_inv in parent_invs:
 
346
        for parent_id in rev.parent_ids:
 
347
            ##if parent_id in self.absent_revisions:
 
348
            ##    continue
 
349
            assert parent_id in self.converted_revs, \
 
350
                   'parent {%s} not converted' % parent_id
 
351
            parent_inv = self.inventories[parent_id]
377
352
            if parent_inv.has_id(file_id):
378
353
                parent_ie = parent_inv[file_id]
379
354
                old_text_version = parent_ie.text_version