53
60
from bzrlib.tests.test_http import TestWithTransport_pycurl
54
61
from bzrlib.transport import (
58
65
from bzrlib.transport.http._urllib import HttpTransport_urllib
59
66
from bzrlib.transport.nosmart import NoSmartTransportDecorator
60
67
from bzrlib.transport.readonly import ReadonlyTransportDecorator
61
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
68
from bzrlib.repofmt import knitrepo, pack_repo
64
71
class TestDefaultFormat(TestCase):
66
73
def test_get_set_default_format(self):
67
74
old_format = bzrdir.BzrDirFormat.get_default_format()
68
# default is BzrDirFormat6
75
# default is BzrDirMetaFormat1
69
76
self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
70
bzrdir.BzrDirFormat._set_default_format(SampleBzrDirFormat())
77
controldir.ControlDirFormat._set_default_format(SampleBzrDirFormat())
71
78
# creating a bzr dir should now create an instrumented dir.
73
80
result = bzrdir.BzrDir.create('memory:///')
74
81
self.failUnless(isinstance(result, SampleBzrDir))
76
bzrdir.BzrDirFormat._set_default_format(old_format)
83
controldir.ControlDirFormat._set_default_format(old_format)
77
84
self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
87
class DeprecatedBzrDirFormat(bzrdir.BzrDirFormat):
88
"""A deprecated bzr dir format."""
80
91
class TestFormatRegistry(TestCase):
82
93
def make_format_registry(self):
83
my_format_registry = bzrdir.BzrDirFormatRegistry()
84
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
85
'Pre-0.8 format. Slower and does not support checkouts or shared'
86
' repositories', deprecated=True)
87
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
88
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
89
my_format_registry.register_metadir('knit',
94
my_format_registry = controldir.ControlDirFormatRegistry()
95
my_format_registry.register('deprecated', DeprecatedBzrDirFormat,
96
'Some format. Slower and unawesome and deprecated.',
98
my_format_registry.register_lazy('lazy', 'bzrlib.tests.test_bzrdir',
99
'DeprecatedBzrDirFormat', 'Format registered lazily',
101
bzrdir.register_metadir(my_format_registry, 'knit',
90
102
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
91
103
'Format using knits',
93
105
my_format_registry.set_default('knit')
94
my_format_registry.register_metadir(
106
bzrdir.register_metadir(my_format_registry,
96
108
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
97
109
'Experimental successor to knit. Use at your own risk.',
98
110
branch_format='bzrlib.branch.BzrBranchFormat6',
99
111
experimental=True)
100
my_format_registry.register_metadir(
112
bzrdir.register_metadir(my_format_registry,
102
114
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
103
115
'Experimental successor to knit. Use at your own risk.',
104
116
branch_format='bzrlib.branch.BzrBranchFormat6', hidden=True)
105
my_format_registry.register('hiddenweave', bzrdir.BzrDirFormat6,
106
'Pre-0.8 format. Slower and does not support checkouts or shared'
107
' repositories', hidden=True)
108
my_format_registry.register_lazy('hiddenlazy', 'bzrlib.bzrdir',
109
'BzrDirFormat6', 'Format registered lazily', deprecated=True,
117
my_format_registry.register('hiddendeprecated', DeprecatedBzrDirFormat,
118
'Old format. Slower and does not support things. ', hidden=True)
119
my_format_registry.register_lazy('hiddenlazy', 'bzrlib.tests.test_bzrdir',
120
'DeprecatedBzrDirFormat', 'Format registered lazily',
121
deprecated=True, hidden=True)
111
122
return my_format_registry
113
124
def test_format_registry(self):
114
125
my_format_registry = self.make_format_registry()
115
126
my_bzrdir = my_format_registry.make_bzrdir('lazy')
116
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
117
my_bzrdir = my_format_registry.make_bzrdir('weave')
118
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
127
self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
128
my_bzrdir = my_format_registry.make_bzrdir('deprecated')
129
self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
119
130
my_bzrdir = my_format_registry.make_bzrdir('default')
120
131
self.assertIsInstance(my_bzrdir.repository_format,
121
132
knitrepo.RepositoryFormatKnit1)
166
176
self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
167
177
bzrdir.format_registry.get('default'))
169
repository.RepositoryFormat.get_default_format().__class__,
179
repository.format_registry.get_default().__class__,
170
180
knitrepo.RepositoryFormatKnit3)
172
182
bzrdir.format_registry.set_default_repository(old_default)
174
184
def test_aliases(self):
175
a_registry = bzrdir.BzrDirFormatRegistry()
176
a_registry.register('weave', bzrdir.BzrDirFormat6,
177
'Pre-0.8 format. Slower and does not support checkouts or shared'
178
' repositories', deprecated=True)
179
a_registry.register('weavealias', bzrdir.BzrDirFormat6,
180
'Pre-0.8 format. Slower and does not support checkouts or shared'
181
' repositories', deprecated=True, alias=True)
182
self.assertEqual(frozenset(['weavealias']), a_registry.aliases())
185
a_registry = controldir.ControlDirFormatRegistry()
186
a_registry.register('deprecated', DeprecatedBzrDirFormat,
187
'Old format. Slower and does not support stuff',
189
a_registry.register('deprecatedalias', DeprecatedBzrDirFormat,
190
'Old format. Slower and does not support stuff',
191
deprecated=True, alias=True)
192
self.assertEqual(frozenset(['deprecatedalias']), a_registry.aliases())
185
195
class SampleBranch(bzrlib.branch.Branch):
242
252
return "opened branch."
255
class BzrDirFormatTest1(bzrdir.BzrDirMetaFormat1):
258
def get_format_string():
259
return "Test format 1"
262
class BzrDirFormatTest2(bzrdir.BzrDirMetaFormat1):
265
def get_format_string():
266
return "Test format 2"
245
269
class TestBzrDirFormat(TestCaseWithTransport):
246
270
"""Tests for the BzrDirFormat facility."""
248
272
def test_find_format(self):
249
273
# is the right format object found for a branch?
250
274
# create a branch with a few known format objects.
251
# this is not quite the same as
252
t = get_transport(self.get_url())
275
bzrdir.BzrDirFormat.register_format(BzrDirFormatTest1())
276
self.addCleanup(bzrdir.BzrDirFormat.unregister_format, BzrDirFormatTest1())
277
bzrdir.BzrDirFormat.register_format(BzrDirFormatTest2())
278
self.addCleanup(bzrdir.BzrDirFormat.unregister_format, BzrDirFormatTest2())
279
t = self.get_transport()
253
280
self.build_tree(["foo/", "bar/"], transport=t)
254
281
def check_format(format, url):
255
282
format.initialize(url)
256
t = get_transport(url)
283
t = _mod_transport.get_transport(url)
257
284
found_format = bzrdir.BzrDirFormat.find_format(t)
258
285
self.failUnless(isinstance(found_format, format.__class__))
259
check_format(bzrdir.BzrDirFormat5(), "foo")
260
check_format(bzrdir.BzrDirFormat6(), "bar")
286
check_format(BzrDirFormatTest1(), "foo")
287
check_format(BzrDirFormatTest2(), "bar")
262
289
def test_find_format_nothing_there(self):
263
290
self.assertRaises(NotBranchError,
264
291
bzrdir.BzrDirFormat.find_format,
292
_mod_transport.get_transport('.'))
267
294
def test_find_format_unknown_format(self):
268
t = get_transport(self.get_url())
295
t = self.get_transport()
270
297
t.put_bytes('.bzr/branch-format', '')
271
298
self.assertRaises(UnknownFormatError,
272
299
bzrdir.BzrDirFormat.find_format,
300
_mod_transport.get_transport('.'))
275
302
def test_register_unregister_format(self):
276
303
format = SampleBzrDirFormat()
284
311
# which bzrdir.open_containing will refuse (not supported)
285
312
self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open_containing, url)
286
313
# but open_downlevel will work
287
t = get_transport(url)
314
t = _mod_transport.get_transport(url)
288
315
self.assertEqual(format.open(t), bzrdir.BzrDir.open_unsupported(url))
289
316
# unregister the format
290
317
bzrdir.BzrDirFormat.unregister_format(format)
291
318
# now open_downlevel should fail too.
292
319
self.assertRaises(UnknownFormatError, bzrdir.BzrDir.open_unsupported, url)
321
def test_register_unregister_format_lazy(self):
322
# register a format for it.
323
bzrdir.BzrDirFormat.register_lazy_format("Test format 1",
324
"bzrlib.tests.test_bzrdir", "BzrDirFormatTest1")
325
# It should be registered with the prober:
326
self.assertIsInstance(bzrdir.BzrProber.formats.get("Test format 1"),
328
self.assertTrue(BzrDirFormatTest1 in
329
controldir.ControlDirFormat.known_formats())
330
bzrdir.BzrDirFormat.unregister_lazy_format("Test format 1",
331
"bzrlib.tests.test_bzrdir", "BzrDirFormatTest1")
332
self.assertFalse(BzrDirFormatTest1 in
333
controldir.ControlDirFormat.known_formats())
334
self.assertRaises(KeyError, bzrdir.BzrProber.formats.get,
294
337
def test_create_branch_and_repo_uses_default(self):
295
338
format = SampleBzrDirFormat()
296
339
branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url(),
676
719
self.assertEqual(relpath, 'baz')
678
721
def test_open_containing_from_transport(self):
679
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
680
get_transport(self.get_readonly_url('')))
681
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
682
get_transport(self.get_readonly_url('g/p/q')))
722
self.assertRaises(NotBranchError,
723
bzrdir.BzrDir.open_containing_from_transport,
724
_mod_transport.get_transport(self.get_readonly_url('')))
725
self.assertRaises(NotBranchError,
726
bzrdir.BzrDir.open_containing_from_transport,
727
_mod_transport.get_transport(self.get_readonly_url('g/p/q')))
683
728
control = bzrdir.BzrDir.create(self.get_url())
684
729
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
685
get_transport(self.get_readonly_url('')))
730
_mod_transport.get_transport(self.get_readonly_url('')))
686
731
self.assertEqual('', relpath)
687
732
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
688
get_transport(self.get_readonly_url('g/p/q')))
733
_mod_transport.get_transport(self.get_readonly_url('g/p/q')))
689
734
self.assertEqual('g/p/q', relpath)
691
736
def test_open_containing_tree_or_branch(self):
735
780
# transport pointing at bzrdir should give a bzrdir with root transport
736
781
# set to the given transport
737
782
control = bzrdir.BzrDir.create(self.get_url())
738
transport = get_transport(self.get_url())
739
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
740
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
783
t = self.get_transport()
784
opened_bzrdir = bzrdir.BzrDir.open_from_transport(t)
785
self.assertEqual(t.base, opened_bzrdir.root_transport.base)
741
786
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
743
788
def test_open_from_transport_no_bzrdir(self):
744
transport = get_transport(self.get_url())
745
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
789
t = self.get_transport()
790
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
748
792
def test_open_from_transport_bzrdir_in_parent(self):
749
793
control = bzrdir.BzrDir.create(self.get_url())
750
transport = get_transport(self.get_url())
751
transport.mkdir('subdir')
752
transport = transport.clone('subdir')
753
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
794
t = self.get_transport()
796
t = t.clone('subdir')
797
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
756
799
def test_sprout_recursive(self):
757
800
tree = self.make_branch_and_tree('tree1',
787
830
self.build_tree(['tree1/subtree/file'])
788
831
sub_tree.add('file')
789
832
tree.commit('Initial commit')
833
# The following line force the orhaning to reveal bug #634470
834
tree.branch.get_config().set_user_option(
835
'bzr.transform.orphan_policy', 'move')
790
836
tree.bzrdir.destroy_workingtree()
837
# FIXME: subtree/.bzr is left here which allows the test to pass (or
838
# fail :-( ) -- vila 20100909
791
839
repo = self.make_repository('repo', shared=True,
792
840
format='dirstate-with-subtree')
793
841
repo.set_make_working_trees(False)
794
tree.bzrdir.sprout('repo/tree2')
795
self.failUnlessExists('repo/tree2/subtree')
796
self.failIfExists('repo/tree2/subtree/file')
842
# FIXME: we just deleted the workingtree and now we want to use it ????
843
# At a minimum, we should use tree.branch below (but this fails too
844
# currently) or stop calling this test 'treeless'. Specifically, I've
845
# turn the line below into an assertRaises when 'subtree/.bzr' is
846
# orphaned and sprout tries to access the branch there (which is left
847
# by bzrdir.BzrDirMeta1.destroy_workingtree when it ignores the
848
# [DeletingParent('Not deleting', u'subtree', None)] conflict). See bug
849
# #634470. -- vila 20100909
850
self.assertRaises(errors.NotBranchError,
851
tree.bzrdir.sprout, 'repo/tree2')
852
# self.failUnlessExists('repo/tree2/subtree')
853
# self.failIfExists('repo/tree2/subtree/file')
798
855
def make_foo_bar_baz(self):
799
856
foo = bzrdir.BzrDir.create_branch_convenience('foo').bzrdir
804
861
def test_find_bzrdirs(self):
805
862
foo, bar, baz = self.make_foo_bar_baz()
806
transport = get_transport(self.get_url())
807
self.assertEqualBzrdirs([baz, foo, bar],
808
bzrdir.BzrDir.find_bzrdirs(transport))
863
t = self.get_transport()
864
self.assertEqualBzrdirs([baz, foo, bar], bzrdir.BzrDir.find_bzrdirs(t))
866
def make_fake_permission_denied_transport(self, transport, paths):
867
"""Create a transport that raises PermissionDenied for some paths."""
870
raise errors.PermissionDenied(path)
872
path_filter_server = pathfilter.PathFilteringServer(transport, filter)
873
path_filter_server.start_server()
874
self.addCleanup(path_filter_server.stop_server)
875
path_filter_transport = pathfilter.PathFilteringTransport(
876
path_filter_server, '.')
877
return (path_filter_server, path_filter_transport)
879
def assertBranchUrlsEndWith(self, expect_url_suffix, actual_bzrdirs):
880
"""Check that each branch url ends with the given suffix."""
881
for actual_bzrdir in actual_bzrdirs:
882
self.assertEndsWith(actual_bzrdir.user_url, expect_url_suffix)
884
def test_find_bzrdirs_permission_denied(self):
885
foo, bar, baz = self.make_foo_bar_baz()
886
t = self.get_transport()
887
path_filter_server, path_filter_transport = \
888
self.make_fake_permission_denied_transport(t, ['foo'])
890
self.assertBranchUrlsEndWith('/baz/',
891
bzrdir.BzrDir.find_bzrdirs(path_filter_transport))
893
smart_transport = self.make_smart_server('.',
894
backing_server=path_filter_server)
895
self.assertBranchUrlsEndWith('/baz/',
896
bzrdir.BzrDir.find_bzrdirs(smart_transport))
810
898
def test_find_bzrdirs_list_current(self):
811
899
def list_current(transport):
812
900
return [s for s in transport.list_dir('') if s != 'baz']
814
902
foo, bar, baz = self.make_foo_bar_baz()
815
transport = get_transport(self.get_url())
816
self.assertEqualBzrdirs([foo, bar],
817
bzrdir.BzrDir.find_bzrdirs(transport,
818
list_current=list_current))
903
t = self.get_transport()
904
self.assertEqualBzrdirs(
906
bzrdir.BzrDir.find_bzrdirs(t, list_current=list_current))
821
908
def test_find_bzrdirs_evaluate(self):
822
909
def evaluate(bzrdir):
844
930
root = self.make_repository('', shared=True)
845
931
foo, bar, baz = self.make_foo_bar_baz()
846
932
qux = self.make_bzrdir('foo/qux')
847
transport = get_transport(self.get_url())
848
branches = bzrdir.BzrDir.find_branches(transport)
933
t = self.get_transport()
934
branches = bzrdir.BzrDir.find_branches(t)
849
935
self.assertEqual(baz.root_transport.base, branches[0].base)
850
936
self.assertEqual(foo.root_transport.base, branches[1].base)
851
937
self.assertEqual(bar.root_transport.base, branches[2].base)
853
939
# ensure this works without a top-level repo
854
branches = bzrdir.BzrDir.find_branches(transport.clone('foo'))
940
branches = bzrdir.BzrDir.find_branches(t.clone('foo'))
855
941
self.assertEqual(foo.root_transport.base, branches[0].base)
856
942
self.assertEqual(bar.root_transport.base, branches[1].base)
945
class TestMissingRepoBranchesSkipped(TestCaseWithMemoryTransport):
947
def test_find_bzrdirs_missing_repo(self):
948
t = self.get_transport()
949
arepo = self.make_repository('arepo', shared=True)
950
abranch_url = arepo.user_url + '/abranch'
951
abranch = bzrdir.BzrDir.create(abranch_url).create_branch()
952
t.delete_tree('arepo/.bzr')
953
self.assertRaises(errors.NoRepositoryPresent,
954
branch.Branch.open, abranch_url)
955
self.make_branch('baz')
956
for actual_bzrdir in bzrdir.BzrDir.find_branches(t):
957
self.assertEndsWith(actual_bzrdir.user_url, '/baz/')
859
960
class TestMeta1DirFormat(TestCaseWithTransport):
860
961
"""Tests specific to the meta1 dir format."""
921
1023
self.assertEqual(2, rpc_count)
924
class TestFormat5(TestCaseWithTransport):
925
"""Tests specific to the version 5 bzrdir format."""
927
def test_same_lockfiles_between_tree_repo_branch(self):
928
# this checks that only a single lockfiles instance is created
929
# for format 5 objects
930
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
931
def check_dir_components_use_same_lock(dir):
932
ctrl_1 = dir.open_repository().control_files
933
ctrl_2 = dir.open_branch().control_files
934
ctrl_3 = dir.open_workingtree()._control_files
935
self.assertTrue(ctrl_1 is ctrl_2)
936
self.assertTrue(ctrl_2 is ctrl_3)
937
check_dir_components_use_same_lock(dir)
938
# and if we open it normally.
939
dir = bzrdir.BzrDir.open(self.get_url())
940
check_dir_components_use_same_lock(dir)
942
def test_can_convert(self):
943
# format 5 dirs are convertable
944
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
945
self.assertTrue(dir.can_convert_format())
947
def test_needs_conversion(self):
948
# format 5 dirs need a conversion if they are not the default,
950
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
951
# don't need to convert it to itself
952
self.assertFalse(dir.needs_format_conversion(bzrdir.BzrDirFormat5()))
953
# do need to convert it to the current default
954
self.assertTrue(dir.needs_format_conversion(
955
bzrdir.BzrDirFormat.get_default_format()))
958
class TestFormat6(TestCaseWithTransport):
959
"""Tests specific to the version 6 bzrdir format."""
961
def test_same_lockfiles_between_tree_repo_branch(self):
962
# this checks that only a single lockfiles instance is created
963
# for format 6 objects
964
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
965
def check_dir_components_use_same_lock(dir):
966
ctrl_1 = dir.open_repository().control_files
967
ctrl_2 = dir.open_branch().control_files
968
ctrl_3 = dir.open_workingtree()._control_files
969
self.assertTrue(ctrl_1 is ctrl_2)
970
self.assertTrue(ctrl_2 is ctrl_3)
971
check_dir_components_use_same_lock(dir)
972
# and if we open it normally.
973
dir = bzrdir.BzrDir.open(self.get_url())
974
check_dir_components_use_same_lock(dir)
976
def test_can_convert(self):
977
# format 6 dirs are convertable
978
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
979
self.assertTrue(dir.can_convert_format())
981
def test_needs_conversion(self):
982
# format 6 dirs need an conversion if they are not the default.
983
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
984
self.assertTrue(dir.needs_format_conversion(
985
bzrdir.BzrDirFormat.get_default_format()))
988
1026
class NotBzrDir(bzrlib.bzrdir.BzrDir):
989
1027
"""A non .bzr based control directory."""
1030
1070
dir = format.initialize(self.get_url())
1031
1071
self.assertIsInstance(dir, NotBzrDir)
1032
1072
# now probe for it.
1033
bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
1073
controldir.ControlDirFormat.register_prober(NotBzrDirProber)
1035
found = bzrlib.bzrdir.BzrDirFormat.find_format(
1036
get_transport(self.get_url()))
1075
found = bzrlib.bzrdir.BzrDirFormat.find_format(self.get_transport())
1037
1076
self.assertIsInstance(found, NotBzrDirFormat)
1039
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
1078
controldir.ControlDirFormat.unregister_prober(NotBzrDirProber)
1041
1080
def test_included_in_known_formats(self):
1042
bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
1081
not_format = NotBzrDirFormat()
1082
bzrlib.controldir.ControlDirFormat.register_format(not_format)
1044
1084
formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
1045
1085
for format in formats:
1351
1402
self.assertIsInstance(params, RepoInitHookParams)
1352
1403
self.assertTrue(hasattr(params, 'bzrdir'))
1353
1404
self.assertTrue(hasattr(params, 'repository'))
1406
def test_post_repo_init_hook_repr(self):
1408
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1409
lambda params: param_reprs.append(repr(params)), None)
1410
self.make_repository('foo')
1411
self.assertLength(1, param_reprs)
1412
param_repr = param_reprs[0]
1413
self.assertStartsWith(param_repr, '<RepoInitHookParams for ')
1416
class TestGenerateBackupName(TestCaseWithMemoryTransport):
1417
# FIXME: This may need to be unified with test_osutils.TestBackupNames or
1418
# moved to per_bzrdir or per_transport for better coverage ?
1422
super(TestGenerateBackupName, self).setUp()
1423
self._transport = self.get_transport()
1424
bzrdir.BzrDir.create(self.get_url(),
1425
possible_transports=[self._transport])
1426
self._bzrdir = bzrdir.BzrDir.open_from_transport(self._transport)
1428
def test_deprecated_generate_backup_name(self):
1429
res = self.applyDeprecated(
1430
symbol_versioning.deprecated_in((2, 3, 0)),
1431
self._bzrdir.generate_backup_name, 'whatever')
1434
self.assertEqual("a.~1~", self._bzrdir._available_backup_name("a"))
1436
def test_exiting(self):
1437
self._transport.put_bytes("a.~1~", "some content")
1438
self.assertEqual("a.~2~", self._bzrdir._available_backup_name("a"))