71
# TODO: Don't create a progress bar here, have it passed by the caller.
72
# At least do it from the UI factory.
88
from bzrlib.branch import Branch, find_branch, BZR_BRANCH_FORMAT_5
89
from bzrlib.revfile import Revfile
74
from bzrlib.branch import Branch, find_branch
75
from bzrlib.branch import BZR_BRANCH_FORMAT_5, BZR_BRANCH_FORMAT_6
76
import bzrlib.hashcache as hashcache
90
77
from bzrlib.weave import Weave
91
78
from bzrlib.weavefile import read_weave, write_weave
92
79
from bzrlib.ui import ui_factory
93
80
from bzrlib.atomicfile import AtomicFile
94
81
from bzrlib.xml4 import serializer_v4
95
82
from bzrlib.xml5 import serializer_v5
96
from bzrlib.trace import mutter, note, warning, enable_default_logging
97
from bzrlib.osutils import sha_strings, sha_string
83
from bzrlib.trace import mutter, note, warning
84
from bzrlib.osutils import sha_strings, sha_string, pathjoin, abspath
100
87
class Convert(object):
113
100
note('starting upgrade of %s', os.path.abspath(self.base))
114
101
self._backup_control_dir()
115
note('starting upgrade')
102
self.pb = ui_factory.progress_bar()
103
if self.old_format == 4:
104
note('starting upgrade from format 4 to 5')
105
self._convert_to_weaves()
107
if self.old_format == 5:
108
note('starting upgrade from format 5 to 6')
109
self._convert_to_prefixed()
111
cache = hashcache.HashCache(abspath(self.base))
117
def _convert_to_prefixed(self):
118
from bzrlib.store import hash_prefix
119
for store_name in ["weaves", "revision-store"]:
120
note("adding prefixes to %s" % store_name)
121
store_dir = pathjoin(self.base, ".bzr", store_name)
122
for filename in os.listdir(store_dir):
123
if filename.endswith(".weave") or filename.endswith(".gz"):
124
file_id = os.path.splitext(filename)[0]
127
prefix_dir = pathjoin(store_dir, hash_prefix(file_id))
128
if not os.path.isdir(prefix_dir):
130
os.rename(pathjoin(store_dir, filename),
131
pathjoin(prefix_dir, filename))
132
self._set_new_format(BZR_BRANCH_FORMAT_6)
135
def _convert_to_weaves(self):
116
136
note('note: upgrade may be faster if all store files are ungzipped first')
117
self.pb = ui_factory.progress_bar()
118
137
if not os.path.isdir(self.base + '/.bzr/weaves'):
119
138
os.mkdir(self.base + '/.bzr/weaves')
120
139
self.inv_weave = Weave('inventory')
126
145
# to_read is a stack holding the revisions we still need to process;
127
146
# appending to it adds new highest-priority revisions
128
147
self.known_revisions = set(rev_history)
129
self.to_read = [rev_history[-1]]
148
self.to_read = rev_history[-1:]
130
149
while self.to_read:
131
150
rev_id = self.to_read.pop()
132
151
if (rev_id not in self.revisions
144
163
note(' %6d texts' % self.text_count)
145
164
self._write_all_weaves()
146
165
self._write_all_revs()
147
self._set_new_format()
148
166
self._cleanup_spare_files()
167
self._set_new_format(BZR_BRANCH_FORMAT_5)
151
170
def _open_branch(self):
152
171
self.branch = Branch.open_downlevel(self.base)
153
if self.branch._branch_format == 5:
154
note('this branch is already in the most current format')
172
self.old_format = self.branch._branch_format
173
if self.old_format == 6:
174
note('this branch is in the most current format')
156
if self.branch._branch_format != 4:
176
if self.old_format not in (4, 5):
157
177
raise BzrError("cannot upgrade from branch format %r" %
158
178
self.branch._branch_format)
162
def _set_new_format(self):
163
self.branch.put_controlfile('branch-format', BZR_BRANCH_FORMAT_5)
182
def _set_new_format(self, format):
183
self.branch.put_controlfile('branch-format', format)
166
186
def _cleanup_spare_files(self):
228
248
self.pb.update('loading revision',
229
249
len(self.revisions),
230
250
len(self.known_revisions))
231
if rev_id not in self.branch.revision_store:
251
if not self.branch.revision_store.has_id(rev_id):
233
253
note('revision {%s} not present in branch; '
234
254
'will be converted as a ghost',
236
256
self.absent_revisions.add(rev_id)
238
rev_xml = self.branch.revision_store[rev_id].read()
258
rev_xml = self.branch.revision_store.get(rev_id).read()
239
259
rev = serializer_v4.read_revision_from_string(rev_xml)
240
260
for parent_id in rev.parent_ids:
241
261
self.known_revisions.add(parent_id)
246
266
def _load_old_inventory(self, rev_id):
247
267
assert rev_id not in self.converted_revs
248
old_inv_xml = self.branch.inventory_store[rev_id].read()
268
old_inv_xml = self.branch.inventory_store.get(rev_id).read()
249
269
inv = serializer_v4.read_inventory_from_string(old_inv_xml)
250
270
rev = self.revisions[rev_id]
251
271
if rev.inventory_sha1:
341
361
parent_indexes = map(w.lookup, previous_revisions)
342
362
if ie.has_text():
343
file_lines = self.branch.text_store[ie.text_id].readlines()
363
file_lines = self.branch.text_store.get(ie.text_id).readlines()
344
364
assert sha_strings(file_lines) == ie.text_sha1
345
365
assert sum(map(len, file_lines)) == ie.text_size
346
366
w.add(rev_id, parent_indexes, file_lines, ie.text_sha1)