~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to tools/history2weaves.py

  • Committer: Martin Pool
  • Date: 2005-09-13 01:12:11 UTC
  • Revision ID: mbp@sourcefrog.net-20050913011211-47c8a4f18ac40dda
- fix up import
- fix creation of test directory
- shorten test directory names by removing __main__

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2008, 2009 Canonical Ltd
2
 
#
 
1
#! /usr/bin/python
 
2
 
 
3
# Copyright (C) 2005 Canonical Ltd
 
4
 
3
5
# This program is free software; you can redistribute it and/or modify
4
6
# it under the terms of the GNU General Public License as published by
5
7
# the Free Software Foundation; either version 2 of the License, or
6
8
# (at your option) any later version.
7
 
#
 
9
 
8
10
# This program is distributed in the hope that it will be useful,
9
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
13
# GNU General Public License for more details.
12
 
#
 
14
 
13
15
# You should have received a copy of the GNU General Public License
14
16
# along with this program; if not, write to the Free Software
15
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
18
 
17
 
"""bzr upgrade logic."""
18
 
 
19
 
 
20
 
from bzrlib.bzrdir import BzrDir, BzrDirFormat
21
 
import bzrlib.errors as errors
22
 
from bzrlib.remote import RemoteBzrDir
23
 
from bzrlib.transport import get_transport
24
 
import bzrlib.ui as ui
25
 
 
26
 
 
27
 
class Convert(object):
28
 
 
29
 
    def __init__(self, url, format):
30
 
        if format is None:
31
 
            format = BzrDirFormat.get_default_format()
32
 
        self.format = format
33
 
        self.bzrdir = BzrDir.open_unsupported(url)
34
 
        if isinstance(self.bzrdir, RemoteBzrDir):
35
 
            self.bzrdir._ensure_real()
36
 
            self.bzrdir = self.bzrdir._real_bzrdir
37
 
        if self.bzrdir.root_transport.is_readonly():
38
 
            raise errors.UpgradeReadonly
39
 
        self.transport = self.bzrdir.root_transport
40
 
        self.pb = ui.ui_factory.nested_progress_bar()
41
 
        try:
42
 
            self.convert()
43
 
        finally:
44
 
            self.pb.finished()
45
 
 
46
 
    def convert(self):
47
 
        try:
48
 
            branch = self.bzrdir.open_branch()
49
 
            if branch.bzrdir.root_transport.base != \
50
 
                self.bzrdir.root_transport.base:
51
 
                self.pb.note("This is a checkout. The branch (%s) needs to be "
52
 
                             "upgraded separately.",
53
 
                             branch.bzrdir.root_transport.base)
54
 
            del branch
55
 
        except (errors.NotBranchError, errors.IncompatibleRepositories):
56
 
            # might not be a format we can open without upgrading; see e.g. 
57
 
            # https://bugs.launchpad.net/bzr/+bug/253891
58
 
            pass
59
 
        if not self.bzrdir.needs_format_conversion(self.format):
60
 
            raise errors.UpToDateFormat(self.bzrdir._format)
61
 
        if not self.bzrdir.can_convert_format():
62
 
            raise errors.BzrError("cannot upgrade from bzrdir format %s" %
63
 
                           self.bzrdir._format)
64
 
        self.bzrdir.check_conversion_target(self.format)
65
 
        self.pb.note('starting upgrade of %s', self.transport.base)
66
 
        self.bzrdir.backup_bzrdir()
67
 
        while self.bzrdir.needs_format_conversion(self.format):
68
 
            converter = self.bzrdir._format.get_converter(self.format)
69
 
            self.bzrdir = converter.convert(self.bzrdir, self.pb)
70
 
        self.pb.note("finished")
71
 
 
72
 
 
73
 
def upgrade(url, format=None):
74
 
    """Upgrade to format, or the default bzrdir format if not supplied."""
75
 
    Convert(url, format)
 
19
"""Experiment in converting existing bzr branches to weaves."""
 
20
 
 
21
try:
 
22
    import psyco
 
23
    psyco.full()
 
24
except ImportError:
 
25
    pass
 
26
 
 
27
 
 
28
import logging
 
29
 
 
30
import bzrlib.branch
 
31
from bzrlib.revfile import Revfile
 
32
from bzrlib.weave import Weave
 
33
from bzrlib.weavefile import read_weave, write_weave
 
