1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
1
# Copyright (C) 2006-2010 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
91
class ControlComponent(object):
92
"""Abstract base class for control directory components.
94
This provides interfaces that are common across bzrdirs,
95
repositories, branches, and workingtree control directories.
97
They all expose two urls and transports: the *user* URL is the
98
one that stops above the control directory (eg .bzr) and that
99
should normally be used in messages, and the *control* URL is
100
under that in eg .bzr/checkout and is used to read the control
103
This can be used as a mixin and is intended to fit with
108
def control_transport(self):
109
raise NotImplementedError
112
def control_url(self):
113
return self.control_transport.base
116
def user_transport(self):
117
raise NotImplementedError
121
return self.user_transport.base
124
class BzrDir(ControlComponent):
90
125
"""A .bzr control diretory.
92
127
BzrDir instances let you create or open any of the things that can be
130
165
def check_conversion_target(self, target_format):
166
"""Check that a bzrdir as a whole can be converted to a new format."""
167
# The only current restriction is that the repository content can be
168
# fetched compatibly with the target.
131
169
target_repo_format = target_format.repository_format
132
source_repo_format = self._format.repository_format
133
source_repo_format.check_conversion_target(target_repo_format)
171
self.open_repository()._format.check_conversion_target(
173
except errors.NoRepositoryPresent:
174
# No repo, no problem.
136
178
def _check_supported(format, allow_unsupported,
252
294
# copied, and finally if we are copying up to a specific
253
295
# revision_id then we can use the pending-ancestry-result which
254
296
# does not require traversing all of history to describe it.
255
if (result_repo.bzrdir.root_transport.base ==
256
result.root_transport.base and not require_stacking and
297
if (result_repo.user_url == result.user_url
298
and not require_stacking and
257
299
revision_id is not None):
258
300
fetch_spec = graph.PendingAncestryResult(
259
301
[revision_id], local_repo)
335
377
bzrdir = BzrDir.open_from_transport(current_transport)
336
except errors.NotBranchError:
378
except (errors.NotBranchError, errors.PermissionDenied):
339
381
recurse, value = evaluate(bzrdir)
342
384
subdirs = list_current(current_transport)
343
except errors.NoSuchFile:
385
except (errors.NoSuchFile, errors.PermissionDenied):
346
388
for subdir in sorted(subdirs, reverse=True):
347
389
pending.append(current_transport.clone(subdir))
391
def list_branches(self):
392
"""Return a sequence of all branches local to this control directory.
396
return [self.open_branch()]
397
except (errors.NotBranchError, errors.NoRepositoryPresent):
350
401
def find_branches(transport):
351
402
"""Find all branches under a transport.
363
414
except errors.NoRepositoryPresent:
366
return False, (None, repository)
368
branch = bzrdir.open_branch()
369
except errors.NotBranchError:
370
return True, (None, None)
372
return True, (branch, None)
374
for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
417
return False, ([], repository)
418
return True, (bzrdir.list_branches(), None)
420
for branches, repo in BzrDir.find_bzrdirs(transport,
375
422
if repo is not None:
376
branches.extend(repo.find_branches())
377
if branch is not None:
378
branches.append(branch)
423
ret.extend(repo.find_branches())
424
if branches is not None:
381
428
def destroy_repository(self):
382
429
"""Destroy the repository in this BzrDir"""
383
430
raise NotImplementedError(self.destroy_repository)
385
def create_branch(self):
432
def create_branch(self, name=None):
386
433
"""Create a branch in this BzrDir.
435
:param name: Name of the colocated branch to create, None for
388
438
The bzrdir's format will control what branch format is created.
389
439
For more control see BranchFormatXX.create(a_bzrdir).
391
441
raise NotImplementedError(self.create_branch)
393
def destroy_branch(self):
394
"""Destroy the branch in this BzrDir"""
443
def destroy_branch(self, name=None):
444
"""Destroy a branch in this BzrDir.
446
:param name: Name of the branch to destroy, None for the default
395
449
raise NotImplementedError(self.destroy_branch)
445
499
except errors.NoRepositoryPresent:
446
500
repository = None
448
if ((found_bzrdir.root_transport.base !=
449
self.root_transport.base) and not repository.is_shared()):
502
if (found_bzrdir.user_url != self.user_url
503
and not repository.is_shared()):
450
504
# Don't look higher, can't use a higher shared repo.
451
505
repository = None
567
621
:return: Tuple with old path name and new path name
623
def name_gen(base='backup.bzr'):
625
name = "%s.~%d~" % (base, counter)
626
while self.root_transport.has(name):
628
name = "%s.~%d~" % (base, counter)
631
backup_dir=name_gen()
569
632
pb = ui.ui_factory.nested_progress_bar()
571
634
# FIXME: bug 300001 -- the backup fails if the backup directory
572
635
# already exists, but it should instead either remove it or make
573
636
# a new backup directory.
575
# FIXME: bug 262450 -- the backup directory should have the same
576
# permissions as the .bzr directory (probably a bug in copy_tree)
577
638
old_path = self.root_transport.abspath('.bzr')
578
new_path = self.root_transport.abspath('backup.bzr')
579
pb.note('making backup of %s' % (old_path,))
580
pb.note(' to %s' % (new_path,))
581
self.root_transport.copy_tree('.bzr', 'backup.bzr')
639
new_path = self.root_transport.abspath(backup_dir)
640
ui.ui_factory.note('making backup of %s\n to %s' % (old_path, new_path,))
641
self.root_transport.copy_tree('.bzr', backup_dir)
582
642
return (old_path, new_path)
644
704
next_transport = found_bzrdir.root_transport.clone('..')
645
if (found_bzrdir.root_transport.base == next_transport.base):
705
if (found_bzrdir.user_url == next_transport.base):
646
706
# top of the file system
648
708
# find the next containing bzrdir
665
725
repository = found_bzrdir.open_repository()
666
726
except errors.NoRepositoryPresent:
667
727
return None, False
668
if found_bzrdir.root_transport.base == self.root_transport.base:
728
if found_bzrdir.user_url == self.user_url:
669
729
return repository, True
670
730
elif repository.is_shared():
671
731
return repository, True
677
737
raise errors.NoRepositoryPresent(self)
678
738
return found_repo
680
def get_branch_reference(self):
740
def get_branch_reference(self, name=None):
681
741
"""Return the referenced URL for the branch in this bzrdir.
743
:param name: Optional colocated branch name
683
744
:raises NotBranchError: If there is no Branch.
745
:raises NoColocatedBranchSupport: If a branch name was specified
746
but colocated branches are not supported.
684
747
:return: The URL the branch in this bzrdir references if it is a
685
748
reference branch, or None for regular branches.
751
raise errors.NoColocatedBranchSupport(self)
689
def get_branch_transport(self, branch_format):
754
def get_branch_transport(self, branch_format, name=None):
690
755
"""Get the transport for use by branch format in this BzrDir.
692
757
Note that bzr dirs that do not support format strings will raise
787
852
:param _transport: the transport this dir is based at.
789
854
self._format = _format
855
# these are also under the more standard names of
856
# control_transport and user_transport
790
857
self.transport = _transport.clone('.bzr')
791
858
self.root_transport = _transport
792
859
self._mode_check_done = False
862
def user_transport(self):
863
return self.root_transport
866
def control_transport(self):
867
return self.transport
794
869
def is_control_filename(self, filename):
795
870
"""True if filename is the name of a path which is reserved for bzrdir's.
870
945
BzrDir._check_supported(format, _unsupported)
871
946
return format.open(transport, _found=True)
873
def open_branch(self, unsupported=False, ignore_fallbacks=False):
948
def open_branch(self, name=None, unsupported=False,
949
ignore_fallbacks=False):
874
950
"""Open the branch object at this BzrDir if one is present.
876
952
If unsupported is True, then no longer supported branch formats can
923
999
raise errors.NotBranchError(path=url)
924
1000
a_transport = new_t
926
def _get_tree_branch(self):
1002
def _get_tree_branch(self, name=None):
927
1003
"""Return the branch and tree, if any, for this bzrdir.
1005
:param name: Name of colocated branch to open.
929
1007
Return None for tree if not present or inaccessible.
930
1008
Raise NotBranchError if no branch is present.
931
1009
:return: (tree, branch)
934
1012
tree = self.open_workingtree()
935
1013
except (errors.NoWorkingTree, errors.NotLocalUrl):
937
branch = self.open_branch()
1015
branch = self.open_branch(name=name)
1017
if name is not None:
1018
branch = self.open_branch(name=name)
1020
branch = tree.branch
940
1021
return tree, branch
1015
1096
raise NotImplementedError(self.open_workingtree)
1017
def has_branch(self):
1098
def has_branch(self, name=None):
1018
1099
"""Tell if this bzrdir contains a branch.
1020
1101
Note: if you're going to open the branch, you should just go ahead
1163
1244
repository_policy = result.determine_repository_policy(
1164
1245
force_new_repo, stacked_branch_url, require_stacking=stacked)
1165
1246
result_repo, is_new_repo = repository_policy.acquire_repository()
1166
if is_new_repo and revision_id is not None and not stacked:
1247
is_stacked = stacked or (len(result_repo._fallback_repositories) != 0)
1248
if is_new_repo and revision_id is not None and not is_stacked:
1167
1249
fetch_spec = graph.PendingAncestryResult(
1168
1250
[revision_id], source_repository)
1302
1384
self.create_hook(hooks.HookPoint('pre_open',
1303
1385
"Invoked before attempting to open a BzrDir with the transport "
1304
1386
"that the open will use.", (1, 14), None))
1387
self.create_hook(hooks.HookPoint('post_repo_init',
1388
"Invoked after a repository has been initialized. "
1389
"post_repo_init is called with a "
1390
"bzrlib.bzrdir.RepoInitHookParams.",
1306
1393
# install the default hooks
1307
1394
BzrDir.hooks = BzrDirHooks()
1397
class RepoInitHookParams(object):
1398
"""Object holding parameters passed to *_repo_init hooks.
1400
There are 4 fields that hooks may wish to access:
1402
:ivar repository: Repository created
1403
:ivar format: Repository format
1404
:ivar bzrdir: The bzrdir for the repository
1405
:ivar shared: The repository is shared
1408
def __init__(self, repository, format, a_bzrdir, shared):
1409
"""Create a group of RepoInitHook parameters.
1411
:param repository: Repository created
1412
:param format: Repository format
1413
:param bzrdir: The bzrdir for the repository
1414
:param shared: The repository is shared
1416
self.repository = repository
1417
self.format = format
1418
self.bzrdir = a_bzrdir
1419
self.shared = shared
1421
def __eq__(self, other):
1422
return self.__dict__ == other.__dict__
1426
return "<%s for %s>" % (self.__class__.__name__,
1429
return "<%s for %s>" % (self.__class__.__name__,
1310
1433
class BzrDirPreSplitOut(BzrDir):
1311
1434
"""A common class for the all-in-one formats."""
1351
1474
tree.clone(result)
1354
def create_branch(self):
1477
def create_branch(self, name=None):
1355
1478
"""See BzrDir.create_branch."""
1356
return self._format.get_branch_format().initialize(self)
1479
return self._format.get_branch_format().initialize(self, name=name)
1358
def destroy_branch(self):
1481
def destroy_branch(self, name=None):
1359
1482
"""See BzrDir.destroy_branch."""
1360
1483
raise errors.UnsupportedOperation(self.destroy_branch, self)
1384
1507
# that can do wonky stuff here, and that only
1385
1508
# happens for creating checkouts, which cannot be
1386
1509
# done on this format anyway. So - acceptable wart.
1511
warning("can't support hardlinked working trees in %r"
1388
1514
result = self.open_workingtree(recommend_upgrade=False)
1389
1515
except errors.NoSuchFile:
1414
1540
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1417
def get_branch_transport(self, branch_format):
1543
def get_branch_transport(self, branch_format, name=None):
1418
1544
"""See BzrDir.get_branch_transport()."""
1545
if name is not None:
1546
raise errors.NoColocatedBranchSupport(self)
1419
1547
if branch_format is None:
1420
1548
return self.transport
1454
1582
format = BzrDirFormat.get_default_format()
1455
1583
return not isinstance(self._format, format.__class__)
1457
def open_branch(self, unsupported=False, ignore_fallbacks=False):
1585
def open_branch(self, name=None, unsupported=False,
1586
ignore_fallbacks=False):
1458
1587
"""See BzrDir.open_branch."""
1459
1588
from bzrlib.branch import BzrBranchFormat4
1460
1589
format = BzrBranchFormat4()
1461
1590
self._check_supported(format, unsupported)
1462
return format.open(self, _found=True)
1591
return format.open(self, name, _found=True)
1464
1593
def sprout(self, url, revision_id=None, force_new_repo=False,
1465
1594
possible_transports=None, accelerator_tree=None,
1526
1655
This is a deprecated format and may be removed after sept 2006.
1658
def has_workingtree(self):
1659
"""See BzrDir.has_workingtree."""
1529
1662
def open_repository(self):
1530
1663
"""See BzrDir.open_repository."""
1531
1664
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1547
1680
This is a deprecated format and may be removed after sept 2006.
1683
def has_workingtree(self):
1684
"""See BzrDir.has_workingtree."""
1550
1687
def open_repository(self):
1551
1688
"""See BzrDir.open_repository."""
1552
1689
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1574
1711
"""See BzrDir.can_convert_format()."""
1577
def create_branch(self):
1714
def create_branch(self, name=None):
1578
1715
"""See BzrDir.create_branch."""
1579
return self._format.get_branch_format().initialize(self)
1716
return self._format.get_branch_format().initialize(self, name=name)
1581
def destroy_branch(self):
1718
def destroy_branch(self, name=None):
1582
1719
"""See BzrDir.create_branch."""
1720
if name is not None:
1721
raise errors.NoColocatedBranchSupport(self)
1583
1722
self.transport.delete_tree('branch')
1585
1724
def create_repository(self, shared=False):
1608
1747
def destroy_workingtree_metadata(self):
1609
1748
self.transport.delete_tree('checkout')
1611
def find_branch_format(self):
1750
def find_branch_format(self, name=None):
1612
1751
"""Find the branch 'format' for this bzrdir.
1614
1753
This might be a synthetic object for e.g. RemoteBranch and SVN.
1616
1755
from bzrlib.branch import BranchFormat
1617
return BranchFormat.find_format(self)
1756
return BranchFormat.find_format(self, name=name)
1619
1758
def _get_mkdir_mode(self):
1620
1759
"""Figure out the mode to use when creating a bzrdir subdir."""
1622
1761
lockable_files.TransportLock)
1623
1762
return temp_control._dir_mode
1625
def get_branch_reference(self):
1764
def get_branch_reference(self, name=None):
1626
1765
"""See BzrDir.get_branch_reference()."""
1627
1766
from bzrlib.branch import BranchFormat
1628
format = BranchFormat.find_format(self)
1629
return format.get_reference(self)
1767
format = BranchFormat.find_format(self, name=name)
1768
return format.get_reference(self, name=name)
1631
def get_branch_transport(self, branch_format):
1770
def get_branch_transport(self, branch_format, name=None):
1632
1771
"""See BzrDir.get_branch_transport()."""
1772
if name is not None:
1773
raise errors.NoColocatedBranchSupport(self)
1774
# XXX: this shouldn't implicitly create the directory if it's just
1775
# promising to get a transport -- mbp 20090727
1633
1776
if branch_format is None:
1634
1777
return self.transport.clone('branch')
1671
1814
return self.transport.clone('checkout')
1816
def has_workingtree(self):
1817
"""Tell if this bzrdir contains a working tree.
1819
This will still raise an exception if the bzrdir has a workingtree that
1820
is remote & inaccessible.
1822
Note: if you're going to open the working tree, you should just go
1823
ahead and try, and not ask permission first.
1825
from bzrlib.workingtree import WorkingTreeFormat
1827
WorkingTreeFormat.find_format(self)
1828
except errors.NoWorkingTree:
1673
1832
def needs_format_conversion(self, format=None):
1674
1833
"""See BzrDir.needs_format_conversion()."""
1675
1834
if format is None:
1689
1848
except errors.NoRepositoryPresent:
1692
if not isinstance(self.open_branch()._format,
1850
for branch in self.list_branches():
1851
if not isinstance(branch._format,
1693
1852
format.get_branch_format().__class__):
1694
1853
# the branch needs an upgrade.
1696
except errors.NotBranchError:
1699
1856
my_wt = self.open_workingtree(recommend_upgrade=False)
1700
1857
if not isinstance(my_wt._format,
1708
def open_branch(self, unsupported=False, ignore_fallbacks=False):
1865
def open_branch(self, name=None, unsupported=False,
1866
ignore_fallbacks=False):
1709
1867
"""See BzrDir.open_branch."""
1710
format = self.find_branch_format()
1868
format = self.find_branch_format(name=name)
1711
1869
self._check_supported(format, unsupported)
1712
return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
1870
return format.open(self, name=name,
1871
_found=True, ignore_fallbacks=ignore_fallbacks)
1714
1873
def open_repository(self, unsupported=False):
1715
1874
"""See BzrDir.open_repository."""
1747
1906
Once a format is deprecated, just deprecate the initialize and open
1748
1907
methods on the format class. Do not deprecate the object, as the
1749
1908
object will be created every system load.
1910
:cvar colocated_branches: Whether this formats supports colocated branches.
1752
1913
_default_format = None
1770
1931
_lock_file_name = 'branch-lock'
1933
colocated_branches = False
1934
"""Whether co-located branches are supported for this control dir format.
1772
1937
# _lock_class must be set in subclasses to the lock type, typ.
1773
1938
# TransportLock or LockDir
1791
1956
def probe_transport(klass, transport):
1792
1957
"""Return the .bzrdir style format present in a directory."""
1794
format_string = transport.get(".bzr/branch-format").read()
1959
format_string = transport.get_bytes(".bzr/branch-format")
1795
1960
except errors.NoSuchFile:
1796
1961
raise errors.NotBranchError(path=transport.base)
1799
1963
return klass._formats[format_string]
1800
1964
except KeyError:
2573
2737
def convert(self, to_convert, pb):
2574
2738
"""See Converter.convert()."""
2575
2739
self.bzrdir = to_convert
2577
self.pb.note('starting upgrade from format 4 to 5')
2578
if isinstance(self.bzrdir.transport, local.LocalTransport):
2579
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2580
self._convert_to_weaves()
2581
return BzrDir.open(self.bzrdir.root_transport.base)
2741
warnings.warn("pb parameter to convert() is deprecated")
2742
self.pb = ui.ui_factory.nested_progress_bar()
2744
ui.ui_factory.note('starting upgrade from format 4 to 5')
2745
if isinstance(self.bzrdir.transport, local.LocalTransport):
2746
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2747
self._convert_to_weaves()
2748
return BzrDir.open(self.bzrdir.user_url)
2583
2752
def _convert_to_weaves(self):
2584
self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
2753
ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2586
2755
# TODO permissions
2587
2756
stat = self.bzrdir.transport.stat('weaves')
2615
2784
self.pb.clear()
2616
2785
self._write_all_weaves()
2617
2786
self._write_all_revs()
2618
self.pb.note('upgraded to weaves:')
2619
self.pb.note(' %6d revisions and inventories', len(self.revisions))
2620
self.pb.note(' %6d revisions not present', len(self.absent_revisions))
2621
self.pb.note(' %6d texts', self.text_count)
2787
ui.ui_factory.note('upgraded to weaves:')
2788
ui.ui_factory.note(' %6d revisions and inventories' % len(self.revisions))
2789
ui.ui_factory.note(' %6d revisions not present' % len(self.absent_revisions))
2790
ui.ui_factory.note(' %6d texts' % self.text_count)
2622
2791
self._cleanup_spare_files_after_format4()
2623
2792
self.branch._transport.put_bytes(
2624
2793
'branch-format',
2692
2861
len(self.known_revisions))
2693
2862
if not self.branch.repository.has_revision(rev_id):
2694
2863
self.pb.clear()
2695
self.pb.note('revision {%s} not present in branch; '
2696
'will be converted as a ghost',
2864
ui.ui_factory.note('revision {%s} not present in branch; '
2865
'will be converted as a ghost' %
2698
2867
self.absent_revisions.add(rev_id)
2704
2873
self.revisions[rev_id] = rev
2706
2875
def _load_old_inventory(self, rev_id):
2707
old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
2876
f = self.branch.repository.inventory_store.get(rev_id)
2878
old_inv_xml = f.read()
2708
2881
inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2709
2882
inv.revision_id = rev_id
2710
2883
rev = self.revisions[rev_id]
2766
2939
previous_entries = dict((head, parent_candiate_entries[head]) for head
2768
2941
self.snapshot_ie(previous_entries, ie, w, rev_id)
2771
2943
def get_parent_map(self, revision_ids):
2772
2944
"""See graph.StackedParentsProvider.get_parent_map"""
2788
2960
ie.revision = previous_ie.revision
2790
2962
if ie.has_text():
2791
text = self.branch.repository._text_store.get(ie.text_id)
2792
file_lines = text.readlines()
2963
f = self.branch.repository._text_store.get(ie.text_id)
2965
file_lines = f.readlines()
2793
2968
w.add_lines(rev_id, previous_revisions, file_lines)
2794
2969
self.text_count += 1
2825
3000
def convert(self, to_convert, pb):
2826
3001
"""See Converter.convert()."""
2827
3002
self.bzrdir = to_convert
2829
self.pb.note('starting upgrade from format 5 to 6')
2830
self._convert_to_prefixed()
2831
return BzrDir.open(self.bzrdir.root_transport.base)
3003
pb = ui.ui_factory.nested_progress_bar()
3005
ui.ui_factory.note('starting upgrade from format 5 to 6')
3006
self._convert_to_prefixed()
3007
return BzrDir.open(self.bzrdir.user_url)
2833
3011
def _convert_to_prefixed(self):
2834
3012
from bzrlib.store import TransportStore
2835
3013
self.bzrdir.transport.delete('branch-format')
2836
3014
for store_name in ["weaves", "revision-store"]:
2837
self.pb.note("adding prefixes to %s" % store_name)
3015
ui.ui_factory.note("adding prefixes to %s" % store_name)
2838
3016
store_transport = self.bzrdir.transport.clone(store_name)
2839
3017
store = TransportStore(store_transport, prefixed=True)
2840
3018
for urlfilename in store_transport.list_dir('.'):
2867
3045
from bzrlib.repofmt.weaverepo import RepositoryFormat7
2868
3046
from bzrlib.branch import BzrBranchFormat5
2869
3047
self.bzrdir = to_convert
3048
self.pb = ui.ui_factory.nested_progress_bar()
2872
3050
self.total = 20 # the steps we know about
2873
3051
self.garbage_inventories = []
2874
3052
self.dir_mode = self.bzrdir._get_dir_mode()
2875
3053
self.file_mode = self.bzrdir._get_file_mode()
2877
self.pb.note('starting upgrade from format 6 to metadir')
3055
ui.ui_factory.note('starting upgrade from format 6 to metadir')
2878
3056
self.bzrdir.transport.put_bytes(
2879
3057
'branch-format',
2880
3058
"Converting to format 6",
2931
3109
has_checkout = True
2932
3110
if not has_checkout:
2933
self.pb.note('No working tree.')
3111
ui.ui_factory.note('No working tree.')
2934
3112
# If some checkout files are there, we may as well get rid of them.
2935
3113
for name, mandatory in checkout_files:
2936
3114
if name in bzrcontents:
2953
3131
'branch-format',
2954
3132
BzrDirMetaFormat1().get_format_string(),
2955
3133
mode=self.file_mode)
2956
return BzrDir.open(self.bzrdir.root_transport.base)
3135
return BzrDir.open(self.bzrdir.user_url)
2958
3137
def make_lock(self, name):
2959
3138
"""Make a lock for the new control dir name."""
2994
3173
def convert(self, to_convert, pb):
2995
3174
"""See Converter.convert()."""
2996
3175
self.bzrdir = to_convert
3176
self.pb = ui.ui_factory.nested_progress_bar()
3000
3179
self.step('checking repository format')
3006
3185
if not isinstance(repo._format, self.target_format.repository_format.__class__):
3007
3186
from bzrlib.repository import CopyConverter
3008
self.pb.note('starting repository conversion')
3187
ui.ui_factory.note('starting repository conversion')
3009
3188
converter = CopyConverter(self.target_format.repository_format)
3010
3189
converter.convert(repo, pb)
3012
branch = self.bzrdir.open_branch()
3013
except errors.NotBranchError:
3190
for branch in self.bzrdir.list_branches():
3016
3191
# TODO: conversions of Branch and Tree should be done by
3017
3192
# InterXFormat lookups/some sort of registry.
3018
3193
# Avoid circular imports
3033
3208
new is _mod_branch.BzrBranchFormat8):
3034
3209
branch_converter = _mod_branch.Converter7to8()
3036
raise errors.BadConversionTarget("No converter", new)
3211
raise errors.BadConversionTarget("No converter", new,
3037
3213
branch_converter.convert(branch)
3038
3214
branch = self.bzrdir.open_branch()
3039
3215
old = branch._format.__class__
3072
3249
def __init__(self):
3073
3250
BzrDirMetaFormat1.__init__(self)
3251
# XXX: It's a bit ugly that the network name is here, because we'd
3252
# like to believe that format objects are stateless or at least
3253
# immutable, However, we do at least avoid mutating the name after
3254
# it's returned. See <https://bugs.launchpad.net/bzr/+bug/504102>
3074
3255
self._network_name = None
3258
return "%s(_network_name=%r)" % (self.__class__.__name__,
3076
3261
def get_format_description(self):
3262
if self._network_name:
3263
real_format = network_format_registry.get(self._network_name)
3264
return 'Remote: ' + real_format.get_format_description()
3077
3265
return 'bzr remote bzrdir'
3079
3267
def get_format_string(self):
3212
3400
args.append(self._serialize_NoneString(repo_format_name))
3213
3401
args.append(self._serialize_NoneTrueFalse(make_working_trees))
3214
3402
args.append(self._serialize_NoneTrueFalse(shared_repo))
3215
if self._network_name is None:
3216
self._network_name = \
3403
request_network_name = self._network_name or \
3217
3404
BzrDirFormat.get_default_format().network_name()
3219
3406
response = client.call('BzrDirFormat.initialize_ex_1.16',
3220
self.network_name(), path, *args)
3407
request_network_name, path, *args)
3221
3408
except errors.UnknownSmartMethod:
3222
3409
client._medium._remember_remote_is_before((1,16))
3223
3410
local_dir_format = BzrDirMetaFormat1()
3473
3660
experimental_pairs.append((key, help))
3475
3662
output += wrapped(key, help, info)
3476
output += "\nSee ``bzr help formats`` for more about storage formats."
3663
output += "\nSee :doc:`formats-help` for more about storage formats."
3477
3664
other_output = ""
3478
3665
if len(experimental_pairs) > 0:
3479
3666
other_output += "Experimental formats are shown below.\n\n"
3533
3720
stack_on = urlutils.rebase_url(self._stack_on,
3534
3721
self._stack_on_pwd,
3535
branch.bzrdir.root_transport.base)
3536
3723
except errors.InvalidRebaseURLs:
3537
3724
stack_on = self._get_full_stack_on()
3542
3729
if self._require_stacking:
3732
def requires_stacking(self):
3733
"""Return True if this policy requires stacking."""
3734
return self._stack_on is not None and self._require_stacking
3545
3736
def _get_full_stack_on(self):
3546
3737
"""Get a fully-qualified URL for the stack_on location."""
3547
3738
if self._stack_on is None:
3663
3854
format_registry.register('weave', BzrDirFormat6,
3664
3855
'Pre-0.8 format. Slower than knit and does not'
3665
3856
' support checkouts or shared repositories.',
3666
3858
deprecated=True)
3667
3859
format_registry.register_metadir('metaweave',
3668
3860
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3669
3861
'Transitional format in 0.8. Slower than knit.',
3670
3862
branch_format='bzrlib.branch.BzrBranchFormat5',
3671
3863
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3672
3865
deprecated=True)
3673
3866
format_registry.register_metadir('knit',
3674
3867
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3675
3868
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
3676
3869
branch_format='bzrlib.branch.BzrBranchFormat5',
3677
3870
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3678
3872
deprecated=True)
3679
3873
format_registry.register_metadir('dirstate',
3680
3874
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3684
3878
# this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
3685
3879
# directly from workingtree_4 triggers a circular import.
3686
3880
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3687
3882
deprecated=True)
3688
3883
format_registry.register_metadir('dirstate-tags',
3689
3884
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3692
3887
' Incompatible with bzr < 0.15.',
3693
3888
branch_format='bzrlib.branch.BzrBranchFormat6',
3694
3889
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3695
3891
deprecated=True)
3696
3892
format_registry.register_metadir('rich-root',
3697
3893
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3700
3896
branch_format='bzrlib.branch.BzrBranchFormat6',
3701
3897
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3702
3899
deprecated=True)
3703
3900
format_registry.register_metadir('dirstate-with-subtree',
3704
3901
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3715
3912
help='New in 0.92: Pack-based format with data compatible with '
3716
3913
'dirstate-tags format repositories. Interoperates with '
3717
3914
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3718
'Previously called knitpack-experimental. '
3719
'For more information, see '
3720
'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3721
3916
branch_format='bzrlib.branch.BzrBranchFormat6',
3722
3917
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3726
3921
help='New in 0.92: Pack-based format with data compatible with '
3727
3922
'dirstate-with-subtree format repositories. Interoperates with '
3728
3923
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3729
'Previously called knitpack-experimental. '
3730
'For more information, see '
3731
'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3732
3925
branch_format='bzrlib.branch.BzrBranchFormat6',
3733
3926
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3740
3933
'(needed for bzr-svn and bzr-git).',
3741
3934
branch_format='bzrlib.branch.BzrBranchFormat6',
3742
3935
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3744
3938
format_registry.register_metadir('1.6',
3745
3939
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3748
3942
'not present locally.',
3749
3943
branch_format='bzrlib.branch.BzrBranchFormat7',
3750
3944
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3752
3947
format_registry.register_metadir('1.6.1-rich-root',
3753
3948
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3755
3950
'(needed for bzr-svn and bzr-git).',
3756
3951
branch_format='bzrlib.branch.BzrBranchFormat7',
3757
3952
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3759
3955
format_registry.register_metadir('1.9',
3760
3956
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3763
3959
'performance for most operations.',
3764
3960
branch_format='bzrlib.branch.BzrBranchFormat7',
3765
3961
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3767
3964
format_registry.register_metadir('1.9-rich-root',
3768
3965
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3770
3967
'(needed for bzr-svn and bzr-git).',
3771
3968
branch_format='bzrlib.branch.BzrBranchFormat7',
3772
3969
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3774
3972
format_registry.register_metadir('1.14',
3775
3973
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3791
3989
'to and from rich-root-pack (and anything compatible with '
3792
3990
'rich-root-pack) format repositories. Repositories and branches in '
3793
3991
'this format can only be read by bzr.dev. Please read '
3794
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3992
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3796
3994
branch_format='bzrlib.branch.BzrBranchFormat7',
3797
3995
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3798
3996
experimental=True,
3801
4000
format_registry.register_metadir('development-subtree',
3802
4001
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3804
4003
'from pack-0.92-subtree (and anything compatible with '
3805
4004
'pack-0.92-subtree) format repositories. Repositories and branches in '
3806
4005
'this format can only be read by bzr.dev. Please read '
3807
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
4006
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3809
4008
branch_format='bzrlib.branch.BzrBranchFormat7',
3810
4009
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3811
4010
experimental=True,
3812
4012
alias=False, # Restore to being an alias when an actual development subtree format is added
3813
4013
# This current non-alias status is simply because we did not introduce a
3814
4014
# chk based subtree format.
3819
4019
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3820
4020
help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3822
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
4022
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3824
4024
branch_format='bzrlib.branch.BzrBranchFormat7',
3825
4025
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3831
4031
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3832
4032
help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3833
4033
'rich roots. Please read '
3834
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
4034
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3836
4036
branch_format='bzrlib.branch.BzrBranchFormat7',
3837
4037
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3854
4054
# The following format should be an alias for the rich root equivalent
3855
4055
# of the default format
3856
4056
format_registry.register_metadir('default-rich-root',
3857
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3858
help='Default format, rich root variant. (needed for bzr-svn and bzr-git).',
3859
branch_format='bzrlib.branch.BzrBranchFormat6',
3860
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
4057
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
4058
branch_format='bzrlib.branch.BzrBranchFormat7',
4059
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3863
4064
# The current format that is made on 'bzr init'.
3864
format_registry.set_default('pack-0.92')
4065
format_registry.set_default('2a')