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
39
from bzrlib.check import check
28
import bzrlib.errors as errors
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.get_inventory_weave()
129
right_inv_weave = right_repo.get_inventory_weave()
130
self.assertEqual(set(left_inv_weave.versions()),
131
set(right_inv_weave.versions()))
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.versions()), set(all_revs))
137
left_trees = left_repo.revision_trees(all_revs)
138
right_trees = right_repo.revision_trees(all_revs)
139
for left_tree, right_tree in izip(left_trees, right_trees):
140
self.assertEqual(left_tree.inventory, right_tree.inventory)
142
text_index = left_repo._generate_text_key_index()
143
self.assertEqual(text_index,
144
right_repo._generate_text_key_index())
145
for file_id, revision_id in text_index.iterkeys():
146
left_weave = left_repo.weave_store.get_weave(
147
file_id, left_repo.get_transaction())
148
right_weave = right_repo.weave_store.get_weave(
149
file_id, right_repo.get_transaction())
151
left_weave.get_text(revision_id),
152
right_weave.get_text(revision_id))
154
for rev_id in all_revs:
156
left_text = left_repo.get_signature_text(rev_id)
157
except NoSuchRevision:
159
right_text = right_repo.get_signature_text(rev_id)
160
self.assertEqual(left_text, right_text)
108
166
def skipIfNoWorkingTree(self, a_bzrdir):
109
167
"""Raises TestSkipped if a_bzrdir doesn't have a working tree.
128
186
raise TestSkipped("cannot make working tree with transport %r"
129
187
% a_bzrdir.transport)
131
def sproutOrSkip(self, from_bzrdir, to_url, revision_id=None, basis=None,
132
force_new_repo=False):
189
def sproutOrSkip(self, from_bzrdir, to_url, revision_id=None,
190
force_new_repo=False, accelerator_tree=None):
133
191
"""Sprout from_bzrdir into to_url, or raise TestSkipped.
135
193
A simple wrapper for from_bzrdir.sprout that translates NotLocalUrl into
136
194
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:
196
to_transport = get_transport(to_url)
197
if not isinstance(to_transport, LocalTransport):
143
198
raise TestSkipped('Cannot sprout to remote bzrdirs.')
199
target = from_bzrdir.sprout(to_url, revision_id=revision_id,
200
force_new_repo=force_new_repo,
201
possible_transports=[to_transport],
202
accelerator_tree=accelerator_tree)
146
205
def test_create_null_workingtree(self):
147
206
dir = self.make_bzrdir('dir1')
148
207
dir.create_repository()
149
208
dir.create_branch()
150
wt = dir.create_workingtree(revision_id=bzrlib.revision.NULL_REVISION)
210
wt = dir.create_workingtree(revision_id=bzrlib.revision.NULL_REVISION)
211
except errors.NotLocalUrl:
212
raise TestSkipped("cannot make working tree with transport %r"
151
214
self.assertEqual([], wt.get_parent_ids())
216
def test_destroy_workingtree(self):
217
tree = self.make_branch_and_tree('tree')
218
self.build_tree(['tree/file'])
220
tree.commit('first commit')
223
bzrdir.destroy_workingtree()
224
except errors.UnsupportedOperation:
225
raise TestSkipped('Format does not support destroying tree')
226
self.failIfExists('tree/file')
227
self.assertRaises(errors.NoWorkingTree, bzrdir.open_workingtree)
228
bzrdir.create_workingtree()
229
self.failUnlessExists('tree/file')
230
bzrdir.destroy_workingtree_metadata()
231
self.failUnlessExists('tree/file')
232
self.assertRaises(errors.NoWorkingTree, bzrdir.open_workingtree)
234
def test_destroy_branch(self):
235
branch = self.make_branch('branch')
236
bzrdir = branch.bzrdir
238
bzrdir.destroy_branch()
239
except (errors.UnsupportedOperation, errors.TransportNotPossible):
240
raise TestNotApplicable('Format does not support destroying tree')
241
self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
242
bzrdir.create_branch()
245
def test_destroy_repository(self):
246
repo = self.make_repository('repository')
249
bzrdir.destroy_repository()
250
except (errors.UnsupportedOperation, errors.TransportNotPossible):
251
raise TestNotApplicable('Format does not support destroying'
253
self.assertRaises(errors.NoRepositoryPresent, bzrdir.open_repository)
254
bzrdir.create_repository()
255
bzrdir.open_repository()
257
def test_open_workingtree_raises_no_working_tree(self):
258
"""BzrDir.open_workingtree() should raise NoWorkingTree (rather than
259
e.g. NotLocalUrl) if there is no working tree.
261
dir = self.make_bzrdir('source')
262
vfs_dir = bzrdir.BzrDir.open(self.get_vfs_only_url('source'))
263
if vfs_dir.has_workingtree():
264
# This BzrDir format doesn't support BzrDirs without working trees,
265
# so this test is irrelevant.
267
self.assertRaises(errors.NoWorkingTree, dir.open_workingtree)
269
def test_clone_on_transport(self):
270
a_dir = self.make_bzrdir('source')
271
target_transport = a_dir.root_transport.clone('..').clone('target')
272
target = a_dir.clone_on_transport(target_transport)
273
self.assertNotEqual(a_dir.transport.base, target.transport.base)
274
self.assertDirectoriesEqual(a_dir.root_transport, target.root_transport,
275
['./.bzr/merge-hashes'])
153
277
def test_clone_bzrdir_empty(self):
154
278
dir = self.make_bzrdir('source')
155
279
target = dir.clone(self.get_url('target'))
156
280
self.assertNotEqual(dir.transport.base, target.transport.base)
157
self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
281
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
282
['./.bzr/merge-hashes'])
159
284
def test_clone_bzrdir_empty_force_new_ignored(self):
160
285
# the force_new_repo parameter should have no effect on an empty
198
326
self.assertRaises(errors.NoRepositoryPresent, target.open_repository)
200
328
def test_clone_bzrdir_repository_branch_both_under_shared(self):
329
# Create a shared repository
202
331
shared_repo = self.make_repository('shared', shared=True)
203
332
except errors.IncompatibleFormat:
334
# Make a branch, 'commit_tree', and working tree outside of the shared
335
# repository, and commit some revisions to it.
205
336
tree = self.make_branch_and_tree('commit_tree')
206
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
337
self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
208
339
tree.commit('revision 1', rev_id='1')
209
340
tree.bzrdir.open_branch().set_revision_history([])
210
341
tree.set_parent_trees([])
211
342
tree.commit('revision 2', rev_id='2')
212
tree.bzrdir.open_repository().copy_content_into(shared_repo)
343
# Copy the content (i.e. revisions) from the 'commit_tree' branch's
344
# repository into the shared repository.
345
tree.branch.repository.copy_content_into(shared_repo)
346
# Make a branch 'source' inside the shared repository.
213
347
dir = self.make_bzrdir('shared/source')
214
348
dir.create_branch()
349
# Clone 'source' to 'target', also inside the shared repository.
215
350
target = dir.clone(self.get_url('shared/target'))
351
# 'source', 'target', and the shared repo all have distinct bzrdirs.
216
352
self.assertNotEqual(dir.transport.base, target.transport.base)
217
353
self.assertNotEqual(dir.transport.base, shared_repo.bzrdir.transport.base)
354
# The shared repository will contain revisions from the 'commit_tree'
355
# repository, even revisions that are not part of the history of the
356
# 'commit_tree' branch.
218
357
self.assertTrue(shared_repo.has_revision('1'))
220
359
def test_clone_bzrdir_repository_branch_only_source_under_shared(self):
223
362
except errors.IncompatibleFormat:
225
364
tree = self.make_branch_and_tree('commit_tree')
226
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
365
self.build_tree(['commit_tree/foo'])
228
367
tree.commit('revision 1', rev_id='1')
229
tree.bzrdir.open_branch().set_revision_history([])
368
tree.branch.bzrdir.open_branch().set_revision_history([])
230
369
tree.set_parent_trees([])
231
370
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())
371
tree.branch.repository.copy_content_into(shared_repo)
372
if shared_repo.make_working_trees():
373
shared_repo.set_make_working_trees(False)
374
self.assertFalse(shared_repo.make_working_trees())
235
375
self.assertTrue(shared_repo.has_revision('1'))
236
376
dir = self.make_bzrdir('shared/source')
237
377
dir.create_branch()
268
409
# and clone it with a revision limit.
270
411
tree = self.make_branch_and_tree('commit_tree')
271
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
412
self.build_tree(['commit_tree/foo'])
273
414
tree.commit('revision 1', rev_id='1')
274
tree.bzrdir.open_branch().set_revision_history([])
415
tree.branch.bzrdir.open_branch().set_revision_history([])
275
416
tree.set_parent_trees([])
276
417
tree.commit('revision 2', rev_id='2')
277
418
source = self.make_repository('source')
278
tree.bzrdir.open_repository().copy_content_into(source)
419
tree.branch.repository.copy_content_into(source)
279
420
dir = source.bzrdir
280
421
target = dir.clone(self.get_url('target'), revision_id='2')
281
422
raise TestSkipped('revision limiting not strict yet')
283
424
def test_clone_bzrdir_branch_and_repo(self):
284
425
tree = self.make_branch_and_tree('commit_tree')
285
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
426
self.build_tree(['commit_tree/foo'])
287
428
tree.commit('revision 1')
288
429
source = self.make_branch('source')
289
tree.bzrdir.open_repository().copy_content_into(source.repository)
290
tree.bzrdir.open_branch().copy_content_into(source)
430
tree.branch.repository.copy_content_into(source.repository)
431
tree.branch.copy_content_into(source)
291
432
dir = source.bzrdir
292
433
target = dir.clone(self.get_url('target'))
293
434
self.assertNotEqual(dir.transport.base, target.transport.base)
294
435
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
295
['./.bzr/stat-cache',
437
'./.bzr/basis-inventory-cache',
296
438
'./.bzr/checkout/stat-cache',
297
'./.bzr/repository/inventory.knit',
439
'./.bzr/merge-hashes',
443
self.assertRepositoryHasSameItems(
444
tree.branch.repository, target.open_repository())
300
446
def test_clone_bzrdir_branch_and_repo_into_shared_repo(self):
301
447
# by default cloning into a shared repo uses the shared repo.
302
448
tree = self.make_branch_and_tree('commit_tree')
303
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
449
self.build_tree(['commit_tree/foo'])
305
451
tree.commit('revision 1')
306
452
source = self.make_branch('source')
307
tree.bzrdir.open_repository().copy_content_into(source.repository)
308
tree.bzrdir.open_branch().copy_content_into(source)
453
tree.branch.repository.copy_content_into(source.repository)
454
tree.branch.copy_content_into(source)
310
456
self.make_repository('target', shared=True)
311
457
except errors.IncompatibleFormat:
360
505
# and clone it with a revision limit.
362
507
tree = self.make_branch_and_tree('commit_tree')
363
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
508
self.build_tree(['commit_tree/foo'])
365
510
tree.commit('revision 1', rev_id='1')
366
511
tree.commit('revision 2', rev_id='2', allow_pointless=True)
367
512
source = self.make_branch('source')
368
tree.bzrdir.open_repository().copy_content_into(source.repository)
369
tree.bzrdir.open_branch().copy_content_into(source)
513
tree.branch.repository.copy_content_into(source.repository)
514
tree.branch.copy_content_into(source)
370
515
dir = source.bzrdir
371
516
target = dir.clone(self.get_url('target'), revision_id='1')
372
517
self.assertEqual('1', target.open_branch().last_revision())
374
519
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('..'))
520
tree = self.make_branch_and_tree('source')
521
self.build_tree(['source/foo'])
378
523
tree.commit('revision 1')
379
524
dir = tree.bzrdir
382
527
self.assertNotEqual(dir.transport.base, target.transport.base)
383
528
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
384
529
['./.bzr/stat-cache',
530
'./.bzr/checkout/dirstate',
385
531
'./.bzr/checkout/stat-cache',
386
'./.bzr/repository/inventory.knit',
532
'./.bzr/checkout/merge-hashes',
533
'./.bzr/merge-hashes',
536
self.assertRepositoryHasSameItems(tree.branch.repository,
537
target.open_repository())
538
target.open_workingtree().revert()
389
target.open_workingtree().revert([])
540
def test_clone_on_transport_preserves_repo_format(self):
541
if self.bzrdir_format == bzrdir.format_registry.make_bzrdir('default'):
545
source_branch = self.make_branch('source', format=format)
546
# Ensure no format data is cached
547
a_dir = bzrlib.branch.Branch.open_from_transport(
548
self.get_transport('source')).bzrdir
549
target_transport = a_dir.root_transport.clone('..').clone('target')
550
target_bzrdir = a_dir.clone_on_transport(target_transport)
551
target_repo = target_bzrdir.open_repository()
552
self.assertEqual(target_repo._format, source_branch.repository._format)
391
554
def test_revert_inventory(self):
392
tree = self.make_branch_and_tree('sourcce')
393
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
555
tree = self.make_branch_and_tree('source')
556
self.build_tree(['source/foo'])
395
558
tree.commit('revision 1')
396
559
dir = tree.bzrdir
398
561
self.skipIfNoWorkingTree(target)
399
562
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
400
563
['./.bzr/stat-cache',
564
'./.bzr/checkout/dirstate',
401
565
'./.bzr/checkout/stat-cache',
402
'./.bzr/repository/inventory.knit',
566
'./.bzr/checkout/merge-hashes',
567
'./.bzr/merge-hashes',
570
self.assertRepositoryHasSameItems(tree.branch.repository,
571
target.open_repository())
405
target.open_workingtree().revert([])
573
target.open_workingtree().revert()
406
574
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
407
575
['./.bzr/stat-cache',
576
'./.bzr/checkout/dirstate',
408
577
'./.bzr/checkout/stat-cache',
409
'./.bzr/repository/inventory.knit',
578
'./.bzr/checkout/merge-hashes',
579
'./.bzr/merge-hashes',
582
self.assertRepositoryHasSameItems(tree.branch.repository,
583
target.open_repository())
413
585
def test_clone_bzrdir_tree_branch_reference(self):
414
586
# a tree with a branch reference (aka a checkout)
447
621
self.skipIfNoWorkingTree(target)
448
622
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('..'))
624
def test_clone_bzrdir_into_notrees_repo(self):
625
"""Cloning into a no-trees repo should not create a working tree"""
626
tree = self.make_branch_and_tree('source')
627
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'))
629
tree.commit('revision 1')
632
repo = self.make_repository('repo', shared=True)
633
except errors.IncompatibleFormat:
634
raise TestNotApplicable('must support shared repositories')
635
if repo.make_working_trees():
636
repo.set_make_working_trees(False)
637
self.assertFalse(repo.make_working_trees())
640
a_dir = dir.clone(self.get_url('repo/a'))
642
self.assertRaises(errors.NoWorkingTree, a_dir.open_workingtree)
644
def test_get_branch_reference_on_reference(self):
645
"""get_branch_reference should return the right url."""
646
referenced_branch = self.make_branch('referenced')
647
dir = self.make_bzrdir('source')
649
reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
651
except errors.IncompatibleFormat:
652
# this is ok too, not all formats have to support references.
654
self.assertEqual(referenced_branch.bzrdir.root_transport.abspath('') + '/',
655
dir.get_branch_reference())
657
def test_get_branch_reference_on_non_reference(self):
658
"""get_branch_reference should return None for non-reference branches."""
659
branch = self.make_branch('referenced')
660
self.assertEqual(None, branch.bzrdir.get_branch_reference())
662
def test_get_branch_reference_no_branch(self):
663
"""get_branch_reference should not mask NotBranchErrors."""
664
dir = self.make_bzrdir('source')
666
# this format does not support branchless bzrdirs.
668
self.assertRaises(errors.NotBranchError, dir.get_branch_reference)
474
670
def test_sprout_bzrdir_empty(self):
475
671
dir = self.make_bzrdir('source')
515
716
repo = dir.create_repository()
516
717
repo.fetch(tree.branch.repository)
517
718
self.assertTrue(repo.has_revision('1'))
721
_mod_revision.is_null(_mod_revision.ensure_null(
722
dir.open_branch().last_revision())))
723
except errors.NotBranchError:
518
725
target = self.sproutOrSkip(dir, self.get_url('target'))
519
726
self.assertNotEqual(dir.transport.base, target.transport.base)
727
# testing inventory isn't reasonable for repositories
520
728
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
521
['./.bzr/repository/inventory.knit',
734
'./.bzr/repository/inventory.knit',
737
# If we happen to have a tree, we'll guarantee everything
738
# except for the tree root is the same.
739
inventory_f = file(dir.transport.base+'inventory', 'rb')
740
self.assertContainsRe(inventory_f.read(),
741
'<inventory file_id="TREE_ROOT[^"]*"'
742
' format="5">\n</inventory>\n')
745
if e.errno != errno.ENOENT:
524
748
def test_sprout_bzrdir_with_repository_to_shared(self):
525
749
tree = self.make_branch_and_tree('commit_tree')
526
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
750
self.build_tree(['commit_tree/foo'])
528
752
tree.commit('revision 1', rev_id='1')
529
753
tree.bzrdir.open_branch().set_revision_history([])
530
754
tree.set_parent_trees([])
531
755
tree.commit('revision 2', rev_id='2')
532
756
source = self.make_repository('source')
533
tree.bzrdir.open_repository().copy_content_into(source)
757
tree.branch.repository.copy_content_into(source)
534
758
dir = source.bzrdir
536
760
shared_repo = self.make_repository('target', shared=True)
566
790
except errors.IncompatibleFormat:
568
792
tree = self.make_branch_and_tree('commit_tree')
569
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
793
self.build_tree(['commit_tree/foo'])
571
795
tree.commit('revision 1', rev_id='1')
572
796
tree.bzrdir.open_branch().set_revision_history([])
573
797
tree.set_parent_trees([])
574
798
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())
799
tree.branch.repository.copy_content_into(shared_repo)
800
if shared_repo.make_working_trees():
801
shared_repo.set_make_working_trees(False)
802
self.assertFalse(shared_repo.make_working_trees())
578
803
self.assertTrue(shared_repo.has_revision('1'))
579
804
dir = self.make_bzrdir('shared/source')
580
805
dir.create_branch()
583
808
self.assertNotEqual(dir.transport.base, shared_repo.bzrdir.transport.base)
584
809
branch = target.open_branch()
585
810
self.assertTrue(branch.repository.has_revision('1'))
586
self.assertTrue(branch.repository.make_working_trees())
811
if not isinstance(branch.bzrdir, RemoteBzrDir):
812
self.assertTrue(branch.repository.make_working_trees())
587
813
self.assertFalse(branch.repository.is_shared())
589
815
def test_sprout_bzrdir_repository_under_shared_force_new_repo(self):
590
816
tree = self.make_branch_and_tree('commit_tree')
591
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
817
self.build_tree(['commit_tree/foo'])
593
819
tree.commit('revision 1', rev_id='1')
594
820
tree.bzrdir.open_branch().set_revision_history([])
595
821
tree.set_parent_trees([])
596
822
tree.commit('revision 2', rev_id='2')
597
823
source = self.make_repository('source')
598
tree.bzrdir.open_repository().copy_content_into(source)
824
tree.branch.repository.copy_content_into(source)
599
825
dir = source.bzrdir
601
827
shared_repo = self.make_repository('target', shared=True)
612
838
# and sprout it with a revision limit.
614
840
tree = self.make_branch_and_tree('commit_tree')
615
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
841
self.build_tree(['commit_tree/foo'])
617
843
tree.commit('revision 1', rev_id='1')
618
844
tree.bzrdir.open_branch().set_revision_history([])
619
845
tree.set_parent_trees([])
620
846
tree.commit('revision 2', rev_id='2')
621
847
source = self.make_repository('source')
622
tree.bzrdir.open_repository().copy_content_into(source)
848
tree.branch.repository.copy_content_into(source)
623
849
dir = source.bzrdir
624
850
target = self.sproutOrSkip(dir, self.get_url('target'), revision_id='2')
625
851
raise TestSkipped('revision limiting not strict yet')
627
853
def test_sprout_bzrdir_branch_and_repo(self):
628
854
tree = self.make_branch_and_tree('commit_tree')
629
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
855
self.build_tree(['commit_tree/foo'])
631
857
tree.commit('revision 1')
632
858
source = self.make_branch('source')
633
tree.bzrdir.open_repository().copy_content_into(source.repository)
859
tree.branch.repository.copy_content_into(source.repository)
634
860
tree.bzrdir.open_branch().copy_content_into(source)
635
861
dir = source.bzrdir
636
862
target = self.sproutOrSkip(dir, self.get_url('target'))
637
863
self.assertNotEqual(dir.transport.base, target.transport.base)
638
864
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
639
['./.bzr/stat-cache',
866
'./.bzr/basis-inventory-cache',
867
'./.bzr/branch/branch.conf',
868
'./.bzr/branch/parent',
870
'./.bzr/checkout/inventory',
640
871
'./.bzr/checkout/stat-cache',
641
872
'./.bzr/inventory',
642
'./.bzr/checkout/inventory',
643
874
'./.bzr/repository/inventory.knit',
646
879
def test_sprout_bzrdir_branch_and_repo_shared(self):
647
880
# sprouting a branch with a repo into a shared repo uses the shared
649
882
tree = self.make_branch_and_tree('commit_tree')
650
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
883
self.build_tree(['commit_tree/foo'])
652
885
tree.commit('revision 1', rev_id='1')
653
886
source = self.make_branch('source')
654
tree.bzrdir.open_repository().copy_content_into(source.repository)
887
tree.branch.repository.copy_content_into(source.repository)
655
888
tree.bzrdir.open_branch().copy_content_into(source)
656
889
dir = source.bzrdir
758
991
# and sprout it with a revision limit.
760
993
tree = self.make_branch_and_tree('commit_tree')
761
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
994
self.build_tree(['commit_tree/foo'])
763
996
tree.commit('revision 1', rev_id='1')
764
997
tree.commit('revision 2', rev_id='2', allow_pointless=True)
765
998
source = self.make_branch('source')
766
tree.bzrdir.open_repository().copy_content_into(source.repository)
999
tree.branch.repository.copy_content_into(source.repository)
767
1000
tree.bzrdir.open_branch().copy_content_into(source)
768
1001
dir = source.bzrdir
769
1002
target = self.sproutOrSkip(dir, self.get_url('target'), revision_id='1')
770
1003
self.assertEqual('1', target.open_branch().last_revision())
772
1005
def test_sprout_bzrdir_tree_branch_repo(self):
773
tree = self.make_branch_and_tree('sourcce')
1006
tree = self.make_branch_and_tree('source')
774
1007
self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
776
1009
tree.commit('revision 1')
778
1011
target = self.sproutOrSkip(dir, self.get_url('target'))
779
1012
self.assertNotEqual(dir.transport.base, target.transport.base)
780
1013
self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
781
['./.bzr/stat-cache',
1015
'./.bzr/branch/branch.conf',
1016
'./.bzr/branch/parent',
1017
'./.bzr/checkout/dirstate',
782
1018
'./.bzr/checkout/stat-cache',
1019
'./.bzr/checkout/inventory',
783
1020
'./.bzr/inventory',
784
'./.bzr/checkout/inventory',
785
'./.bzr/repository/inventory.knit',
1022
'./.bzr/repository',
1023
'./.bzr/stat-cache',
1025
self.assertRepositoryHasSameItems(
1026
tree.branch.repository, target.open_repository())
788
1028
def test_sprout_bzrdir_tree_branch_reference(self):
789
1029
# sprouting should create a repository if needed and a sprouted branch.
855
1095
target = self.sproutOrSkip(dir, self.get_url('target'), revision_id='1')
856
1096
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)
1098
def test_sprout_takes_accelerator(self):
1099
tree = self.make_branch_and_tree('source')
1100
self.build_tree(['source/foo'])
863
1102
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
1103
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
1105
target = self.sproutOrSkip(dir, self.get_url('target'),
874
self.assertEqual('2', target.open_branch().last_revision())
1106
accelerator_tree=tree)
875
1107
self.assertEqual(['2'], target.open_workingtree().get_parent_ids())
876
self.assertTrue(target.open_branch().repository.has_revision('2'))
878
1109
def test_format_initialize_find_open(self):
879
1110
# loopback test to check the current format initializes to itself.
1027
1259
# because the default open will not open them and
1028
1260
# they may not be initializable.
1030
# this has to be tested with local access as we still support creating
1262
# this has to be tested with local access as we still support creating
1031
1263
# 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()
1264
t = self.get_transport()
1266
made_control = self.bzrdir_format.initialize(t.base)
1267
made_repo = made_control.create_repository()
1268
made_branch = made_control.create_branch()
1269
made_tree = made_control.create_workingtree()
1270
except errors.NotLocalUrl:
1271
raise TestSkipped("Can't initialize %r on transport %r"
1272
% (self.bzrdir_format, t))
1037
1273
opened_tree = made_control.open_workingtree()
1038
1274
self.assertEqual(made_control, opened_tree.bzrdir)
1039
1275
self.failUnless(isinstance(opened_tree, made_tree.__class__))
1222
1458
dir = self.make_bzrdir('.')
1223
1459
if dir.can_convert_format():
1224
1460
# 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)
1461
# (we force the latest known format as downgrades may not be
1463
self.assertTrue(isinstance(dir._format.get_converter(
1464
format=dir._format), bzrdir.Converter))
1234
1465
dir.needs_format_conversion(None)
1236
1467
def test_upgrade_new_instance(self):
1242
1473
self.createWorkingTreeOrSkip(dir)
1243
1474
if dir.can_convert_format():
1244
1475
# 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)
1476
# (we force the latest known format as downgrades may not be
1249
1478
pb = ui.ui_factory.nested_progress_bar()
1251
dir._format.get_converter(None).convert(dir, pb)
1480
dir._format.get_converter(format=dir._format).convert(dir, pb)
1253
bzrdir.BzrDirFormat.set_default_format(old_format)
1255
1483
# and it should pass 'check' now.
1256
1484
check(bzrdir.BzrDir.open(self.get_url('.')).open_branch(), False)
1260
1488
text = dir._format.get_format_description()
1261
1489
self.failUnless(len(text))
1491
def test_retire_bzrdir(self):
1492
bd = self.make_bzrdir('.')
1493
transport = bd.root_transport
1494
# must not overwrite existing directories
1495
self.build_tree(['.bzr.retired.0/', '.bzr.retired.0/junk',],
1496
transport=transport)
1497
self.failUnless(transport.has('.bzr'))
1499
self.failIf(transport.has('.bzr'))
1500
self.failUnless(transport.has('.bzr.retired.1'))
1502
def test_retire_bzrdir_limited(self):
1503
bd = self.make_bzrdir('.')
1504
transport = bd.root_transport
1505
# must not overwrite existing directories
1506
self.build_tree(['.bzr.retired.0/', '.bzr.retired.0/junk',],
1507
transport=transport)
1508
self.failUnless(transport.has('.bzr'))
1509
self.assertRaises((errors.FileExists, errors.DirectoryNotEmpty),
1510
bd.retire_bzrdir, limit=0)
1264
1513
class TestBreakLock(TestCaseWithBzrDir):
1317
1572
unused_repo = thisdir.create_repository()
1318
1573
master.lock_write()
1319
1574
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()
1576
# two yes's : branch and repository. If the repo in this
1577
# dir is inappropriately accessed, 3 will be needed, and
1578
# we'll see that because the stream will be fully consumed
1579
bzrlib.ui.ui_factory.stdin = StringIO("y\ny\ny\n")
1580
# determine if the repository will have been locked;
1581
this_repo_locked = \
1582
thisdir.open_repository().get_physical_lock_status()
1583
master.bzrdir.break_lock()
1584
if this_repo_locked:
1585
# only two ys should have been read
1586
self.assertEqual("y\n", bzrlib.ui.ui_factory.stdin.read())
1588
# only one y should have been read
1589
self.assertEqual("y\ny\n", bzrlib.ui.ui_factory.stdin.read())
1590
# we should be able to lock a newly opened branch now
1591
branch = master.bzrdir.open_branch()
1594
if this_repo_locked:
1595
# we should not be able to lock the repository in thisdir as
1596
# its still held by the explicit lock we took, and the break
1597
# lock should not have touched it.
1598
repo = thisdir.open_repository()
1599
self.assertRaises(errors.LockContention, repo.lock_write)
1601
unused_repo.unlock()
1337
1602
self.assertRaises(errors.LockBroken, master.unlock)
1339
1604
def test_break_lock_tree(self):