34
from bzrlib.progress import ProgressBar
 
35
from bzrlib.atomicfile import AtomicFile
 
36
import bzrlib.trace
 
37
import tempfile
 
38
import hotshot, hotshot.stats
 
39
import sys
 
40
 
 
41
def convert():
 
42
    bzrlib.trace.enable_default_logging()
 
43
 
 
44
    pb = ProgressBar()
 
45
 
 
46
    inv_weave = Weave()
 
47
 
 
48
    last_text_sha = {}
 
49
 
 
50
    # holds in-memory weaves for all files
 
51
    text_weaves = {}
 
52
 
 
53
    b = bzrlib.branch.find_branch('.')
 
54
 
 
55
    revno = 1
 
56
    rev_history = b.revision_history()
 
57
    last_idx = None
 
58
    inv_parents = []
 
59
    text_count = 0
 
60
    
 
61
    for rev_id in rev_history:
 
62
        pb.update('converting revision', revno, len(rev_history))
 
63
        
 
64
        inv_xml = b.get_inventory_xml(rev_id).readlines()
 
65
 
 
66
        new_idx = inv_weave.add(rev_id, inv_parents, inv_xml)
 
67
        inv_parents = [new_idx]
 
68
 
 
69
        tree = b.revision_tree(rev_id)
 
70
        inv = tree.inventory
 
71
 
 
72
        # for each file in the inventory, put it into its own revfile
 
73
        for file_id in inv:
 
74
            ie = inv[file_id]
 
75
            if ie.kind != 'file':
 
76
                continue
 
77
            if last_text_sha.get(file_id) == ie.text_sha1:
 
78
                # same as last time
 
79
                continue
 
80
            last_text_sha[file_id] = ie.text_sha1
 
81
 
 
82
            # new text (though possibly already stored); need to store it
 
83
            text_lines = tree.get_file(file_id).readlines()
 
84
 
 
85
            # if the file's created for the first time in this
 
86
            # revision then make a new weave; else find the old one
 
87
            if file_id not in text_weaves:
 
88
                text_weaves[file_id] = Weave()
 
89
                
 
90
            w = text_weaves[file_id]
 
91
 
 
92
            # base the new text version off whatever was last
 
93
            # (actually it'd be better to track this, to allow for
 
94
            # files that are deleted and then reappear)
 
95
            last = len(w)
 
96
            if last == 0:
 
97
                parents = []
 
98
            else:
 
99
                parents = [last-1]
 
100
 
 
101
            w.add(rev_id, parents, text_lines)
 
102
            text_count += 1
 
103
 
 
104
        revno += 1
 
105
 
 
106
    pb.clear()
 
107
    print '%6d revisions and inventories' % revno
 
108
    print '%6d texts' % text_count
 
109
 
 
110
    i = 0
 
111
    # TODO: commit them all atomically at the end, not one by one
 
112
    write_atomic_weave(inv_weave, 'weaves/inventory.weave')
 
113
    for file_id, file_weave in text_weaves.items():
 
114
        pb.update('writing weave', i, len(text_weaves))
 
115
        write_atomic_weave(file_weave, 'weaves/%s.weave' % file_id)
 
116
        i += 1
 
117
 
 
118
    pb.clear()
 
119
 
 
120
 
 
121
def write_atomic_weave(weave, filename):
 
122
    inv_wf = AtomicFile(filename)
 
123
    try:
 
124
        write_weave(weave, inv_wf)
 
125
        inv_wf.commit()
 
126
    finally:
 
127
        inv_wf.close()
 
128
 
 
129
    
 
130
 
 
131
 
 
132
def profile_convert(): 
 
133
    prof_f = tempfile.NamedTemporaryFile()
 
134
 
 
135
    prof = hotshot.Profile(prof_f.name)
 
136
 
 
137
    prof.runcall(convert) 
 
138
    prof.close()
 
139
 
 
140
    stats = hotshot.stats.load(prof_f.name)
 
141
    #stats.strip_dirs()
 
142
    stats.sort_stats('time')
 
143
    ## XXX: Might like to write to stderr or the trace file instead but
 
144
    ## print_stats seems hardcoded to stdout
 
145
    stats.print_stats(20)
 
146
            
 
147
 
 
148
if '-p' in sys.argv[1:]:
 
149
    profile_convert()
 
150
else:
 
151
    convert()
 
152