1
# Copyright (C) 2006-2010 Canonical Ltd
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 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):
125
91
"""A .bzr control diretory.
127
93
BzrDir instances let you create or open any of the things that can be
165
131
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.
169
132
target_repo_format = target_format.repository_format
171
self.open_repository()._format.check_conversion_target(
173
except errors.NoRepositoryPresent:
174
# No repo, no problem.
133
source_repo_format = self._format.repository_format
134
source_repo_format.check_conversion_target(target_repo_format)
178
137
def _check_supported(format, allow_unsupported,
294
253
# copied, and finally if we are copying up to a specific
295
254
# revision_id then we can use the pending-ancestry-result which
296
255
# does not require traversing all of history to describe it.
297
if (result_repo.user_url == result.user_url
298
and not require_stacking and
256
if (result_repo.bzrdir.root_transport.base ==
257
result.root_transport.base and not require_stacking and
299
258
revision_id is not None):
300
259
fetch_spec = graph.PendingAncestryResult(
301
260
[revision_id], local_repo)
388
347
for subdir in sorted(subdirs, reverse=True):
389
348
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:
401
351
def find_branches(transport):
402
352
"""Find all branches under a transport.
414
364
except errors.NoRepositoryPresent:
417
return False, ([], repository)
418
return True, (bzrdir.list_branches(), None)
420
for branches, repo in BzrDir.find_bzrdirs(transport,
367
return False, (None, repository)
369
branch = bzrdir.open_branch()
370
except errors.NotBranchError:
371
return True, (None, None)
373
return True, (branch, None)
375
for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
422
376
if repo is not None:
423
ret.extend(repo.find_branches())
424
if branches is not None:
377
branches.extend(repo.find_branches())
378
if branch is not None:
379
branches.append(branch)
428
382
def destroy_repository(self):
429
383
"""Destroy the repository in this BzrDir"""
430
384
raise NotImplementedError(self.destroy_repository)
432
def create_branch(self, name=None):
386
def create_branch(self):
433
387
"""Create a branch in this BzrDir.
435
:param name: Name of the colocated branch to create, None for
438
389
The bzrdir's format will control what branch format is created.
439
390
For more control see BranchFormatXX.create(a_bzrdir).
441
392
raise NotImplementedError(self.create_branch)
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
394
def destroy_branch(self):
395
"""Destroy the branch in this BzrDir"""
449
396
raise NotImplementedError(self.destroy_branch)
499
446
except errors.NoRepositoryPresent:
500
447
repository = None
502
if (found_bzrdir.user_url != self.user_url
503
and not repository.is_shared()):
449
if ((found_bzrdir.root_transport.base !=
450
self.root_transport.base) and not repository.is_shared()):
504
451
# Don't look higher, can't use a higher shared repo.
505
452
repository = None
621
568
: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()
632
570
pb = ui.ui_factory.nested_progress_bar()
634
572
# FIXME: bug 300001 -- the backup fails if the backup directory
635
573
# already exists, but it should instead either remove it or make
636
574
# a new backup directory.
576
# FIXME: bug 262450 -- the backup directory should have the same
577
# permissions as the .bzr directory (probably a bug in copy_tree)
638
578
old_path = self.root_transport.abspath('.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)
579
new_path = self.root_transport.abspath('backup.bzr')
580
pb.note('making backup of %s' % (old_path,))
581
pb.note(' to %s' % (new_path,))
582
self.root_transport.copy_tree('.bzr', 'backup.bzr')
642
583
return (old_path, new_path)
704
645
next_transport = found_bzrdir.root_transport.clone('..')
705
if (found_bzrdir.user_url == next_transport.base):
646
if (found_bzrdir.root_transport.base == next_transport.base):
706
647
# top of the file system
708
649
# find the next containing bzrdir
725
666
repository = found_bzrdir.open_repository()
726
667
except errors.NoRepositoryPresent:
727
668
return None, False
728
if found_bzrdir.user_url == self.user_url:
669
if found_bzrdir.root_transport.base == self.root_transport.base:
729
670
return repository, True
730
671
elif repository.is_shared():
731
672
return repository, True
737
678
raise errors.NoRepositoryPresent(self)
738
679
return found_repo
740
def get_branch_reference(self, name=None):
681
def get_branch_reference(self):
741
682
"""Return the referenced URL for the branch in this bzrdir.
743
:param name: Optional colocated branch name
744
684
:raises NotBranchError: If there is no Branch.
745
:raises NoColocatedBranchSupport: If a branch name was specified
746
but colocated branches are not supported.
747
685
:return: The URL the branch in this bzrdir references if it is a
748
686
reference branch, or None for regular branches.
751
raise errors.NoColocatedBranchSupport(self)
754
def get_branch_transport(self, branch_format, name=None):
690
def get_branch_transport(self, branch_format):
755
691
"""Get the transport for use by branch format in this BzrDir.
757
693
Note that bzr dirs that do not support format strings will raise
852
788
:param _transport: the transport this dir is based at.
854
790
self._format = _format
855
# these are also under the more standard names of
856
# control_transport and user_transport
857
791
self.transport = _transport.clone('.bzr')
858
792
self.root_transport = _transport
859
793
self._mode_check_done = False
862
def user_transport(self):
863
return self.root_transport
866
def control_transport(self):
867
return self.transport
869
795
def is_control_filename(self, filename):
870
796
"""True if filename is the name of a path which is reserved for bzrdir's.
945
871
BzrDir._check_supported(format, _unsupported)
946
872
return format.open(transport, _found=True)
948
def open_branch(self, name=None, unsupported=False,
949
ignore_fallbacks=False):
874
def open_branch(self, unsupported=False, ignore_fallbacks=False):
950
875
"""Open the branch object at this BzrDir if one is present.
952
877
If unsupported is True, then no longer supported branch formats can
999
924
raise errors.NotBranchError(path=url)
1000
925
a_transport = new_t
1002
def _get_tree_branch(self, name=None):
927
def _get_tree_branch(self):
1003
928
"""Return the branch and tree, if any, for this bzrdir.
1005
:param name: Name of colocated branch to open.
1007
930
Return None for tree if not present or inaccessible.
1008
931
Raise NotBranchError if no branch is present.
1009
932
:return: (tree, branch)
1012
935
tree = self.open_workingtree()
1013
936
except (errors.NoWorkingTree, errors.NotLocalUrl):
1015
branch = self.open_branch(name=name)
938
branch = self.open_branch()
1017
if name is not None:
1018
branch = self.open_branch(name=name)
1020
branch = tree.branch
1021
941
return tree, branch
1096
1016
raise NotImplementedError(self.open_workingtree)
1098
def has_branch(self, name=None):
1018
def has_branch(self):
1099
1019
"""Tell if this bzrdir contains a branch.
1101
1021
Note: if you're going to open the branch, you should just go ahead
1316
1236
def push_branch(self, source, revision_id=None, overwrite=False,
1317
remember=False, create_prefix=False):
1318
1238
"""Push the source branch into this BzrDir."""
1320
1240
# If we can open a branch, use its direct repository, otherwise see
1383
1303
self.create_hook(hooks.HookPoint('pre_open',
1384
1304
"Invoked before attempting to open a BzrDir with the transport "
1385
1305
"that the open will use.", (1, 14), None))
1386
self.create_hook(hooks.HookPoint('post_repo_init',
1387
"Invoked after a repository has been initialized. "
1388
"post_repo_init is called with a "
1389
"bzrlib.bzrdir.RepoInitHookParams.",
1392
1307
# install the default hooks
1393
1308
BzrDir.hooks = BzrDirHooks()
1396
class RepoInitHookParams(object):
1397
"""Object holding parameters passed to *_repo_init hooks.
1399
There are 4 fields that hooks may wish to access:
1401
:ivar repository: Repository created
1402
:ivar format: Repository format
1403
:ivar bzrdir: The bzrdir for the repository
1404
:ivar shared: The repository is shared
1407
def __init__(self, repository, format, a_bzrdir, shared):
1408
"""Create a group of RepoInitHook parameters.
1410
:param repository: Repository created
1411
:param format: Repository format
1412
:param bzrdir: The bzrdir for the repository
1413
:param shared: The repository is shared
1415
self.repository = repository
1416
self.format = format
1417
self.bzrdir = a_bzrdir
1418
self.shared = shared
1420
def __eq__(self, other):
1421
return self.__dict__ == other.__dict__
1425
return "<%s for %s>" % (self.__class__.__name__,
1428
return "<%s for %s>" % (self.__class__.__name__,
1432
1311
class BzrDirPreSplitOut(BzrDir):
1433
1312
"""A common class for the all-in-one formats."""
1473
1352
tree.clone(result)
1476
def create_branch(self, name=None):
1355
def create_branch(self):
1477
1356
"""See BzrDir.create_branch."""
1478
return self._format.get_branch_format().initialize(self, name=name)
1357
return self._format.get_branch_format().initialize(self)
1480
def destroy_branch(self, name=None):
1359
def destroy_branch(self):
1481
1360
"""See BzrDir.destroy_branch."""
1482
1361
raise errors.UnsupportedOperation(self.destroy_branch, self)
1506
1385
# that can do wonky stuff here, and that only
1507
1386
# happens for creating checkouts, which cannot be
1508
1387
# done on this format anyway. So - acceptable wart.
1510
warning("can't support hardlinked working trees in %r"
1513
1389
result = self.open_workingtree(recommend_upgrade=False)
1514
1390
except errors.NoSuchFile:
1539
1415
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1542
def get_branch_transport(self, branch_format, name=None):
1418
def get_branch_transport(self, branch_format):
1543
1419
"""See BzrDir.get_branch_transport()."""
1544
if name is not None:
1545
raise errors.NoColocatedBranchSupport(self)
1546
1420
if branch_format is None:
1547
1421
return self.transport
1581
1455
format = BzrDirFormat.get_default_format()
1582
1456
return not isinstance(self._format, format.__class__)
1584
def open_branch(self, name=None, unsupported=False,
1585
ignore_fallbacks=False):
1458
def open_branch(self, unsupported=False, ignore_fallbacks=False):
1586
1459
"""See BzrDir.open_branch."""
1587
1460
from bzrlib.branch import BzrBranchFormat4
1588
1461
format = BzrBranchFormat4()
1589
1462
self._check_supported(format, unsupported)
1590
return format.open(self, name, _found=True)
1463
return format.open(self, _found=True)
1592
1465
def sprout(self, url, revision_id=None, force_new_repo=False,
1593
1466
possible_transports=None, accelerator_tree=None,
1654
1527
This is a deprecated format and may be removed after sept 2006.
1657
def has_workingtree(self):
1658
"""See BzrDir.has_workingtree."""
1661
1530
def open_repository(self):
1662
1531
"""See BzrDir.open_repository."""
1663
1532
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1679
1548
This is a deprecated format and may be removed after sept 2006.
1682
def has_workingtree(self):
1683
"""See BzrDir.has_workingtree."""
1686
1551
def open_repository(self):
1687
1552
"""See BzrDir.open_repository."""
1688
1553
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1710
1575
"""See BzrDir.can_convert_format()."""
1713
def create_branch(self, name=None):
1578
def create_branch(self):
1714
1579
"""See BzrDir.create_branch."""
1715
return self._format.get_branch_format().initialize(self, name=name)
1580
return self._format.get_branch_format().initialize(self)
1717
def destroy_branch(self, name=None):
1582
def destroy_branch(self):
1718
1583
"""See BzrDir.create_branch."""
1719
if name is not None:
1720
raise errors.NoColocatedBranchSupport(self)
1721
1584
self.transport.delete_tree('branch')
1723
1586
def create_repository(self, shared=False):
1746
1609
def destroy_workingtree_metadata(self):
1747
1610
self.transport.delete_tree('checkout')
1749
def find_branch_format(self, name=None):
1612
def find_branch_format(self):
1750
1613
"""Find the branch 'format' for this bzrdir.
1752
1615
This might be a synthetic object for e.g. RemoteBranch and SVN.
1754
1617
from bzrlib.branch import BranchFormat
1755
return BranchFormat.find_format(self, name=name)
1618
return BranchFormat.find_format(self)
1757
1620
def _get_mkdir_mode(self):
1758
1621
"""Figure out the mode to use when creating a bzrdir subdir."""
1760
1623
lockable_files.TransportLock)
1761
1624
return temp_control._dir_mode
1763
def get_branch_reference(self, name=None):
1626
def get_branch_reference(self):
1764
1627
"""See BzrDir.get_branch_reference()."""
1765
1628
from bzrlib.branch import BranchFormat
1766
format = BranchFormat.find_format(self, name=name)
1767
return format.get_reference(self, name=name)
1629
format = BranchFormat.find_format(self)
1630
return format.get_reference(self)
1769
def get_branch_transport(self, branch_format, name=None):
1632
def get_branch_transport(self, branch_format):
1770
1633
"""See BzrDir.get_branch_transport()."""
1771
if name is not None:
1772
raise errors.NoColocatedBranchSupport(self)
1773
# XXX: this shouldn't implicitly create the directory if it's just
1774
# promising to get a transport -- mbp 20090727
1775
1634
if branch_format is None:
1776
1635
return self.transport.clone('branch')
1813
1672
return self.transport.clone('checkout')
1815
def has_workingtree(self):
1816
"""Tell if this bzrdir contains a working tree.
1818
This will still raise an exception if the bzrdir has a workingtree that
1819
is remote & inaccessible.
1821
Note: if you're going to open the working tree, you should just go
1822
ahead and try, and not ask permission first.
1824
from bzrlib.workingtree import WorkingTreeFormat
1826
WorkingTreeFormat.find_format(self)
1827
except errors.NoWorkingTree:
1831
1674
def needs_format_conversion(self, format=None):
1832
1675
"""See BzrDir.needs_format_conversion()."""
1833
1676
if format is None:
1847
1690
except errors.NoRepositoryPresent:
1849
for branch in self.list_branches():
1850
if not isinstance(branch._format,
1693
if not isinstance(self.open_branch()._format,
1851
1694
format.get_branch_format().__class__):
1852
1695
# the branch needs an upgrade.
1697
except errors.NotBranchError:
1855
1700
my_wt = self.open_workingtree(recommend_upgrade=False)
1856
1701
if not isinstance(my_wt._format,
1864
def open_branch(self, name=None, unsupported=False,
1865
ignore_fallbacks=False):
1709
def open_branch(self, unsupported=False, ignore_fallbacks=False):
1866
1710
"""See BzrDir.open_branch."""
1867
format = self.find_branch_format(name=name)
1711
format = self.find_branch_format()
1868
1712
self._check_supported(format, unsupported)
1869
return format.open(self, name=name,
1870
_found=True, ignore_fallbacks=ignore_fallbacks)
1713
return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
1872
1715
def open_repository(self, unsupported=False):
1873
1716
"""See BzrDir.open_repository."""
1905
1748
Once a format is deprecated, just deprecate the initialize and open
1906
1749
methods on the format class. Do not deprecate the object, as the
1907
1750
object will be created every system load.
1909
:cvar colocated_branches: Whether this formats supports colocated branches.
1912
1753
_default_format = None
1930
1771
_lock_file_name = 'branch-lock'
1932
colocated_branches = False
1933
"""Whether co-located branches are supported for this control dir format.
1936
1773
# _lock_class must be set in subclasses to the lock type, typ.
1937
1774
# TransportLock or LockDir
1955
1792
def probe_transport(klass, transport):
1956
1793
"""Return the .bzrdir style format present in a directory."""
1958
format_string = transport.get_bytes(".bzr/branch-format")
1795
format_string = transport.get(".bzr/branch-format").read()
1959
1796
except errors.NoSuchFile:
1960
1797
raise errors.NotBranchError(path=transport.base)
2521
2358
def set_branch_format(self, format):
2522
2359
self._branch_format = format
2524
def require_stacking(self, stack_on=None, possible_transports=None,
2361
def require_stacking(self, stack_on=None, possible_transports=None):
2526
2362
"""We have a request to stack, try to ensure the formats support it.
2528
2364
:param stack_on: If supplied, it is the URL to a branch that we want to
2566
2402
target[:] = [target_branch, True, False]
2569
if (not _skip_repo and
2570
not self.repository_format.supports_external_lookups):
2405
if not (self.repository_format.supports_external_lookups):
2571
2406
# We need to upgrade the Repository.
2572
2407
target_branch, _, do_upgrade = get_target_branch()
2573
2408
if target_branch is None:
2737
2572
def convert(self, to_convert, pb):
2738
2573
"""See Converter.convert()."""
2739
2574
self.bzrdir = to_convert
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)
2576
self.pb.note('starting upgrade from format 4 to 5')
2577
if isinstance(self.bzrdir.transport, local.LocalTransport):
2578
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2579
self._convert_to_weaves()
2580
return BzrDir.open(self.bzrdir.root_transport.base)
2752
2582
def _convert_to_weaves(self):
2753
ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2583
self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
2755
2585
# TODO permissions
2756
2586
stat = self.bzrdir.transport.stat('weaves')
2784
2614
self.pb.clear()
2785
2615
self._write_all_weaves()
2786
2616
self._write_all_revs()
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)
2617
self.pb.note('upgraded to weaves:')
2618
self.pb.note(' %6d revisions and inventories', len(self.revisions))
2619
self.pb.note(' %6d revisions not present', len(self.absent_revisions))
2620
self.pb.note(' %6d texts', self.text_count)
2791
2621
self._cleanup_spare_files_after_format4()
2792
2622
self.branch._transport.put_bytes(
2793
2623
'branch-format',
2861
2691
len(self.known_revisions))
2862
2692
if not self.branch.repository.has_revision(rev_id):
2863
2693
self.pb.clear()
2864
ui.ui_factory.note('revision {%s} not present in branch; '
2865
'will be converted as a ghost' %
2694
self.pb.note('revision {%s} not present in branch; '
2695
'will be converted as a ghost',
2867
2697
self.absent_revisions.add(rev_id)
2994
2824
def convert(self, to_convert, pb):
2995
2825
"""See Converter.convert()."""
2996
2826
self.bzrdir = to_convert
2997
pb = ui.ui_factory.nested_progress_bar()
2999
ui.ui_factory.note('starting upgrade from format 5 to 6')
3000
self._convert_to_prefixed()
3001
return BzrDir.open(self.bzrdir.user_url)
2828
self.pb.note('starting upgrade from format 5 to 6')
2829
self._convert_to_prefixed()
2830
return BzrDir.open(self.bzrdir.root_transport.base)
3005
2832
def _convert_to_prefixed(self):
3006
2833
from bzrlib.store import TransportStore
3007
2834
self.bzrdir.transport.delete('branch-format')
3008
2835
for store_name in ["weaves", "revision-store"]:
3009
ui.ui_factory.note("adding prefixes to %s" % store_name)
2836
self.pb.note("adding prefixes to %s" % store_name)
3010
2837
store_transport = self.bzrdir.transport.clone(store_name)
3011
2838
store = TransportStore(store_transport, prefixed=True)
3012
2839
for urlfilename in store_transport.list_dir('.'):
3039
2866
from bzrlib.repofmt.weaverepo import RepositoryFormat7
3040
2867
from bzrlib.branch import BzrBranchFormat5
3041
2868
self.bzrdir = to_convert
3042
self.pb = ui.ui_factory.nested_progress_bar()
3044
2871
self.total = 20 # the steps we know about
3045
2872
self.garbage_inventories = []
3046
2873
self.dir_mode = self.bzrdir._get_dir_mode()
3047
2874
self.file_mode = self.bzrdir._get_file_mode()
3049
ui.ui_factory.note('starting upgrade from format 6 to metadir')
2876
self.pb.note('starting upgrade from format 6 to metadir')
3050
2877
self.bzrdir.transport.put_bytes(
3051
2878
'branch-format',
3052
2879
"Converting to format 6",
3103
2930
has_checkout = True
3104
2931
if not has_checkout:
3105
ui.ui_factory.note('No working tree.')
2932
self.pb.note('No working tree.')
3106
2933
# If some checkout files are there, we may as well get rid of them.
3107
2934
for name, mandatory in checkout_files:
3108
2935
if name in bzrcontents:
3125
2952
'branch-format',
3126
2953
BzrDirMetaFormat1().get_format_string(),
3127
2954
mode=self.file_mode)
3129
return BzrDir.open(self.bzrdir.user_url)
2955
return BzrDir.open(self.bzrdir.root_transport.base)
3131
2957
def make_lock(self, name):
3132
2958
"""Make a lock for the new control dir name."""
3167
2993
def convert(self, to_convert, pb):
3168
2994
"""See Converter.convert()."""
3169
2995
self.bzrdir = to_convert
3170
self.pb = ui.ui_factory.nested_progress_bar()
3173
2999
self.step('checking repository format')
3179
3005
if not isinstance(repo._format, self.target_format.repository_format.__class__):
3180
3006
from bzrlib.repository import CopyConverter
3181
ui.ui_factory.note('starting repository conversion')
3007
self.pb.note('starting repository conversion')
3182
3008
converter = CopyConverter(self.target_format.repository_format)
3183
3009
converter.convert(repo, pb)
3184
for branch in self.bzrdir.list_branches():
3011
branch = self.bzrdir.open_branch()
3012
except errors.NotBranchError:
3185
3015
# TODO: conversions of Branch and Tree should be done by
3186
3016
# InterXFormat lookups/some sort of registry.
3187
3017
# Avoid circular imports
3202
3032
new is _mod_branch.BzrBranchFormat8):
3203
3033
branch_converter = _mod_branch.Converter7to8()
3205
raise errors.BadConversionTarget("No converter", new,
3035
raise errors.BadConversionTarget("No converter", new)
3207
3036
branch_converter.convert(branch)
3208
3037
branch = self.bzrdir.open_branch()
3209
3038
old = branch._format.__class__
3243
3071
def __init__(self):
3244
3072
BzrDirMetaFormat1.__init__(self)
3245
# XXX: It's a bit ugly that the network name is here, because we'd
3246
# like to believe that format objects are stateless or at least
3247
# immutable, However, we do at least avoid mutating the name after
3248
# it's returned. See <https://bugs.edge.launchpad.net/bzr/+bug/504102>
3249
3073
self._network_name = None
3252
return "%s(_network_name=%r)" % (self.__class__.__name__,
3255
3075
def get_format_description(self):
3256
if self._network_name:
3257
real_format = network_format_registry.get(self._network_name)
3258
return 'Remote: ' + real_format.get_format_description()
3259
3076
return 'bzr remote bzrdir'
3261
3078
def get_format_string(self):
3359
3176
client = _SmartClient(client_medium)
3360
3177
path = client.remote_path_from_transport(transport)
3361
if client_medium._is_remote_before((1, 16)):
3178
if client_medium._is_remote_before((1, 15)):
3364
3181
# TODO: lookup the local format from a server hint.
3394
3211
args.append(self._serialize_NoneString(repo_format_name))
3395
3212
args.append(self._serialize_NoneTrueFalse(make_working_trees))
3396
3213
args.append(self._serialize_NoneTrueFalse(shared_repo))
3397
request_network_name = self._network_name or \
3214
if self._network_name is None:
3215
self._network_name = \
3398
3216
BzrDirFormat.get_default_format().network_name()
3400
response = client.call('BzrDirFormat.initialize_ex_1.16',
3401
request_network_name, path, *args)
3218
response = client.call('BzrDirFormat.initialize_ex',
3219
self.network_name(), path, *args)
3402
3220
except errors.UnknownSmartMethod:
3403
client._medium._remember_remote_is_before((1,16))
3404
3221
local_dir_format = BzrDirMetaFormat1()
3405
3222
self._supply_sub_formats_to(local_dir_format)
3406
3223
return local_dir_format.initialize_on_transport_ex(transport,
3432
3249
repo_bzr = bzrdir
3433
3250
final_stack = response[8] or None
3434
3251
final_stack_pwd = response[9] or None
3436
final_stack_pwd = urlutils.join(
3437
transport.base, final_stack_pwd)
3438
3252
remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
3439
3253
if len(response) > 10:
3440
3254
# Updated server verb that locks remotely.
3451
3265
remote_repo = None
3453
bzrdir._format.set_branch_format(self.get_branch_format())
3454
if require_stacking:
3455
# The repo has already been created, but we need to make sure that
3456
# we'll make a stackable branch.
3457
bzrdir._format.require_stacking(_skip_repo=True)
3458
3267
return remote_repo, bzrdir, require_stacking, policy
3460
3269
def _open(self, transport):
3636
3445
if info.native:
3637
3446
help = '(native) ' + help
3638
3447
return ':%s:\n%s\n\n' % (key,
3639
textwrap.fill(help, initial_indent=' ',
3640
subsequent_indent=' ',
3641
break_long_words=False))
3448
textwrap.fill(help, initial_indent=' ',
3449
subsequent_indent=' '))
3642
3450
if default_realkey is not None:
3643
3451
output += wrapped(default_realkey, '(default) %s' % default_help,
3644
3452
self.get_info('default'))
3654
3462
experimental_pairs.append((key, help))
3656
3464
output += wrapped(key, help, info)
3657
output += "\nSee :doc:`formats-help` for more about storage formats."
3465
output += "\nSee ``bzr help formats`` for more about storage formats."
3658
3466
other_output = ""
3659
3467
if len(experimental_pairs) > 0:
3660
3468
other_output += "Experimental formats are shown below.\n\n"
3714
3522
stack_on = urlutils.rebase_url(self._stack_on,
3715
3523
self._stack_on_pwd,
3524
branch.bzrdir.root_transport.base)
3717
3525
except errors.InvalidRebaseURLs:
3718
3526
stack_on = self._get_full_stack_on()
3723
3531
if self._require_stacking:
3726
def requires_stacking(self):
3727
"""Return True if this policy requires stacking."""
3728
return self._stack_on is not None and self._require_stacking
3730
3534
def _get_full_stack_on(self):
3731
3535
"""Get a fully-qualified URL for the stack_on location."""
3732
3536
if self._stack_on is None:
3848
3652
format_registry.register('weave', BzrDirFormat6,
3849
3653
'Pre-0.8 format. Slower than knit and does not'
3850
3654
' support checkouts or shared repositories.',
3852
3655
deprecated=True)
3853
3656
format_registry.register_metadir('metaweave',
3854
3657
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3855
3658
'Transitional format in 0.8. Slower than knit.',
3856
3659
branch_format='bzrlib.branch.BzrBranchFormat5',
3857
3660
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3859
3661
deprecated=True)
3860
3662
format_registry.register_metadir('knit',
3861
3663
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3862
3664
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
3863
3665
branch_format='bzrlib.branch.BzrBranchFormat5',
3864
3666
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3866
3667
deprecated=True)
3867
3668
format_registry.register_metadir('dirstate',
3868
3669
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3872
3673
# this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
3873
3674
# directly from workingtree_4 triggers a circular import.
3874
3675
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3876
3676
deprecated=True)
3877
3677
format_registry.register_metadir('dirstate-tags',
3878
3678
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3881
3681
' Incompatible with bzr < 0.15.',
3882
3682
branch_format='bzrlib.branch.BzrBranchFormat6',
3883
3683
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3885
3684
deprecated=True)
3886
3685
format_registry.register_metadir('rich-root',
3887
3686
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3890
3689
branch_format='bzrlib.branch.BzrBranchFormat6',
3891
3690
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3893
3691
deprecated=True)
3894
3692
format_registry.register_metadir('dirstate-with-subtree',
3895
3693
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3906
3704
help='New in 0.92: Pack-based format with data compatible with '
3907
3705
'dirstate-tags format repositories. Interoperates with '
3908
3706
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3707
'Previously called knitpack-experimental. '
3708
'For more information, see '
3709
'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3910
3710
branch_format='bzrlib.branch.BzrBranchFormat6',
3911
3711
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3915
3715
help='New in 0.92: Pack-based format with data compatible with '
3916
3716
'dirstate-with-subtree format repositories. Interoperates with '
3917
3717
'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.',
3919
3721
branch_format='bzrlib.branch.BzrBranchFormat6',
3920
3722
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3927
3729
'(needed for bzr-svn and bzr-git).',
3928
3730
branch_format='bzrlib.branch.BzrBranchFormat6',
3929
3731
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3932
3733
format_registry.register_metadir('1.6',
3933
3734
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3936
3737
'not present locally.',
3937
3738
branch_format='bzrlib.branch.BzrBranchFormat7',
3938
3739
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3941
3741
format_registry.register_metadir('1.6.1-rich-root',
3942
3742
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3944
3744
'(needed for bzr-svn and bzr-git).',
3945
3745
branch_format='bzrlib.branch.BzrBranchFormat7',
3946
3746
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3949
3748
format_registry.register_metadir('1.9',
3950
3749
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3953
3752
'performance for most operations.',
3954
3753
branch_format='bzrlib.branch.BzrBranchFormat7',
3955
3754
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3958
3756
format_registry.register_metadir('1.9-rich-root',
3959
3757
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3961
3759
'(needed for bzr-svn and bzr-git).',
3962
3760
branch_format='bzrlib.branch.BzrBranchFormat7',
3963
3761
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3966
3763
format_registry.register_metadir('1.14',
3967
3764
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3983
3780
'to and from rich-root-pack (and anything compatible with '
3984
3781
'rich-root-pack) format repositories. Repositories and branches in '
3985
3782
'this format can only be read by bzr.dev. Please read '
3986
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3783
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3988
3785
branch_format='bzrlib.branch.BzrBranchFormat7',
3989
3786
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3990
3787
experimental=True,
3994
3790
format_registry.register_metadir('development-subtree',
3995
3791
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3997
3793
'from pack-0.92-subtree (and anything compatible with '
3998
3794
'pack-0.92-subtree) format repositories. Repositories and branches in '
3999
3795
'this format can only be read by bzr.dev. Please read '
4000
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3796
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
4002
3798
branch_format='bzrlib.branch.BzrBranchFormat7',
4003
3799
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
4004
3800
experimental=True,
4006
3801
alias=False, # Restore to being an alias when an actual development subtree format is added
4007
3802
# This current non-alias status is simply because we did not introduce a
4008
3803
# chk based subtree format.
4013
3808
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
4014
3809
help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
4016
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3811
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
4018
3813
branch_format='bzrlib.branch.BzrBranchFormat7',
4019
3814
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
4025
3820
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
4026
3821
help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
4027
3822
'rich roots. Please read '
4028
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3823
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
4030
3825
branch_format='bzrlib.branch.BzrBranchFormat7',
4031
3826
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
4033
3828
experimental=True,
4036
format_registry.register_metadir('2a',
4037
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
4038
help='First format for bzr 2.0 series.\n'
4039
'Uses group-compress storage.\n'
4040
'Provides rich roots which are a one-way transition.\n',
4041
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
4042
# 'rich roots. Supported by bzr 1.16 and later.',
4043
branch_format='bzrlib.branch.BzrBranchFormat7',
4044
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
4048
3831
# The following format should be an alias for the rich root equivalent
4049
3832
# of the default format
4050
3833
format_registry.register_metadir('default-rich-root',
4051
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
4052
branch_format='bzrlib.branch.BzrBranchFormat7',
4053
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3834
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3835
help='Default format, rich root variant. (needed for bzr-svn and bzr-git).',
3836
branch_format='bzrlib.branch.BzrBranchFormat6',
3837
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
4058
3840
# The current format that is made on 'bzr init'.
4059
format_registry.set_default('2a')
3841
format_registry.set_default('pack-0.92')