130
131
"""Give an error or warning on old formats.
132
:param format: may be any kind of format - workingtree, branch,
133
:param format: may be any kind of format - workingtree, branch,
135
:param allow_unsupported: If true, allow opening
136
formats that are strongly deprecated, and which may
136
:param allow_unsupported: If true, allow opening
137
formats that are strongly deprecated, and which may
137
138
have limited functionality.
139
140
:param recommend_upgrade: If true (default), warn
188
189
transport.ensure_base()
189
190
require_stacking = (stacked_on is not None)
190
metadir = self.cloning_metadir(require_stacking)
191
result = metadir.initialize_on_transport(transport)
191
format = self.cloning_metadir(require_stacking)
192
result = format.initialize_on_transport(transport)
192
193
repository_policy = None
194
195
local_repo = self.find_repository()
231
232
result_branch = local_branch.clone(result, revision_id=revision_id)
232
233
if repository_policy is not None:
233
234
repository_policy.configure_branch(result_branch)
234
if result_repo is None or result_repo.make_working_trees():
236
# Cheaper to check if the target is not local, than to try making
238
result.root_transport.local_abspath('.')
239
if result_repo is None or result_repo.make_working_trees():
236
240
self.open_workingtree().clone(result)
237
except (errors.NoWorkingTree, errors.NotLocalUrl):
241
except (errors.NoWorkingTree, errors.NotLocalUrl):
241
245
# TODO: This should be given a Transport, and should chdir up; otherwise
248
252
def create(cls, base, format=None, possible_transports=None):
249
253
"""Create a new BzrDir at the url 'base'.
251
255
:param format: If supplied, the format of branch to create. If not
252
256
supplied, the default is used.
253
:param possible_transports: If supplied, a list of transports that
257
:param possible_transports: If supplied, a list of transports that
254
258
can be reused to share a remote connection.
256
260
if cls is not BzrDir:
356
360
"""Create a new BzrDir, Branch and Repository at the url 'base'.
358
362
This will use the current default BzrDirFormat unless one is
359
specified, and use whatever
363
specified, and use whatever
360
364
repository format that that uses via bzrdir.create_branch and
361
365
create_repository. If a shared repository is available that is used
452
456
This will use the current default BzrDirFormat unless one is
453
specified, and use whatever
457
specified, and use whatever
454
458
repository format that that uses via bzrdir.create_branch and
455
459
create_repository. If a shared repository is available that is used
456
460
preferentially. Whatever repository is used, its tree creation policy
459
463
The created Branch object is returned.
460
464
If a working tree cannot be made due to base not being a file:// url,
461
no error is raised unless force_new_tree is True, in which case no
465
no error is raised unless force_new_tree is True, in which case no
462
466
data is created on disk and NotLocalUrl is raised.
464
468
:param base: The URL to create the branch at.
465
469
:param force_new_repo: If True a new repository is always created.
466
:param force_new_tree: If True or False force creation of a tree or
470
:param force_new_tree: If True or False force creation of a tree or
467
471
prevent such creation respectively.
468
472
:param format: Override for the bzrdir format to create.
469
473
:param possible_transports: An optional reusable transports list.
491
495
'base' must be a local path or a file:// url.
493
497
This will use the current default BzrDirFormat unless one is
494
specified, and use whatever
498
specified, and use whatever
495
499
repository format that that uses for bzrdirformat.create_workingtree,
496
500
create_branch and create_repository.
509
513
def create_workingtree(self, revision_id=None, from_branch=None,
510
514
accelerator_tree=None, hardlink=False):
511
515
"""Create a working tree at this BzrDir.
513
517
:param revision_id: create it as of this revision id.
514
518
:param from_branch: override bzrdir branch (for lightweight checkouts)
515
519
:param accelerator_tree: A tree which can be used for retrieving file
530
534
# already exists, but it should instead either remove it or make
531
535
# a new backup directory.
533
# FIXME: bug 262450 -- the backup directory should have the same
537
# FIXME: bug 262450 -- the backup directory should have the same
534
538
# permissions as the .bzr directory (probably a bug in copy_tree)
535
539
old_path = self.root_transport.abspath('.bzr')
536
540
new_path = self.root_transport.abspath('backup.bzr')
651
655
IncompatibleFormat if the branch format they are given has
652
656
a format string, and vice versa.
654
If branch_format is None, the transport is returned with no
658
If branch_format is None, the transport is returned with no
655
659
checking. If it is not None, then the returned transport is
656
660
guaranteed to point to an existing directory ready for use.
708
712
IncompatibleFormat if the repository format they are given has
709
713
a format string, and vice versa.
711
If repository_format is None, the transport is returned with no
715
If repository_format is None, the transport is returned with no
712
716
checking. If it is not None, then the returned transport is
713
717
guaranteed to point to an existing directory ready for use.
715
719
raise NotImplementedError(self.get_repository_transport)
717
721
def get_workingtree_transport(self, tree_format):
718
722
"""Get the transport for use by workingtree format in this BzrDir.
721
725
IncompatibleFormat if the workingtree format they are given has a
722
726
format string, and vice versa.
724
If workingtree_format is None, the transport is returned with no
728
If workingtree_format is None, the transport is returned with no
725
729
checking. If it is not None, then the returned transport is
726
730
guaranteed to point to an existing directory ready for use.
735
739
def __init__(self, _transport, _format):
736
740
"""Initialize a Bzr control dir object.
738
742
Only really common logic should reside here, concrete classes should be
739
743
made with varying behaviours.
757
761
this in the future - for instance to make bzr talk with svn working
760
# this might be better on the BzrDirFormat class because it refers to
761
# all the possible bzrdir disk formats.
762
# This method is tested via the workingtree is_control_filename tests-
764
# this might be better on the BzrDirFormat class because it refers to
765
# all the possible bzrdir disk formats.
766
# This method is tested via the workingtree is_control_filename tests-
763
767
# it was extracted from WorkingTree.is_control_filename. If the method's
764
768
# contract is extended beyond the current trivial implementation, please
765
769
# add new tests for it to the appropriate place.
768
772
def needs_format_conversion(self, format=None):
769
773
"""Return true if this bzrdir needs convert_format run on it.
771
For instance, if the repository format is out of date but the
775
For instance, if the repository format is out of date but the
772
776
branch and working tree are not, this should return True.
774
778
:param format: Optional parameter indicating a specific desired
780
784
def open_unsupported(base):
781
785
"""Open a branch which is not supported."""
782
786
return BzrDir.open(base, _unsupported=True)
785
789
def open(base, _unsupported=False, possible_transports=None):
786
790
"""Open an existing bzrdir, rooted at 'base' (url).
788
792
:param _unsupported: a private parameter to the BzrDir class.
790
794
t = get_transport(base, possible_transports=possible_transports)
837
841
def open_containing(url, possible_transports=None):
838
842
"""Open an existing branch which contains url.
840
844
:param url: url to search from.
841
845
See open_containing_from_transport for more detail.
843
847
transport = get_transport(url, possible_transports)
844
848
return BzrDir.open_containing_from_transport(transport)
847
851
def open_containing_from_transport(a_transport):
848
852
"""Open an existing branch which contains a_transport.base.
852
856
Basically we keep looking up until we find the control directory or
853
857
run into the root. If there isn't one, raises NotBranchError.
854
If there is one and it is either an unrecognised format or an unsupported
858
If there is one and it is either an unrecognised format or an unsupported
855
859
format, UnknownFormatError or UnsupportedFormatError are raised.
856
860
If there is one, it is returned, along with the unused portion of url.
858
:return: The BzrDir that contains the path, and a Unicode path
862
:return: The BzrDir that contains the path, and a Unicode path
859
863
for the rest of the URL.
861
865
# this gets the normalised url back. I.e. '.' -> the full path.
970
974
def has_branch(self):
971
975
"""Tell if this bzrdir contains a branch.
973
977
Note: if you're going to open the branch, you should just go ahead
974
and try, and not ask permission first. (This method just opens the
975
branch and discards it, and that's somewhat expensive.)
978
and try, and not ask permission first. (This method just opens the
979
branch and discards it, and that's somewhat expensive.)
978
982
self.open_branch()
986
990
This will still raise an exception if the bzrdir has a workingtree that
987
991
is remote & inaccessible.
989
993
Note: if you're going to open the working tree, you should just go ahead
990
and try, and not ask permission first. (This method just opens the
991
workingtree and discards it, and that's somewhat expensive.)
994
and try, and not ask permission first. (This method just opens the
995
workingtree and discards it, and that's somewhat expensive.)
994
998
self.open_workingtree(recommend_upgrade=False)
1257
1261
# and that will have set it for us, its only
1258
1262
# specific uses of create_workingtree in isolation
1259
1263
# that can do wonky stuff here, and that only
1260
# happens for creating checkouts, which cannot be
1264
# happens for creating checkouts, which cannot be
1261
1265
# done on this format anyway. So - acceptable wart.
1263
1267
result = self.open_workingtree(recommend_upgrade=False)
1287
1291
def destroy_workingtree_metadata(self):
1288
1292
"""See BzrDir.destroy_workingtree_metadata."""
1289
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1293
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1292
1296
def get_branch_transport(self, branch_format):
1432
1436
class BzrDirMeta1(BzrDir):
1433
1437
"""A .bzr meta version 1 control object.
1435
This is the first control object where the
1439
This is the first control object where the
1436
1440
individual aspects are really split out: there are separate repository,
1437
1441
workingtree and branch subdirectories and any subset of the three can be
1438
1442
present within a BzrDir.
1608
1612
* a format string,
1609
1613
* an open routine.
1611
Formats are placed in a dict by their format string for reference
1615
Formats are placed in a dict by their format string for reference
1612
1616
during bzrdir opening. These should be subclasses of BzrDirFormat
1613
1617
for consistency.
1615
1619
Once a format is deprecated, just deprecate the initialize and open
1616
methods on the format class. Do not deprecate the object, as the
1620
methods on the format class. Do not deprecate the object, as the
1617
1621
object will be created every system load.
1690
1694
current default format. In the case of plugins we can/should provide
1691
1695
some means for them to extend the range of returnable converters.
1693
:param format: Optional format to override the default format of the
1697
:param format: Optional format to override the default format of the
1696
1700
raise NotImplementedError(self.get_converter)
1698
1702
def initialize(self, url, possible_transports=None):
1699
1703
"""Create a bzr control dir at this url and return an opened copy.
1701
1705
Subclasses should typically override initialize_on_transport
1702
1706
instead of this method.
1707
1711
def initialize_on_transport(self, transport):
1708
1712
"""Initialize a new bzrdir in the base directory of a Transport."""
1709
# Since we don't have a .bzr directory, inherit the
1714
# can we hand off the request to the smart server rather than using
1716
client_medium = transport.get_smart_medium()
1717
except errors.NoSmartMedium:
1718
return self._initialize_on_transport_vfs(transport)
1720
# Current RPC's only know how to create bzr metadir1 instances, so
1721
# we still delegate to vfs methods if the requested format is not a
1723
if type(self) != BzrDirMetaFormat1:
1724
return self._initialize_on_transport_vfs(transport)
1725
remote_format = RemoteBzrDirFormat()
1726
self._supply_sub_formats_to(remote_format)
1727
return remote_format.initialize_on_transport(transport)
1729
def _initialize_on_transport_vfs(self, transport):
1730
"""Initialize a new bzrdir using VFS calls.
1732
:param transport: The transport to create the .bzr directory in.
1735
# Since we are creating a .bzr directory, inherit the
1710
1736
# mode from the root directory
1711
1737
temp_control = lockable_files.LockableFiles(transport,
1712
1738
'', lockable_files.TransportLock)
1742
1768
"""Is this format supported?
1744
1770
Supported formats must be initializable and openable.
1745
Unsupported formats may not support initialization or committing or
1771
Unsupported formats may not support initialization or committing or
1746
1772
some other features depending on the reason for not being supported.
1750
1776
def same_model(self, target_format):
1751
return (self.repository_format.rich_root_data ==
1777
return (self.repository_format.rich_root_data ==
1752
1778
target_format.rich_root_data)
1755
1781
def known_formats(klass):
1756
1782
"""Return all the known formats.
1758
1784
Concrete formats should override _known_formats.
1760
# There is double indirection here to make sure that control
1761
# formats used by more than one dir format will only be probed
1786
# There is double indirection here to make sure that control
1787
# formats used by more than one dir format will only be probed
1762
1788
# once. This can otherwise be quite expensive for remote connections.
1764
1790
for format in klass._control_formats:
1765
1791
result.update(format._known_formats())
1769
1795
def _known_formats(klass):
1770
1796
"""Return the known format instances for this control format."""
1773
1799
def open(self, transport, _found=False):
1774
1800
"""Return an instance of this format for the dir transport points at.
1776
1802
_found is a private parameter, do not use it.
1779
1805
found_format = BzrDirFormat.find_format(transport)
1780
1806
if not isinstance(found_format, self.__class__):
1781
1807
raise AssertionError("%s was asked to open %s, but it seems to need "
1783
1809
% (self, transport, found_format))
1810
# Allow subclasses - use the found format.
1811
self._supply_sub_formats_to(found_format)
1812
return found_format._open(transport)
1784
1813
return self._open(transport)
1786
1815
def _open(self, transport):
1800
1829
"""Register a format that does not use '.bzr' for its control dir.
1802
1831
TODO: This should be pulled up into a 'ControlDirFormat' base class
1803
which BzrDirFormat can inherit from, and renamed to register_format
1832
which BzrDirFormat can inherit from, and renamed to register_format
1804
1833
there. It has been done without that for now for simplicity of
1805
1834
implementation.
1825
1854
def __str__(self):
1826
1855
# Trim the newline
1827
return self.get_format_string().rstrip()
1856
return self.get_format_description().rstrip()
1858
def _supply_sub_formats_to(self, other_format):
1859
"""Give other_format the same values for sub formats as this has.
1861
This method is expected to be used when parameterising a
1862
RemoteBzrDirFormat instance with the parameters from a
1863
BzrDirMetaFormat1 instance.
1865
:param other_format: other_format is a format which should be
1866
compatible with whatever sub formats are supported by self.
1830
1871
def unregister_format(klass, format):
1862
1903
"""See BzrDirFormat.get_converter()."""
1863
1904
# there is one and only one upgrade path here.
1864
1905
return ConvertBzrDir4To5()
1866
1907
def initialize_on_transport(self, transport):
1867
1908
"""Format 4 branches cannot be created."""
1868
1909
raise errors.UninitializableFormat(self)
1893
1934
This format is a combined format for working tree, branch and repository.
1895
- Format 2 working trees [always]
1896
- Format 4 branches [always]
1936
- Format 2 working trees [always]
1937
- Format 4 branches [always]
1897
1938
- Format 5 repositories [always]
1898
1939
Unhashed stores in the repository.
1920
1961
def _initialize_for_clone(self, url):
1921
1962
return self.initialize_on_transport(get_transport(url), _cloning=True)
1923
1964
def initialize_on_transport(self, transport, _cloning=False):
1924
1965
"""Format 5 dirs always have working tree, branch and repository.
1926
1967
Except when they are being cloned.
1928
1969
from bzrlib.branch import BzrBranchFormat4
1951
1992
This format is a combined format for working tree, branch and repository.
1953
- Format 2 working trees [always]
1954
- Format 4 branches [always]
1994
- Format 2 working trees [always]
1995
- Format 4 branches [always]
1955
1996
- Format 6 repositories [always]
1973
2014
"""See BzrDirFormat.get_converter()."""
1974
2015
# there is one and only one upgrade path here.
1975
2016
return ConvertBzrDir6ToMeta()
1977
2018
def _initialize_for_clone(self, url):
1978
2019
return self.initialize_on_transport(get_transport(url), _cloning=True)
1980
2021
def initialize_on_transport(self, transport, _cloning=False):
1981
2022
"""Format 6 dirs always have working tree, branch and repository.
1983
2024
Except when they are being cloned.
1985
2026
from bzrlib.branch import BzrBranchFormat4
2046
2087
# target doesn't support stacking. So force a branch that *can*
2047
2088
# support stacking.
2048
2089
from bzrlib.branch import BzrBranchFormat7
2049
self._branch_format = BzrBranchFormat7()
2050
mutter("using %r for stacking" % (self._branch_format,))
2090
branch_format = BzrBranchFormat7()
2091
self.set_branch_format(branch_format)
2092
mutter("using %r for stacking" % (branch_format,))
2051
2093
from bzrlib.repofmt import pack_repo
2052
2094
if self.repository_format.rich_root_data:
2053
2095
bzrdir_format_name = '1.6.1-rich-root'
2088
2130
from bzrlib.repository import RepositoryFormat
2089
2131
return RepositoryFormat.get_default_format()
2091
def __set_repository_format(self, value):
2133
def _set_repository_format(self, value):
2092
2134
"""Allow changing the repository format for metadir formats."""
2093
2135
self._repository_format = value
2095
repository_format = property(__return_repository_format, __set_repository_format)
2137
repository_format = property(__return_repository_format,
2138
_set_repository_format)
2140
def _supply_sub_formats_to(self, other_format):
2141
"""Give other_format the same values for sub formats as this has.
2143
This method is expected to be used when parameterising a
2144
RemoteBzrDirFormat instance with the parameters from a
2145
BzrDirMetaFormat1 instance.
2147
:param other_format: other_format is a format which should be
2148
compatible with whatever sub formats are supported by self.
2151
if getattr(self, '_repository_format', None) is not None:
2152
other_format.repository_format = self.repository_format
2153
if self._branch_format is not None:
2154
other_format._branch_format = self._branch_format
2155
if self._workingtree_format is not None:
2156
other_format.workingtree_format = self.workingtree_format
2097
2158
def __get_workingtree_format(self):
2098
2159
if self._workingtree_format is None:
2336
2397
text_changed = False
2337
2398
parent_candiate_entries = ie.parent_candidates(parent_invs)
2338
2399
heads = graph.Graph(self).heads(parent_candiate_entries.keys())
2339
# XXX: Note that this is unordered - and this is tolerable because
2400
# XXX: Note that this is unordered - and this is tolerable because
2340
2401
# the previous code was also unordered.
2341
2402
previous_entries = dict((head, parent_candiate_entries[head]) for head
2359
2420
# a call to:. This needs the path figured out. rather than a work_tree
2360
2421
# a v4 revision_tree can be given, or something that looks enough like
2361
2422
# one to give the file content to the entry if it needs it.
2362
# and we need something that looks like a weave store for snapshot to
2423
# and we need something that looks like a weave store for snapshot to
2363
2424
# save against.
2364
2425
#ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
2365
2426
if len(previous_revisions) == 1:
2481
2542
self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
2482
2543
self.make_lock('repository')
2483
2544
# we hard code the formats here because we are converting into
2484
# the meta format. The meta format upgrader can take this to a
2545
# the meta format. The meta format upgrader can take this to a
2485
2546
# future format within each component.
2486
2547
self.put_format('repository', RepositoryFormat7())
2487
2548
for entry in repository_names:
2642
2703
def get_format_description(self):
2643
2704
return 'bzr remote bzrdir'
2706
def get_format_string(self):
2707
raise NotImplementedError(self.get_format_string)
2646
2710
def probe_transport(klass, transport):
2647
2711
"""Return a RemoteBzrDirFormat object if it looks possible."""
2679
2743
response = client.call('BzrDirFormat.initialize', path)
2680
2744
if response[0] != 'ok':
2681
2745
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2682
return remote.RemoteBzrDir(transport)
2746
format = RemoteBzrDirFormat()
2747
self._supply_sub_formats_to(format)
2748
return remote.RemoteBzrDir(transport, format)
2684
2750
def _open(self, transport):
2685
return remote.RemoteBzrDir(transport)
2751
return remote.RemoteBzrDir(transport, self)
2687
2753
def __eq__(self, other):
2688
2754
if not isinstance(other, RemoteBzrDirFormat):
2690
2756
return self.get_format_description() == other.get_format_description()
2693
def repository_format(self):
2694
# Using a property to avoid early loading of remote
2695
return remote.RemoteRepositoryFormat()
2758
def __return_repository_format(self):
2759
# Always return a RemoteRepositoryFormat object, but if a specific bzr
2760
# repository format has been asked for, tell the RemoteRepositoryFormat
2761
# that it should use that for init() etc.
2762
result = remote.RemoteRepositoryFormat()
2763
custom_format = getattr(self, '_repository_format', None)
2765
# We will use the custom format to create repositories over the
2766
# wire; expose its details like rich_root_data for code to query
2767
if isinstance(custom_format, remote.RemoteRepositoryFormat):
2768
result._custom_format = custom_format._custom_format
2770
result._custom_format = custom_format
2771
result.rich_root_data = custom_format.rich_root_data
2774
def get_branch_format(self):
2775
result = BzrDirMetaFormat1.get_branch_format(self)
2776
if not isinstance(result, remote.RemoteBranchFormat):
2777
new_result = remote.RemoteBranchFormat()
2778
new_result._custom_format = result
2780
self.set_branch_format(new_result)
2784
repository_format = property(__return_repository_format,
2785
BzrDirMetaFormat1._set_repository_format) #.im_func)
2698
2788
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
2710
2800
class BzrDirFormatRegistry(registry.Registry):
2711
2801
"""Registry of user-selectable BzrDir subformats.
2713
2803
Differs from BzrDirFormat._control_formats in that it provides sub-formats,
2714
2804
e.g. BzrDirMeta1 with weave repository. Also, it's more user-oriented.
2774
2864
def register(self, key, factory, help, native=True, deprecated=False,
2775
2865
hidden=False, experimental=False, alias=False):
2776
2866
"""Register a BzrDirFormat factory.
2778
2868
The factory must be a callable that takes one parameter: the key.
2779
2869
It must produce an instance of the BzrDirFormat when called.
2798
2888
def set_default(self, key):
2799
2889
"""Set the 'default' key to be a clone of the supplied key.
2801
2891
This method must be called once and only once.
2803
2893
registry.Registry.register(self, 'default', self.get(key),
2835
2925
def wrapped(key, help, info):
2836
2926
if info.native:
2837
2927
help = '(native) ' + help
2838
return ':%s:\n%s\n\n' % (key,
2839
textwrap.fill(help, initial_indent=' ',
2928
return ':%s:\n%s\n\n' % (key,
2929
textwrap.fill(help, initial_indent=' ',
2840
2930
subsequent_indent=' '))
2841
2931
if default_realkey is not None:
2842
2932
output += wrapped(default_realkey, '(default) %s' % default_help,
3021
3111
# appear in chronological order and format descriptions can build
3022
3112
# on previous ones.
3023
3113
format_registry = BzrDirFormatRegistry()
3114
# The pre-0.8 formats have their repository format network name registered in
3115
# repository.py. MetaDir formats have their repository format network name
3116
# inferred from their disk format string.
3024
3117
format_registry.register('weave', BzrDirFormat6,
3025
3118
'Pre-0.8 format. Slower than knit and does not'
3026
3119
' support checkouts or shared repositories.',