70
66
fixed_components = True
72
68
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
73
create_prefix=False, force_new_repo=False, stacked_on=None,
74
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
69
create_prefix=False, force_new_repo=False, stacked_on=None,
70
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
76
72
"""See ControlDir.initialize_on_transport_ex."""
77
73
require_stacking = (stacked_on is not None)
78
74
# Format 5 cannot stack, but we've been asked to - actually init
80
76
if require_stacking:
81
77
format = BzrDirMetaFormat1()
82
78
return format.initialize_on_transport_ex(transport,
83
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
84
force_new_repo=force_new_repo, stacked_on=stacked_on,
85
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
86
make_working_trees=make_working_trees, shared_repo=shared_repo)
79
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
80
force_new_repo=force_new_repo, stacked_on=stacked_on,
81
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
82
make_working_trees=make_working_trees, shared_repo=shared_repo)
87
83
return BzrDirFormat.initialize_on_transport_ex(self, transport,
88
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
89
force_new_repo=force_new_repo, stacked_on=stacked_on,
90
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
91
make_working_trees=make_working_trees, shared_repo=shared_repo)
84
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
85
force_new_repo=force_new_repo, stacked_on=stacked_on,
86
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
87
make_working_trees=make_working_trees, shared_repo=shared_repo)
94
90
def from_string(cls, format_string):
117
113
def get_format_string(cls):
118
114
"""See BzrDirFormat.get_format_string()."""
119
return b"Bazaar-NG branch, format 5\n"
115
return "Bazaar-NG branch, format 5\n"
121
117
def get_branch_format(self):
122
118
from .branch import BzrBranchFormat4
181
177
def get_format_string(cls):
182
178
"""See BzrDirFormat.get_format_string()."""
183
return b"Bazaar-NG branch, format 6\n"
179
return "Bazaar-NG branch, format 6\n"
185
181
def get_format_description(self):
186
182
"""See ControlDirFormat.get_format_description()."""
241
237
self.controldir = to_convert
242
238
if pb is not None:
243
239
warnings.warn(gettext("pb parameter to convert() is deprecated"))
244
with ui.ui_factory.nested_progress_bar() as self.pb:
240
self.pb = ui.ui_factory.nested_progress_bar()
245
242
ui.ui_factory.note(gettext('starting upgrade from format 4 to 5'))
246
243
if isinstance(self.controldir.transport, local.LocalTransport):
247
self.controldir.get_workingtree_transport(
248
None).delete('stat-cache')
244
self.controldir.get_workingtree_transport(None).delete('stat-cache')
249
245
self._convert_to_weaves()
250
246
return ControlDir.open(self.controldir.user_url)
252
250
def _convert_to_weaves(self):
253
251
ui.ui_factory.note(gettext(
254
'note: upgrade may be faster if all store files are ungzipped first'))
252
'note: upgrade may be faster if all store files are ungzipped first'))
256
254
# TODO permissions
257
255
stat = self.controldir.transport.stat('weaves')
274
272
self.to_read = rev_history[-1:]
275
273
while self.to_read:
276
274
rev_id = self.to_read.pop()
277
if (rev_id not in self.revisions and
278
rev_id not in self.absent_revisions):
275
if (rev_id not in self.revisions
276
and rev_id not in self.absent_revisions):
279
277
self._load_one_rev(rev_id)
281
279
to_import = self._make_order()
287
285
self._write_all_revs()
288
286
ui.ui_factory.note(gettext('upgraded to weaves:'))
289
287
ui.ui_factory.note(' ' + gettext('%6d revisions and inventories') %
291
289
ui.ui_factory.note(' ' + gettext('%6d revisions not present') %
292
len(self.absent_revisions))
290
len(self.absent_revisions))
293
291
ui.ui_factory.note(' ' + gettext('%6d texts') % self.text_count)
294
292
self._cleanup_spare_files_after_format4()
295
293
self.branch._transport.put_bytes(
311
309
def _convert_working_inv(self):
312
310
inv = xml4.serializer_v4.read_inventory(
313
self.branch._transport.get('inventory'))
315
xml5.serializer_v5.write_inventory(inv, f, working=True)
316
self.branch._transport.put_bytes('inventory', f.getvalue(),
317
mode=self.controldir._get_file_mode())
311
self.branch._transport.get('inventory'))
312
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
313
self.branch._transport.put_bytes('inventory', new_inv_xml,
314
mode=self.controldir._get_file_mode())
319
316
def _write_all_weaves(self):
320
317
controlweaves = VersionedFileStore(self.controldir.transport, prefixed=False,
321
versionedfile_class=weave.WeaveFile)
318
versionedfile_class=weave.WeaveFile)
322
319
weave_transport = self.controldir.transport.clone('weaves')
323
320
weaves = VersionedFileStore(weave_transport, prefixed=False,
324
versionedfile_class=weave.WeaveFile)
321
versionedfile_class=weave.WeaveFile)
325
322
transaction = WriteTransaction()
329
326
for file_id, file_weave in self.text_weaves.items():
330
327
self.pb.update(gettext('writing weave'), i,
331
len(self.text_weaves))
328
len(self.text_weaves))
332
329
weaves._put_weave(file_id, file_weave, transaction)
334
331
self.pb.update(gettext('inventory'), 0, 1)
335
controlweaves._put_weave(b'inventory', self.inv_weave, transaction)
332
controlweaves._put_weave('inventory', self.inv_weave, transaction)
336
333
self.pb.update(gettext('inventory'), 1, 1)
346
343
from ...bzr.xml5 import serializer_v5
347
344
from .repository import RevisionTextStore
348
345
revision_store = RevisionTextStore(revision_transport,
349
serializer_v5, False, versionedfile.PrefixMapper(),
350
lambda: True, lambda: True)
346
serializer_v5, False, versionedfile.PrefixMapper(),
347
lambda:True, lambda:True)
352
349
for i, rev_id in enumerate(self.converted_revs):
353
350
self.pb.update(gettext('write revision'), i,
354
len(self.converted_revs))
355
lines = serializer_v5.write_revision_to_lines(
351
len(self.converted_revs))
352
text = serializer_v5.write_revision_to_string(
356
353
self.revisions[rev_id])
358
revision_store.add_lines(key, None, lines)
355
revision_store.add_lines(key, None, osutils.split_lines(text))
370
367
if not self.branch.repository.has_revision(rev_id):
372
369
ui.ui_factory.note(gettext('revision {%s} not present in branch; '
373
'will be converted as a ghost') %
370
'will be converted as a ghost') %
375
372
self.absent_revisions.add(rev_id)
377
374
rev = self.branch.repository.get_revision(rev_id)
381
378
self.revisions[rev_id] = rev
383
380
def _load_old_inventory(self, rev_id):
384
with self.branch.repository.inventory_store.get(rev_id) as f:
385
inv = xml4.serializer_v4.read_inventory(f)
381
f = self.branch.repository.inventory_store.get(rev_id)
383
old_inv_xml = f.read()
386
inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
386
387
inv.revision_id = rev_id
387
388
rev = self.revisions[rev_id]
390
391
def _load_updated_inventory(self, rev_id):
391
inv_xml = self.inv_weave.get_lines(rev_id)
392
inv = xml5.serializer_v5.read_inventory_from_lines(inv_xml, rev_id)
392
inv_xml = self.inv_weave.get_text(rev_id)
393
inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
395
396
def _convert_one_rev(self, rev_id):
403
404
self.converted_revs.add(rev_id)
405
406
def _store_new_inv(self, rev, inv, present_parents):
406
new_inv_xml = xml5.serializer_v5.write_inventory_to_lines(inv)
407
new_inv_sha1 = osutils.sha_strings(new_inv_xml)
407
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
408
new_inv_sha1 = osutils.sha_string(new_inv_xml)
408
409
self.inv_weave.add_lines(rev.revision_id,
411
new_inv_xml.splitlines(True))
411
412
rev.inventory_sha1 = new_inv_sha1
413
414
def _convert_revision_contents(self, rev, inv, present_parents):
439
440
heads = graph.Graph(self).heads(parent_candiate_entries)
440
441
# XXX: Note that this is unordered - and this is tolerable because
441
442
# the previous code was also unordered.
442
previous_entries = {head: parent_candiate_entries[head]
443
previous_entries = dict((head, parent_candiate_entries[head]) for head
444
445
self.snapshot_ie(previous_entries, ie, w, rev_id)
446
447
def get_parent_map(self, revision_ids):
447
448
"""See graph.StackedParentsProvider.get_parent_map"""
448
449
return dict((revision_id, self.revisions[revision_id])
449
450
for revision_id in revision_ids
450
if revision_id in self.revisions)
451
if revision_id in self.revisions)
452
453
def snapshot_ie(self, previous_revisions, ie, w, rev_id):
453
454
# TODO: convert this logic, which is ~= snapshot to
463
464
ie.revision = previous_ie.revision
465
466
if ie.has_text():
466
with self.branch.repository._text_store.get(ie.text_id) as f:
467
f = self.branch.repository._text_store.get(ie.text_id)
467
469
file_lines = f.readlines()
468
472
w.add_lines(rev_id, previous_revisions, file_lines)
469
473
self.text_count += 1
500
504
def convert(self, to_convert, pb):
501
505
"""See Converter.convert()."""
502
506
self.controldir = to_convert
503
with ui.ui_factory.nested_progress_bar() as pb:
507
pb = ui.ui_factory.nested_progress_bar()
504
509
ui.ui_factory.note(gettext('starting upgrade from format 5 to 6'))
505
510
self._convert_to_prefixed()
506
511
return ControlDir.open(self.controldir.user_url)
508
515
def _convert_to_prefixed(self):
509
516
from .store import TransportStore
514
521
store = TransportStore(store_transport, prefixed=True)
515
522
for urlfilename in store_transport.list_dir('.'):
516
523
filename = urlutils.unescape(urlfilename)
517
if (filename.endswith(".weave")
518
or filename.endswith(".gz")
519
or filename.endswith(".sig")):
524
if (filename.endswith(".weave") or
525
filename.endswith(".gz") or
526
filename.endswith(".sig")):
520
527
file_id, suffix = os.path.splitext(filename)
522
529
file_id = filename
524
new_name = store._mapper.map(
525
(file_id.encode('utf-8'),)) + suffix
531
new_name = store._mapper.map((file_id,)) + suffix
526
532
# FIXME keep track of the dirs made RBC 20060121
528
534
store_transport.move(filename, new_name)
529
except errors.NoSuchFile: # catches missing dirs strangely enough
535
except errors.NoSuchFile: # catches missing dirs strangely enough
530
536
store_transport.mkdir(osutils.dirname(new_name))
531
537
store_transport.move(filename, new_name)
532
538
self.controldir.transport.put_bytes(
545
551
self.controldir = to_convert
546
552
self.pb = ui.ui_factory.nested_progress_bar()
548
self.total = 20 # the steps we know about
554
self.total = 20 # the steps we know about
549
555
self.garbage_inventories = []
550
556
self.dir_mode = self.controldir._get_dir_mode()
551
557
self.file_mode = self.controldir._get_file_mode()
554
gettext('starting upgrade from format 6 to metadir'))
559
ui.ui_factory.note(gettext('starting upgrade from format 6 to metadir'))
555
560
self.controldir.transport.put_bytes(
557
b"Converting to format 6",
562
"Converting to format 6",
559
564
# its faster to move specific files around than to open and use the apis...
560
565
# first off, nuke ancestry.weave, it was never used.
617
622
self.step(gettext('Upgrading working tree'))
618
623
self.controldir.transport.mkdir('checkout', mode=self.dir_mode)
619
624
self.make_lock('checkout')
620
self.put_format('checkout', WorkingTreeFormat3())
621
for path in self.garbage_inventories:
622
self.controldir.transport.delete(path)
626
'checkout', WorkingTreeFormat3())
627
self.controldir.transport.delete_multi(
628
self.garbage_inventories, self.pb)
623
629
for entry in checkout_files:
624
630
self.move_entry('checkout', entry)
625
631
if last_revision is not None:
655
661
def put_format(self, dirname, format):
656
662
self.controldir.transport.put_bytes('%s/format' % dirname,
657
format.get_format_string(),
663
format.get_format_string(),
661
667
class BzrDirFormat4(BzrDirFormat):
680
686
def get_format_string(cls):
681
687
"""See BzrDirFormat.get_format_string()."""
682
return b"Bazaar-NG branch, format 0.0.4\n"
688
return "Bazaar-NG branch, format 0.0.4\n"
684
690
def get_format_description(self):
685
691
"""See ControlDirFormat.get_format_description()."""
730
736
"""See ControlDir.__init__."""
731
737
super(BzrDirPreSplitOut, self).__init__(_transport, _format)
732
738
self._control_files = lockable_files.LockableFiles(
733
self.get_branch_transport(None),
734
self._format._lock_file_name,
735
self._format._lock_class)
739
self.get_branch_transport(None),
740
self._format._lock_file_name,
741
self._format._lock_class)
737
743
def break_lock(self):
738
744
"""Pre-splitout bzrdirs do not suffer from stale locks."""
745
751
return self._format.__class__()
747
753
def clone(self, url, revision_id=None, force_new_repo=False,
748
preserve_stacking=False, tag_selector=None):
754
preserve_stacking=False):
749
755
"""See ControlDir.clone().
751
757
force_new_repo has no effect, since this family of formats always
757
763
result = self._format._initialize_for_clone(url)
758
764
self.open_repository().clone(result, revision_id=revision_id)
759
765
from_branch = self.open_branch()
760
from_branch.clone(result, revision_id=revision_id, tag_selector=tag_selector)
766
from_branch.clone(result, revision_id=revision_id)
762
768
tree = self.open_workingtree()
763
769
except errors.NotLocalUrl:
774
780
raise NotImplementedError(
775
781
"create_branch(repository=<not None>) on %r" % (self,))
776
782
return self._format.get_branch_format().initialize(self, name=name,
777
append_revisions_only=append_revisions_only)
783
append_revisions_only=append_revisions_only)
779
785
def destroy_branch(self, name=None):
780
786
"""See ControlDir.destroy_branch."""
841
847
def get_branch_transport(self, branch_format, name=None):
842
848
"""See BzrDir.get_branch_transport()."""
844
850
raise errors.NoColocatedBranchSupport(self)
845
851
if branch_format is None:
846
852
return self.transport
883
889
format = BzrBranchFormat4()
884
890
format.check_support_status(unsupported)
885
891
return format.open(self, name, _found=True,
886
possible_transports=possible_transports)
892
possible_transports=possible_transports)
888
894
def sprout(self, url, revision_id=None, force_new_repo=False,
889
recurse=None, possible_transports=None, accelerator_tree=None,
895
possible_transports=None, accelerator_tree=None,
890
896
hardlink=False, stacked=False, create_tree_if_local=True,
891
897
source_branch=None):
892
898
"""See ControlDir.sprout()."""
897
903
"source branch %r is not within %r with branch %r" %
898
904
(source_branch, self, my_branch))
900
raise _mod_branch.UnstackableBranchFormat(
906
raise errors.UnstackableBranchFormat(
901
907
self._format, self.root_transport.base)
902
908
if not create_tree_if_local:
903
raise MustHaveWorkingTree(
909
raise errors.MustHaveWorkingTree(
904
910
self._format, self.root_transport.base)
905
911
from .workingtree import WorkingTreeFormat2
906
912
self._make_tail(url)
956
962
def has_workingtree(self):
957
963
"""See ControlDir.has_workingtree."""
960
966
def open_repository(self):
961
967
"""See ControlDir.open_repository."""
962
968
from .repository import RepositoryFormat5
963
969
return RepositoryFormat5().open(self, _found=True)
965
971
def open_workingtree(self, unsupported=False,
966
recommend_upgrade=True):
972
recommend_upgrade=True):
967
973
"""See ControlDir.create_workingtree."""
968
974
from .workingtree import WorkingTreeFormat2
969
975
wt_format = WorkingTreeFormat2()