17
17
"""Tests for bzrdir implementations - tests a bzrdir format."""
19
19
from cStringIO import StringIO
21
from itertools import izip
21
23
from stat import S_ISDIR
24
26
import bzrlib.branch
25
import bzrlib.bzrdir as bzrdir
32
revision as _mod_revision,
26
38
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock
27
from bzrlib.check import check
28
import bzrlib.errors as errors
39
from bzrlib.check import check_branch
29
40
from bzrlib.errors import (FileExists,
32
43
UninitializableFormat,
35
import bzrlib.repository as repository
36
46
import bzrlib.revision
37
47
from bzrlib.tests import (
40
50
TestCaseWithTransport,
54
from bzrlib.tests.bzrdir_implementations import TestCaseWithBzrDir
43
55
from bzrlib.trace import mutter
44
import bzrlib.transactions as transactions
45
import bzrlib.transport as transport
46
56
from bzrlib.transport import get_transport
47
import bzrlib.ui as ui
57
from bzrlib.transport.local import LocalTransport
48
58
from bzrlib.upgrade import upgrade
49
import bzrlib.workingtree as workingtree
52
class TestCaseWithBzrDir(TestCaseWithTransport):
55
super(TestCaseWithBzrDir, self).setUp()
59
if self.bzrdir is None:
60
self.bzrdir = self.make_bzrdir(None)
63
def make_bzrdir(self, relpath, format=None):
64
return super(TestCaseWithBzrDir, self).make_bzrdir(
65
relpath, format=self.bzrdir_format)
59
from bzrlib.remote import RemoteBzrDir
60
from bzrlib.repofmt import weaverepo
69
63
class TestBzrDir(TestCaseWithBzrDir):
105
106
target.get(path).read(),
106
107
"text for file %r differs:\n" % path)
109
def assertRepositoryHasSameItems(self, left_repo, right_repo):
110
"""require left_repo and right_repo to contain the same data."""
111
# XXX: TODO: Doesn't work yet, because we need to be able to compare
112
# local repositories to remote ones... but this is an as-yet unsolved
113
# aspect of format management and the Remote protocols...
114
# self.assertEqual(left_repo._format.__class__,
115
# right_repo._format.__class__)
116
left_repo.lock_read()
118
right_repo.lock_read()
121
all_revs = left_repo.all_revision_ids()
122
self.assertEqual(left_repo.all_revision_ids(),
123
right_repo.all_revision_ids())
124
for rev_id in left_repo.all_revision_ids():
125
self.assertEqual(left_repo.get_revision(rev_id),
126
right_repo.get_revision(rev_id))
128
left_inv_weave = left_repo.inventories
129
right_inv_weave = right_repo.inventories
130
self.assertEqual(set(left_inv_weave.keys()),
131
set(right_inv_weave.keys()))
132
# XXX: currently this does not handle indirectly referenced
133
# inventories (e.g. where the inventory is a delta basis for
134
# one that is fully present but that the revid for that
135
# inventory is not yet present.)
136
self.assertEqual(set(left_inv_weave.keys()),
137
set(left_repo.revisions.keys()))
138
left_trees = left_repo.revision_trees(all_revs)
139
right_trees = right_repo.revision_trees(all_revs)
140
for left_tree, right_tree in izip(left_trees, right_trees):
141
self.assertEqual(left_tree.inventory, right_tree.inventory)
143
text_index = left_repo._generate_text_key_index()
144
self.assertEqual(text_index,
145
right_repo._generate_text_key_index())
147
for file_id, revision_id in text_index.iterkeys():
148
desired_files.append(
149
(file_id, revision_id, (file_id, revision_id)))
150
left_texts = list(left_repo.iter_files_bytes(desired_files))
151
right_texts = list(right_repo.iter_files_bytes(desired_files))
154
self.assertEqual(left_texts, right_texts)
156
for rev_id in all_revs:
158
left_text = left_repo.get_signature_text(rev_id)
159
except NoSuchRevision:
161
right_text = right_repo.get_signature_text(rev_id)
162
self.assertEqual(left_text, right_text)
108
168
def skipIfNoWorkingTree(self, a_bzrdir):
109
169
"""Raises TestSkipped if a_bzrdir doesn't have a working tree.
128
188
raise TestSkipped("cannot make working tree with transport %r"
129
189
% a_bzrdir.transport)
131
def sproutOrSkip(self, from_bzrdir, to_url, revision_id=None, basis=None,
132
force_new_repo=False):
191
def sproutOrSkip(self, from_bzrdir, to_url, revision_id=None,
192
force_new_repo=False, accelerator_tree=None):
133
193
"""Sprout from_bzrdir into to_url, or raise TestSkipped.
135
195
A simple wrapper for from_bzrdir.sprout that translates NotLocalUrl into
136
196
TestSkipped. Returns the newly sprouted bzrdir.
139
target = from_bzrdir.sprout(to_url, revision_id=revision_id,
141
force_new_repo=force_new_repo)
142
except errors.NotLocalUrl:
198
to_transport = get_transport(to_url)
199
if not isinstance(to_transport, LocalTransport):
143
200
raise TestSkipped('Cannot sprout to remote bzrdirs.')
201
target = from_bzrdir.sprout(to_url, revision_id=revision_id,
202
force_new_repo=force_new_repo,
203
possible_transports=[to_transport],
204
accelerator_tree=accelerator_tree)
146
207
def test_create_null_workingtree(self):
147
208
dir = self.make_bzrdir('dir1')
148
209
dir.create_repository()
149
210
dir.create_branch()
150
wt = dir.create_workingtree(revision_id=bzrlib.revision.NULL_REVISION)
212
wt = dir.create_workingtree(revision_id=bzrlib.revision.NULL_REVISION)
213
except errors.NotLocalUrl:
214
raise TestSkipped("cannot make working tree with transport %r"
151
216
self.assertEqual([], wt.get_parent_ids())
218
def test_destroy_workingtree(self):
219
tree = self.make_branch_and_tree('tree')
220
self.build_tree(['tree/file'])
222
tree.commit('first commit')
225
bzrdir.destroy_workingtree()
226
except errors.UnsupportedOperation:
227
raise TestSkipped('Format does not support destroying tree')
228
self.failIfExists('tree/file')
229
self.assertRaises(errors.NoWorkingTree, bzrdir.open_workingtree)
230
bzrdir.create_workingtree()
231
self.failUnlessExists('tree/file')
232
bzrdir.destroy_workingtree_metadata()
233
self.failUnlessExists('tree/file')
234
self.assertRaises(errors.NoWorkingTree, bzrdir.open_workingtree)
236
def test_destroy_branch(self):
237
branch = self.make_branch('branch')
238
bzrdir = branch.bzrdir
240
bzrdir.destroy_branch()
241
except (errors.UnsupportedOperation, errors.TransportNotPossible):
242
raise TestNotApplicable('Format does not support destroying tree')
243
self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
244
bzrdir.create_branch()
247
def test_destroy_repository(self):
248
repo = self.make_repository('repository')
251
bzrdir.destroy_repository()
252
except (errors.UnsupportedOperation, errors.TransportNotPossible):
253
raise TestNotApplicable('Format does not support destroying'
255
self.assertRaises(errors.NoRepositoryPresent, bzrdir.open_repository)
256
bzrdir.create_repository()
257
bzrdir.open_repository()
259
def test_open_workingtree_raises_no_working_tree(self):
260
"""BzrDir.open_workingtree() should raise NoWorkingTree (rather than
261
e.g. NotLocalUrl) if there is no working tree.
263
dir = self.make_bzrdir('source')
264
vfs_dir = bzrdir.BzrDir.open(self.get_vfs_only_url('source'))
265
if vfs_dir.has_workingtree():
266
# This BzrDir format doesn't support BzrDirs without working trees,
267
# so this test is irrelevant.
269
self.assertRaises(errors.NoWorkingTree, dir.open_workingtree)
271
def test_clone_on_transport(self):
272
a_dir = self.make_bzrdir('source')
273
target_transport = a_dir.root_transport.clone('..').clone('target')
274
target = a_dir.clone_on_transport(target_transport)
275
self.assertNotEqual(a_dir.transport.base, target.transport.base)
276
self.assertDirectoriesEqual(a_dir.root_transport, target.root_transport,
277
['./.bzr/merge-hashes'])
153
279
def test_clone_bzrdir_empty(self):
154
280
dir = self.make_bzrdir('source')
155
281
target = dir.clone(self.get_url('target'))
156
282
self.assertNotEqual(dir.transport.base, target.transport.base)
157
self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
283
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
284
['./.bzr/merge-hashes'])
159
286
def test_clone_bzrdir_empty_force_new_ignored(self):
160
287
# the force_new_repo parameter should have no effect on an empty
198
329
self.assertRaises(errors.NoRepositoryPresent, target.open_repository)
200
331
def test_clone_bzrdir_repository_branch_both_under_shared(self):
332
# Create a shared repository
202
334
shared_repo = self.make_repository('shared', shared=True)
203
335
except errors.IncompatibleFormat:
337
# Make a branch, 'commit_tree', and working tree outside of the shared
338
# repository, and commit some revisions to it.
205
339
tree = self.make_branch_and_tree('commit_tree')
206
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
340
self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
208
342
tree.commit('revision 1', rev_id='1')
209
343
tree.bzrdir.open_branch().set_revision_history([])
210
344
tree.set_parent_trees([])
211
345
tree.commit('revision 2', rev_id='2')
212
tree.bzrdir.open_repository().copy_content_into(shared_repo)
346
# Copy the content (i.e. revisions) from the 'commit_tree' branch's
347
# repository into the shared repository.
348
tree.branch.repository.copy_content_into(shared_repo)
349
# Make a branch 'source' inside the shared repository.
213
350
dir = self.make_bzrdir('shared/source')
214
351
dir.create_branch()
352
# Clone 'source' to 'target', also inside the shared repository.
215
353
target = dir.clone(self.get_url('shared/target'))
354
# 'source', 'target', and the shared repo all have distinct bzrdirs.
216
355
self.assertNotEqual(dir.transport.base, target.transport.base)
217
356
self.assertNotEqual(dir.transport.base, shared_repo.bzrdir.transport.base)
357
# The shared repository will contain revisions from the 'commit_tree'
358
# repository, even revisions that are not part of the history of the
359
# 'commit_tree' branch.
218
360
self.assertTrue(shared_repo.has_revision('1'))
220
362
def test_clone_bzrdir_repository_branch_only_source_under_shared(self):
223
365
except errors.IncompatibleFormat:
225
367
tree = self.make_branch_and_tree('commit_tree')
226
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
368
self.build_tree(['commit_tree/foo'])
228
370
tree.commit('revision 1', rev_id='1')
229
tree.bzrdir.open_branch().set_revision_history([])
371
tree.branch.bzrdir.open_branch().set_revision_history([])
230
372
tree.set_parent_trees([])
231
373
tree.commit('revision 2', rev_id='2')
232
tree.bzrdir.open_repository().copy_content_into(shared_repo)
233
shared_repo.set_make_working_trees(False)
234
self.assertFalse(shared_repo.make_working_trees())
374
tree.branch.repository.copy_content_into(shared_repo)
375
if shared_repo.make_working_trees():
376
shared_repo.set_make_working_trees(False)
377
self.assertFalse(shared_repo.make_working_trees())
235
378
self.assertTrue(shared_repo.has_revision('1'))
236
379
dir = self.make_bzrdir('shared/source')
237
380
dir.create_branch()
268
412
# and clone it with a revision limit.
270
414
tree = self.make_branch_and_tree('commit_tree')
271
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
415
self.build_tree(['commit_tree/foo'])
273
417
tree.commit('revision 1', rev_id='1')
274
tree.bzrdir.open_branch().set_revision_history([])
418
tree.branch.bzrdir.open_branch().set_revision_history([])
275
419
tree.set_parent_trees([])
276
420
tree.commit('revision 2', rev_id='2')
277
421
source = self.make_repository('source')
278
tree.bzrdir.open_repository().copy_content_into(source)
422
tree.branch.repository.copy_content_into(source)
279
423
dir = source.bzrdir
280
424
target = dir.clone(self.get_url('target'), revision_id='2')
281
425
raise TestSkipped('revision limiting not strict yet')
283
427
def test_clone_bzrdir_branch_and_repo(self):
284
428
tree = self.make_branch_and_tree('commit_tree')
285
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
429
self.build_tree(['commit_tree/foo'])
287
431
tree.commit('revision 1')
288
432
source = self.make_branch('source')
289
tree.bzrdir.open_repository().copy_content_into(source.repository)
290
tree.bzrdir.open_branch().copy_content_into(source)
433
tree.branch.repository.copy_content_into(source.repository)
434
tree.branch.copy_content_into(source)
291
435
dir = source.bzrdir
292
436
target = dir.clone(self.get_url('target'))
293
437
self.assertNotEqual(dir.transport.base, target.transport.base)
294
438
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
295
['./.bzr/stat-cache',
440
'./.bzr/basis-inventory-cache',
296
441
'./.bzr/checkout/stat-cache',
297
'./.bzr/repository/inventory.knit',
442
'./.bzr/merge-hashes',
446
self.assertRepositoryHasSameItems(
447
tree.branch.repository, target.open_repository())
300
449
def test_clone_bzrdir_branch_and_repo_into_shared_repo(self):
301
450
# by default cloning into a shared repo uses the shared repo.
302
451
tree = self.make_branch_and_tree('commit_tree')
303
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
452
self.build_tree(['commit_tree/foo'])
305
454
tree.commit('revision 1')
306
455
source = self.make_branch('source')
307
tree.bzrdir.open_repository().copy_content_into(source.repository)
308
tree.bzrdir.open_branch().copy_content_into(source)
456
tree.branch.repository.copy_content_into(source.repository)
457
tree.branch.copy_content_into(source)
310
459
self.make_repository('target', shared=True)
311
460
except errors.IncompatibleFormat:
360
508
# and clone it with a revision limit.
362
510
tree = self.make_branch_and_tree('commit_tree')
363
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
511
self.build_tree(['commit_tree/foo'])
365
513
tree.commit('revision 1', rev_id='1')
366
514
tree.commit('revision 2', rev_id='2', allow_pointless=True)
367
515
source = self.make_branch('source')
368
tree.bzrdir.open_repository().copy_content_into(source.repository)
369
tree.bzrdir.open_branch().copy_content_into(source)
516
tree.branch.repository.copy_content_into(source.repository)
517
tree.branch.copy_content_into(source)
370
518
dir = source.bzrdir
371
519
target = dir.clone(self.get_url('target'), revision_id='1')
372
520
self.assertEqual('1', target.open_branch().last_revision())
374
522
def test_clone_bzrdir_tree_branch_repo(self):
375
tree = self.make_branch_and_tree('sourcce')
376
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
523
tree = self.make_branch_and_tree('source')
524
self.build_tree(['source/foo'])
378
526
tree.commit('revision 1')
379
527
dir = tree.bzrdir
382
530
self.assertNotEqual(dir.transport.base, target.transport.base)
383
531
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
384
532
['./.bzr/stat-cache',
533
'./.bzr/checkout/dirstate',
385
534
'./.bzr/checkout/stat-cache',
386
'./.bzr/repository/inventory.knit',
535
'./.bzr/checkout/merge-hashes',
536
'./.bzr/merge-hashes',
539
self.assertRepositoryHasSameItems(tree.branch.repository,
540
target.open_repository())
541
target.open_workingtree().revert()
389
target.open_workingtree().revert([])
543
def test_clone_on_transport_preserves_repo_format(self):
544
if self.bzrdir_format == bzrdir.format_registry.make_bzrdir('default'):
548
source_branch = self.make_branch('source', format=format)
549
# Ensure no format data is cached
550
a_dir = bzrlib.branch.Branch.open_from_transport(
551
self.get_transport('source')).bzrdir
552
target_transport = a_dir.root_transport.clone('..').clone('target')
553
target_bzrdir = a_dir.clone_on_transport(target_transport)
554
target_repo = target_bzrdir.open_repository()
555
source_branch = bzrlib.branch.Branch.open(
556
self.get_vfs_only_url('source'))
557
self.assertEqual(target_repo._format, source_branch.repository._format)
391
559
def test_revert_inventory(self):
392
tree = self.make_branch_and_tree('sourcce')
393
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
560
tree = self.make_branch_and_tree('source')
561
self.build_tree(['source/foo'])
395
563
tree.commit('revision 1')
396
564
dir = tree.bzrdir
398
566
self.skipIfNoWorkingTree(target)
399
567
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
400
568
['./.bzr/stat-cache',
569
'./.bzr/checkout/dirstate',
401
570
'./.bzr/checkout/stat-cache',
402
'./.bzr/repository/inventory.knit',
571
'./.bzr/checkout/merge-hashes',
572
'./.bzr/merge-hashes',
575
self.assertRepositoryHasSameItems(tree.branch.repository,
576
target.open_repository())
405
target.open_workingtree().revert([])
578
target.open_workingtree().revert()
406
579
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
407
580
['./.bzr/stat-cache',
581
'./.bzr/checkout/dirstate',
408
582
'./.bzr/checkout/stat-cache',
409
'./.bzr/repository/inventory.knit',
583
'./.bzr/checkout/merge-hashes',
584
'./.bzr/merge-hashes',
587
self.assertRepositoryHasSameItems(tree.branch.repository,
588
target.open_repository())
413
590
def test_clone_bzrdir_tree_branch_reference(self):
414
591
# a tree with a branch reference (aka a checkout)
447
626
self.skipIfNoWorkingTree(target)
448
627
self.assertEqual(['1'], target.open_workingtree().get_parent_ids())
450
def test_clone_bzrdir_incomplete_source_with_basis(self):
451
# ensure that basis really does grab from the basis by having incomplete source
452
tree = self.make_branch_and_tree('commit_tree')
453
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
629
def test_clone_bzrdir_into_notrees_repo(self):
630
"""Cloning into a no-trees repo should not create a working tree"""
631
tree = self.make_branch_and_tree('source')
632
self.build_tree(['source/foo'])
455
tree.commit('revision 1', rev_id='1')
456
source = self.make_branch_and_tree('source')
457
# this gives us an incomplete repository
458
tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
459
tree.commit('revision 2', rev_id='2', allow_pointless=True)
460
tree.bzrdir.open_branch().copy_content_into(source.branch)
461
tree.copy_content_into(source)
462
self.assertFalse(source.branch.repository.has_revision('2'))
464
target = dir.clone(self.get_url('target'), basis=tree.bzrdir)
465
self.assertEqual('2', target.open_branch().last_revision())
467
self.assertEqual(['2'], target.open_workingtree().get_parent_ids())
468
except errors.NoWorkingTree:
469
# It should have a working tree if it's able to have one, so if
470
# we're here make sure it really can't have one.
471
self.assertRaises(errors.NotLocalUrl, target.create_workingtree)
472
self.assertTrue(target.open_branch().repository.has_revision('2'))
634
tree.commit('revision 1')
637
repo = self.make_repository('repo', shared=True)
638
except errors.IncompatibleFormat:
639
raise TestNotApplicable('must support shared repositories')
640
if repo.make_working_trees():
641
repo.set_make_working_trees(False)
642
self.assertFalse(repo.make_working_trees())
645
a_dir = dir.clone(self.get_url('repo/a'))
647
self.assertRaises(errors.NoWorkingTree, a_dir.open_workingtree)
649
def test_get_branch_reference_on_reference(self):
650
"""get_branch_reference should return the right url."""
651
referenced_branch = self.make_branch('referenced')
652
dir = self.make_bzrdir('source')
654
reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
656
except errors.IncompatibleFormat:
657
# this is ok too, not all formats have to support references.
659
self.assertEqual(referenced_branch.bzrdir.root_transport.abspath('') + '/',
660
dir.get_branch_reference())
662
def test_get_branch_reference_on_non_reference(self):
663
"""get_branch_reference should return None for non-reference branches."""
664
branch = self.make_branch('referenced')
665
self.assertEqual(None, branch.bzrdir.get_branch_reference())
667
def test_get_branch_reference_no_branch(self):
668
"""get_branch_reference should not mask NotBranchErrors."""
669
dir = self.make_bzrdir('source')
671
# this format does not support branchless bzrdirs.
673
self.assertRaises(errors.NotBranchError, dir.get_branch_reference)
474
675
def test_sprout_bzrdir_empty(self):
475
676
dir = self.make_bzrdir('source')
515
721
repo = dir.create_repository()
516
722
repo.fetch(tree.branch.repository)
517
723
self.assertTrue(repo.has_revision('1'))
726
_mod_revision.is_null(_mod_revision.ensure_null(
727
dir.open_branch().last_revision())))
728
except errors.NotBranchError:
518
730
target = self.sproutOrSkip(dir, self.get_url('target'))
519
731
self.assertNotEqual(dir.transport.base, target.transport.base)
732
# testing inventory isn't reasonable for repositories
520
733
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
521
['./.bzr/repository/inventory.knit',
739
'./.bzr/repository/inventory.knit',
742
# If we happen to have a tree, we'll guarantee everything
743
# except for the tree root is the same.
744
inventory_f = file(dir.transport.base+'inventory', 'rb')
745
self.assertContainsRe(inventory_f.read(),
746
'<inventory file_id="TREE_ROOT[^"]*"'
747
' format="5">\n</inventory>\n')
750
if e.errno != errno.ENOENT:
524
753
def test_sprout_bzrdir_with_repository_to_shared(self):
525
754
tree = self.make_branch_and_tree('commit_tree')
526
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
755
self.build_tree(['commit_tree/foo'])
528
757
tree.commit('revision 1', rev_id='1')
529
758
tree.bzrdir.open_branch().set_revision_history([])
530
759
tree.set_parent_trees([])
531
760
tree.commit('revision 2', rev_id='2')
532
761
source = self.make_repository('source')
533
tree.bzrdir.open_repository().copy_content_into(source)
762
tree.branch.repository.copy_content_into(source)
534
763
dir = source.bzrdir
536
765
shared_repo = self.make_repository('target', shared=True)
566
795
except errors.IncompatibleFormat:
568
797
tree = self.make_branch_and_tree('commit_tree')
569
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
798
self.build_tree(['commit_tree/foo'])
571
800
tree.commit('revision 1', rev_id='1')
572
801
tree.bzrdir.open_branch().set_revision_history([])
573
802
tree.set_parent_trees([])
574
803
tree.commit('revision 2', rev_id='2')
575
tree.bzrdir.open_repository().copy_content_into(shared_repo)
576
shared_repo.set_make_working_trees(False)
577
self.assertFalse(shared_repo.make_working_trees())
804
tree.branch.repository.copy_content_into(shared_repo)
805
if shared_repo.make_working_trees():
806
shared_repo.set_make_working_trees(False)
807
self.assertFalse(shared_repo.make_working_trees())
578
808
self.assertTrue(shared_repo.has_revision('1'))
579
809
dir = self.make_bzrdir('shared/source')
580
810
dir.create_branch()
583
813
self.assertNotEqual(dir.transport.base, shared_repo.bzrdir.transport.base)
584
814
branch = target.open_branch()
585
815
self.assertTrue(branch.repository.has_revision('1'))
586
self.assertTrue(branch.repository.make_working_trees())
816
if not isinstance(branch.bzrdir, RemoteBzrDir):
817
self.assertTrue(branch.repository.make_working_trees())
587
818
self.assertFalse(branch.repository.is_shared())
589
820
def test_sprout_bzrdir_repository_under_shared_force_new_repo(self):
590
821
tree = self.make_branch_and_tree('commit_tree')
591
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
822
self.build_tree(['commit_tree/foo'])
593
824
tree.commit('revision 1', rev_id='1')
594
825
tree.bzrdir.open_branch().set_revision_history([])
595
826
tree.set_parent_trees([])
596
827
tree.commit('revision 2', rev_id='2')
597
828
source = self.make_repository('source')
598
tree.bzrdir.open_repository().copy_content_into(source)
829
tree.branch.repository.copy_content_into(source)
599
830
dir = source.bzrdir
601
832
shared_repo = self.make_repository('target', shared=True)
612
843
# and sprout it with a revision limit.
614
845
tree = self.make_branch_and_tree('commit_tree')
615
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
846
self.build_tree(['commit_tree/foo'])
617
848
tree.commit('revision 1', rev_id='1')
618
849
tree.bzrdir.open_branch().set_revision_history([])
619
850
tree.set_parent_trees([])
620
851
tree.commit('revision 2', rev_id='2')
621
852
source = self.make_repository('source')
622
tree.bzrdir.open_repository().copy_content_into(source)
853
tree.branch.repository.copy_content_into(source)
623
854
dir = source.bzrdir
624
855
target = self.sproutOrSkip(dir, self.get_url('target'), revision_id='2')
625
856
raise TestSkipped('revision limiting not strict yet')
627
858
def test_sprout_bzrdir_branch_and_repo(self):
628
859
tree = self.make_branch_and_tree('commit_tree')
629
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
860
self.build_tree(['commit_tree/foo'])
631
862
tree.commit('revision 1')
632
863
source = self.make_branch('source')
633
tree.bzrdir.open_repository().copy_content_into(source.repository)
864
tree.branch.repository.copy_content_into(source.repository)
634
865
tree.bzrdir.open_branch().copy_content_into(source)
635
866
dir = source.bzrdir
636
867
target = self.sproutOrSkip(dir, self.get_url('target'))
637
868
self.assertNotEqual(dir.transport.base, target.transport.base)
638
869
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
639
['./.bzr/stat-cache',
871
'./.bzr/basis-inventory-cache',
872
'./.bzr/branch/branch.conf',
873
'./.bzr/branch/parent',
875
'./.bzr/checkout/inventory',
640
876
'./.bzr/checkout/stat-cache',
641
877
'./.bzr/inventory',
642
'./.bzr/checkout/inventory',
643
879
'./.bzr/repository/inventory.knit',
646
884
def test_sprout_bzrdir_branch_and_repo_shared(self):
647
885
# sprouting a branch with a repo into a shared repo uses the shared
649
887
tree = self.make_branch_and_tree('commit_tree')
650
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
888
self.build_tree(['commit_tree/foo'])
652
890
tree.commit('revision 1', rev_id='1')
653
891
source = self.make_branch('source')
654
tree.bzrdir.open_repository().copy_content_into(source.repository)
892
tree.branch.repository.copy_content_into(source.repository)
655
893
tree.bzrdir.open_branch().copy_content_into(source)
656
894
dir = source.bzrdir
758
996
# and sprout it with a revision limit.
760
998
tree = self.make_branch_and_tree('commit_tree')
761
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
999
self.build_tree(['commit_tree/foo'])
763
1001
tree.commit('revision 1', rev_id='1')
764
1002
tree.commit('revision 2', rev_id='2', allow_pointless=True)
765
1003
source = self.make_branch('source')
766
tree.bzrdir.open_repository().copy_content_into(source.repository)
1004
tree.branch.repository.copy_content_into(source.repository)
767
1005
tree.bzrdir.open_branch().copy_content_into(source)
768
1006
dir = source.bzrdir
769
1007
target = self.sproutOrSkip(dir, self.get_url('target'), revision_id='1')
770
1008
self.assertEqual('1', target.open_branch().last_revision())
772
1010
def test_sprout_bzrdir_tree_branch_repo(self):
773
tree = self.make_branch_and_tree('sourcce')
1011
tree = self.make_branch_and_tree('source')
774
1012
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
776
1014
tree.commit('revision 1')
778
1016
target = self.sproutOrSkip(dir, self.get_url('target'))
779
1017
self.assertNotEqual(dir.transport.base, target.transport.base)
780
1018
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
781
['./.bzr/stat-cache',
1020
'./.bzr/branch/branch.conf',
1021
'./.bzr/branch/parent',
1022
'./.bzr/checkout/dirstate',
782
1023
'./.bzr/checkout/stat-cache',
1024
'./.bzr/checkout/inventory',
783
1025
'./.bzr/inventory',
784
'./.bzr/checkout/inventory',
785
'./.bzr/repository/inventory.knit',
1027
'./.bzr/repository',
1028
'./.bzr/stat-cache',
1030
self.assertRepositoryHasSameItems(
1031
tree.branch.repository, target.open_repository())
788
1033
def test_sprout_bzrdir_tree_branch_reference(self):
789
1034
# sprouting should create a repository if needed and a sprouted branch.
855
1100
target = self.sproutOrSkip(dir, self.get_url('target'), revision_id='1')
856
1101
self.assertEqual(['1'], target.open_workingtree().get_parent_ids())
858
def test_sprout_bzrdir_incomplete_source_with_basis(self):
859
# ensure that basis really does grab from the basis by having incomplete source
860
tree = self.make_branch_and_tree('commit_tree')
861
self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
1103
def test_sprout_takes_accelerator(self):
1104
tree = self.make_branch_and_tree('source')
1105
self.build_tree(['source/foo'])
863
1107
tree.commit('revision 1', rev_id='1')
864
source = self.make_branch_and_tree('source')
865
# this gives us an incomplete repository
866
tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
867
1108
tree.commit('revision 2', rev_id='2', allow_pointless=True)
868
tree.bzrdir.open_branch().copy_content_into(source.branch)
869
tree.copy_content_into(source)
870
self.assertFalse(source.branch.repository.has_revision('2'))
872
1110
target = self.sproutOrSkip(dir, self.get_url('target'),
874
self.assertEqual('2', target.open_branch().last_revision())
1111
accelerator_tree=tree)
875
1112
self.assertEqual(['2'], target.open_workingtree().get_parent_ids())
876
self.assertTrue(target.open_branch().repository.has_revision('2'))
878
1114
def test_format_initialize_find_open(self):
879
1115
# loopback test to check the current format initializes to itself.
1027
1264
# because the default open will not open them and
1028
1265
# they may not be initializable.
1030
# this has to be tested with local access as we still support creating
1267
# this has to be tested with local access as we still support creating
1031
1268
# format 6 bzrdirs
1032
t = get_transport('.')
1033
made_control = self.bzrdir_format.initialize(t.base)
1034
made_repo = made_control.create_repository()
1035
made_branch = made_control.create_branch()
1036
made_tree = made_control.create_workingtree()
1269
t = self.get_transport()
1271
made_control = self.bzrdir_format.initialize(t.base)
1272
made_repo = made_control.create_repository()
1273
made_branch = made_control.create_branch()
1274
made_tree = made_control.create_workingtree()
1275
except errors.NotLocalUrl:
1276
raise TestSkipped("Can't initialize %r on transport %r"
1277
% (self.bzrdir_format, t))
1037
1278
opened_tree = made_control.open_workingtree()
1038
1279
self.assertEqual(made_control, opened_tree.bzrdir)
1039
1280
self.failUnless(isinstance(opened_tree, made_tree.__class__))
1222
1463
dir = self.make_bzrdir('.')
1223
1464
if dir.can_convert_format():
1224
1465
# if its default updatable there must be an updater
1225
# (we change the default to match the lastest known format
1226
# as downgrades may not be available
1227
old_format = bzrdir.BzrDirFormat.get_default_format()
1228
bzrdir.BzrDirFormat.set_default_format(dir._format)
1230
self.assertTrue(isinstance(dir._format.get_converter(),
1233
bzrdir.BzrDirFormat.set_default_format(old_format)
1466
# (we force the latest known format as downgrades may not be
1468
self.assertTrue(isinstance(dir._format.get_converter(
1469
format=dir._format), bzrdir.Converter))
1234
1470
dir.needs_format_conversion(None)
1236
1472
def test_upgrade_new_instance(self):
1242
1478
self.createWorkingTreeOrSkip(dir)
1243
1479
if dir.can_convert_format():
1244
1480
# if its default updatable there must be an updater
1245
# (we change the default to match the lastest known format
1246
# as downgrades may not be available
1247
old_format = bzrdir.BzrDirFormat.get_default_format()
1248
bzrdir.BzrDirFormat.set_default_format(dir._format)
1481
# (we force the latest known format as downgrades may not be
1249
1483
pb = ui.ui_factory.nested_progress_bar()
1251
dir._format.get_converter(None).convert(dir, pb)
1485
dir._format.get_converter(format=dir._format).convert(dir, pb)
1253
bzrdir.BzrDirFormat.set_default_format(old_format)
1255
1488
# and it should pass 'check' now.
1256
check(bzrdir.BzrDir.open(self.get_url('.')).open_branch(), False)
1489
check_branch(bzrdir.BzrDir.open(self.get_url('.')).open_branch(),
1258
1492
def test_format_description(self):
1259
1493
dir = self.make_bzrdir('.')
1260
1494
text = dir._format.get_format_description()
1261
1495
self.failUnless(len(text))
1497
def test_retire_bzrdir(self):
1498
bd = self.make_bzrdir('.')
1499
transport = bd.root_transport
1500
# must not overwrite existing directories
1501
self.build_tree(['.bzr.retired.0/', '.bzr.retired.0/junk',],
1502
transport=transport)
1503
self.failUnless(transport.has('.bzr'))
1505
self.failIf(transport.has('.bzr'))
1506
self.failUnless(transport.has('.bzr.retired.1'))
1508
def test_retire_bzrdir_limited(self):
1509
bd = self.make_bzrdir('.')
1510
transport = bd.root_transport
1511
# must not overwrite existing directories
1512
self.build_tree(['.bzr.retired.0/', '.bzr.retired.0/junk',],
1513
transport=transport)
1514
self.failUnless(transport.has('.bzr'))
1515
self.assertRaises((errors.FileExists, errors.DirectoryNotEmpty),
1516
bd.retire_bzrdir, limit=0)
1264
1519
class TestBreakLock(TestCaseWithBzrDir):
1317
1578
unused_repo = thisdir.create_repository()
1318
1579
master.lock_write()
1319
1580
unused_repo.lock_write()
1320
# two yes's : branch and repository. If the repo in this
1321
# dir is inappropriately accessed, 3 will be needed, and
1322
# we'll see that because the stream will be fully consumed
1323
bzrlib.ui.ui_factory.stdin = StringIO("y\ny\ny\n")
1324
master.bzrdir.break_lock()
1325
# only two ys should have been read
1326
self.assertEqual("y\n", bzrlib.ui.ui_factory.stdin.read())
1327
# we should be able to lock a newly opened branch now
1328
branch = master.bzrdir.open_branch()
1331
# we should not be able to lock the repository in thisdir as its still
1332
# held by the explicit lock we took, and the break lock should not have
1334
repo = thisdir.open_repository()
1335
self.assertRaises(errors.LockContention, repo.lock_write)
1336
unused_repo.unlock()
1582
# two yes's : branch and repository. If the repo in this
1583
# dir is inappropriately accessed, 3 will be needed, and
1584
# we'll see that because the stream will be fully consumed
1585
bzrlib.ui.ui_factory.stdin = StringIO("y\ny\ny\n")
1586
# determine if the repository will have been locked;
1587
this_repo_locked = \
1588
thisdir.open_repository().get_physical_lock_status()
1589
master.bzrdir.break_lock()
1590
if this_repo_locked:
1591
# only two ys should have been read
1592
self.assertEqual("y\n", bzrlib.ui.ui_factory.stdin.read())
1594
# only one y should have been read
1595
self.assertEqual("y\ny\n", bzrlib.ui.ui_factory.stdin.read())
1596
# we should be able to lock a newly opened branch now
1597
branch = master.bzrdir.open_branch()
1600
if this_repo_locked:
1601
# we should not be able to lock the repository in thisdir as
1602
# its still held by the explicit lock we took, and the break
1603
# lock should not have touched it.
1604
repo = thisdir.open_repository()
1605
self.assertRaises(errors.LockContention, repo.lock_write)
1607
unused_repo.unlock()
1337
1608
self.assertRaises(errors.LockBroken, master.unlock)
1339
1610
def test_break_lock_tree(self):
1359
1633
self.assertRaises(errors.LockBroken, tree.unlock)
1636
class TestTransportConfig(TestCaseWithBzrDir):
1638
def test_get_config(self):
1639
my_dir = self.make_bzrdir('.')
1640
config = my_dir.get_config()
1643
isinstance(my_dir, (bzrdir.BzrDirMeta1, RemoteBzrDir)),
1644
"%r should support configs" % my_dir)
1645
raise TestNotApplicable(
1646
'This BzrDir format does not support configs.')
1647
config.set_default_stack_on('http://example.com')
1648
self.assertEqual('http://example.com', config.get_default_stack_on())
1649
my_dir2 = bzrdir.BzrDir.open(self.get_url('.'))
1650
config2 = my_dir2.get_config()
1651
self.assertEqual('http://example.com', config2.get_default_stack_on())
1362
1654
class ChrootedBzrDirTests(ChrootedTestCase):
1364
1656
def test_find_repository_no_repository(self):