~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/bzrdir_implementations/test_bzrdir.py

  • Committer: Robert Collins
  • Date: 2007-07-04 08:08:13 UTC
  • mfrom: (2572 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2587.
  • Revision ID: robertc@robertcollins.net-20070704080813-wzebx0r88fvwj5rq
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Tests for bzrdir implementations - tests a bzrdir format."""
18
18
 
19
19
from cStringIO import StringIO
 
20
import errno
20
21
import os
21
22
from stat import S_ISDIR
22
23
import sys
47
48
                          TestCaseWithTransport,
48
49
                          TestSkipped,
49
50
                          )
 
51
from bzrlib.tests.bzrdir_implementations import TestCaseWithBzrDir
50
52
from bzrlib.trace import mutter
51
53
from bzrlib.transport import get_transport
52
54
from bzrlib.upgrade import upgrade
53
 
 
54
 
 
55
 
class TestCaseWithBzrDir(TestCaseWithTransport):
56
 
 
57
 
    def setUp(self):
58
 
        super(TestCaseWithBzrDir, self).setUp()
59
 
        self.bzrdir = None
60
 
 
61
 
    def get_bzrdir(self):
62
 
        if self.bzrdir is None:
63
 
            self.bzrdir = self.make_bzrdir(None)
64
 
        return self.bzrdir
65
 
 
66
 
    def make_bzrdir(self, relpath, format=None):
67
 
        return super(TestCaseWithBzrDir, self).make_bzrdir(
68
 
            relpath, format=self.bzrdir_format)
69
 
 
 
55
from bzrlib.remote import RemoteBzrDir
 
56
from bzrlib.repofmt import weaverepo
70
57
 
71
58
 
72
59
class TestBzrDir(TestCaseWithBzrDir):
95
82
        directories = ['.']
96
83
        while directories:
97
84
            dir = directories.pop()
98
 
            for path in source.list_dir(dir):
 
85
            for path in set(source.list_dir(dir) + target.list_dir(dir)):
99
86
                path = dir + '/' + path
100
87
                if path in ignore_list:
101
88
                    continue
102
 
                stat = source.stat(path)
 
89
                try:
 
90
                    stat = source.stat(path)
 
91
                except errors.NoSuchFile:
 
92
                    self.fail('%s not in source' % path)
103
93
                if S_ISDIR(stat.st_mode):
104
94
                    self.assertTrue(S_ISDIR(target.stat(path).st_mode))
105
95
                    directories.append(path)
131
121
            raise TestSkipped("cannot make working tree with transport %r"
132
122
                              % a_bzrdir.transport)
133
123
 
134
 
    def sproutOrSkip(self, from_bzrdir, to_url, revision_id=None, basis=None,
 
124
    def sproutOrSkip(self, from_bzrdir, to_url, revision_id=None,
135
125
                     force_new_repo=False):
136
126
        """Sprout from_bzrdir into to_url, or raise TestSkipped.
137
127
        
140
130
        """
141
131
        try:
142
132
            target = from_bzrdir.sprout(to_url, revision_id=revision_id,
143
 
                                        basis=basis,
144
133
                                        force_new_repo=force_new_repo)
145
134
        except errors.NotLocalUrl:
146
135
            raise TestSkipped('Cannot sprout to remote bzrdirs.')
150
139
        dir = self.make_bzrdir('dir1')
151
140
        dir.create_repository()
152
141
        dir.create_branch()
153
 
        wt = dir.create_workingtree(revision_id=bzrlib.revision.NULL_REVISION)
 
142
        try:
 
143
            wt = dir.create_workingtree(revision_id=bzrlib.revision.NULL_REVISION)
 
144
        except errors.NotLocalUrl:
 
145
            raise TestSkipped("cannot make working tree with transport %r"
 
146
                              % dir.transport)
154
147
        self.assertEqual([], wt.get_parent_ids())
155
148
 
 
149
    def test_destroy_workingtree(self):
 
150
        tree = self.make_branch_and_tree('tree')
 
151
        self.build_tree(['tree/file'])
 
152
        tree.add('file')
 
153
        tree.commit('first commit')
 
154
        bzrdir = tree.bzrdir
 
155
        try:
 
156
            bzrdir.destroy_workingtree()
 
157
        except errors.UnsupportedOperation:
 
158
            raise TestSkipped('Format does not support destroying tree')
 
159
        self.failIfExists('tree/file')
 
160
        self.assertRaises(errors.NoWorkingTree, bzrdir.open_workingtree)
 
161
        bzrdir.create_workingtree()
 
162
        self.failUnlessExists('tree/file')
 
163
        bzrdir.destroy_workingtree_metadata()
 
164
        self.failUnlessExists('tree/file')
 
165
        self.assertRaises(errors.NoWorkingTree, bzrdir.open_workingtree)
 
166
 
 
167
    def test_open_workingtree_raises_no_working_tree(self):
 
168
        """BzrDir.open_workingtree() should raise NoWorkingTree (rather than
 
169
        e.g. NotLocalUrl) if there is no working tree.
 
170
        """
 
171
        dir = self.make_bzrdir('source')
 
172
        vfs_dir = bzrdir.BzrDir.open(self.get_vfs_only_url('source'))
 
173
        if vfs_dir.has_workingtree():
 
174
            # This BzrDir format doesn't support BzrDirs without working trees,
 
175
            # so this test is irrelevant.
 
176
            return
 
177
        self.assertRaises(errors.NoWorkingTree, dir.open_workingtree)
 
178
 
 
179
    def test_clone_on_transport(self):
 
180
        a_dir = self.make_bzrdir('source')
 
181
        target_transport = a_dir.root_transport.clone('..').clone('target')
 
182
        target = a_dir.clone_on_transport(target_transport)
 
183
        self.assertNotEqual(a_dir.transport.base, target.transport.base)
 
184
        self.assertDirectoriesEqual(a_dir.root_transport, target.root_transport,
 
185
                                    ['./.bzr/merge-hashes'])
 
186
 
156
187
    def test_clone_bzrdir_empty(self):
157
188
        dir = self.make_bzrdir('source')
158
189
        target = dir.clone(self.get_url('target'))
159
190
        self.assertNotEqual(dir.transport.base, target.transport.base)
160
 
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
191
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
192
                                    ['./.bzr/merge-hashes'])
161
193
    
162
194
    def test_clone_bzrdir_empty_force_new_ignored(self):
163
195
        # the force_new_repo parameter should have no effect on an empty
165
197
        dir = self.make_bzrdir('source')
166
198
        target = dir.clone(self.get_url('target'), force_new_repo=True)
167
199
        self.assertNotEqual(dir.transport.base, target.transport.base)
168
 
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
200
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
201
                                    ['./.bzr/merge-hashes'])
169
202
    
170
203
    def test_clone_bzrdir_repository(self):
171
204
        tree = self.make_branch_and_tree('commit_tree')
179
212
        target = dir.clone(self.get_url('target'))
180
213
        self.assertNotEqual(dir.transport.base, target.transport.base)
181
214
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
182
 
                                    ['./.bzr/repository/inventory.knit',
 
215
                                    [
 
216
                                     './.bzr/merge-hashes',
 
217
                                     './.bzr/repository/inventory.knit',
183
218
                                     ])
184
219
 
185
220
 
201
236
        self.assertRaises(errors.NoRepositoryPresent, target.open_repository)
202
237
 
203
238
    def test_clone_bzrdir_repository_branch_both_under_shared(self):
 
239
        # Create a shared repository
204
240
        try:
205
241
            shared_repo = self.make_repository('shared', shared=True)
206
242
        except errors.IncompatibleFormat:
207
243
            return
 
244
        # Make a branch, 'commit_tree', and working tree outside of the shared
 
245
        # repository, and commit some revisions to it.
208
246
        tree = self.make_branch_and_tree('commit_tree')
209
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
247
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
210
248
        tree.add('foo')
211
249
        tree.commit('revision 1', rev_id='1')
212
250
        tree.bzrdir.open_branch().set_revision_history([])
213
251
        tree.set_parent_trees([])
214
252
        tree.commit('revision 2', rev_id='2')
215
 
        tree.bzrdir.open_repository().copy_content_into(shared_repo)
 
253
        # Copy the content (i.e. revisions) from the 'commit_tree' branch's
 
254
        # repository into the shared repository.
 
255
        tree.branch.repository.copy_content_into(shared_repo)
 
256
        # Make a branch 'source' inside the shared repository.
216
257
        dir = self.make_bzrdir('shared/source')
217
258
        dir.create_branch()
 
259
        # Clone 'source' to 'target', also inside the shared repository.
218
260
        target = dir.clone(self.get_url('shared/target'))
 
261
        # 'source', 'target', and the shared repo all have distinct bzrdirs.
219
262
        self.assertNotEqual(dir.transport.base, target.transport.base)
220
263
        self.assertNotEqual(dir.transport.base, shared_repo.bzrdir.transport.base)
 
264
        # The shared repository will contain revisions from the 'commit_tree'
 
265
        # repository, even revisions that are not part of the history of the
 
266
        # 'commit_tree' branch.
221
267
        self.assertTrue(shared_repo.has_revision('1'))
222
268
 
223
269
    def test_clone_bzrdir_repository_branch_only_source_under_shared(self):
226
272
        except errors.IncompatibleFormat:
227
273
            return
228
274
        tree = self.make_branch_and_tree('commit_tree')
229
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
275
        self.build_tree(['commit_tree/foo'])
230
276
        tree.add('foo')
231
277
        tree.commit('revision 1', rev_id='1')
232
 
        tree.bzrdir.open_branch().set_revision_history([])
 
278
        tree.branch.bzrdir.open_branch().set_revision_history([])
233
279
        tree.set_parent_trees([])
234
280
        tree.commit('revision 2', rev_id='2')
235
 
        tree.bzrdir.open_repository().copy_content_into(shared_repo)
236
 
        shared_repo.set_make_working_trees(False)
237
 
        self.assertFalse(shared_repo.make_working_trees())
 
281
        tree.branch.repository.copy_content_into(shared_repo)
 
282
        if shared_repo.make_working_trees():
 
283
            shared_repo.set_make_working_trees(False)
 
284
            self.assertFalse(shared_repo.make_working_trees())
238
285
        self.assertTrue(shared_repo.has_revision('1'))
239
286
        dir = self.make_bzrdir('shared/source')
240
287
        dir.create_branch()
248
295
        
249
296
    def test_clone_bzrdir_repository_under_shared_force_new_repo(self):
250
297
        tree = self.make_branch_and_tree('commit_tree')
251
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
298
        self.build_tree(['commit_tree/foo'])
252
299
        tree.add('foo')
253
300
        tree.commit('revision 1', rev_id='1')
254
301
        dir = self.make_bzrdir('source')
271
318
        # and clone it with a revision limit.
272
319
        # 
273
320
        tree = self.make_branch_and_tree('commit_tree')
274
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
321
        self.build_tree(['commit_tree/foo'])
275
322
        tree.add('foo')
276
323
        tree.commit('revision 1', rev_id='1')
277
 
        tree.bzrdir.open_branch().set_revision_history([])
 
324
        tree.branch.bzrdir.open_branch().set_revision_history([])
278
325
        tree.set_parent_trees([])
279
326
        tree.commit('revision 2', rev_id='2')
280
327
        source = self.make_repository('source')
281
 
        tree.bzrdir.open_repository().copy_content_into(source)
 
328
        tree.branch.repository.copy_content_into(source)
282
329
        dir = source.bzrdir
283
330
        target = dir.clone(self.get_url('target'), revision_id='2')
284
331
        raise TestSkipped('revision limiting not strict yet')
285
332
 
286
333
    def test_clone_bzrdir_branch_and_repo(self):
287
334
        tree = self.make_branch_and_tree('commit_tree')
288
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
335
        self.build_tree(['commit_tree/foo'])
289
336
        tree.add('foo')
290
337
        tree.commit('revision 1')
291
338
        source = self.make_branch('source')
292
 
        tree.bzrdir.open_repository().copy_content_into(source.repository)
293
 
        tree.bzrdir.open_branch().copy_content_into(source)
 
339
        tree.branch.repository.copy_content_into(source.repository)
 
340
        tree.branch.copy_content_into(source)
294
341
        dir = source.bzrdir
295
342
        target = dir.clone(self.get_url('target'))
296
343
        self.assertNotEqual(dir.transport.base, target.transport.base)
297
344
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
298
 
                                    ['./.bzr/stat-cache',
 
345
                                    [
 
346
                                     './.bzr/basis-inventory-cache',
299
347
                                     './.bzr/checkout/stat-cache',
 
348
                                     './.bzr/merge-hashes',
300
349
                                     './.bzr/repository/inventory.knit',
301
 
                                     ])
 
350
                                     './.bzr/stat-cache',
 
351
                                    ])
302
352
 
303
353
    def test_clone_bzrdir_branch_and_repo_into_shared_repo(self):
304
354
        # by default cloning into a shared repo uses the shared repo.
305
355
        tree = self.make_branch_and_tree('commit_tree')
306
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
356
        self.build_tree(['commit_tree/foo'])
307
357
        tree.add('foo')
308
358
        tree.commit('revision 1')
309
359
        source = self.make_branch('source')
310
 
        tree.bzrdir.open_repository().copy_content_into(source.repository)
311
 
        tree.bzrdir.open_branch().copy_content_into(source)
 
360
        tree.branch.repository.copy_content_into(source.repository)
 
361
        tree.branch.copy_content_into(source)
312
362
        try:
313
363
            self.make_repository('target', shared=True)
314
364
        except errors.IncompatibleFormat:
323
373
    def test_clone_bzrdir_branch_and_repo_into_shared_repo_force_new_repo(self):
324
374
        # by default cloning into a shared repo uses the shared repo.
325
375
        tree = self.make_branch_and_tree('commit_tree')
326
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
376
        self.build_tree(['commit_tree/foo'])
327
377
        tree.add('foo')
328
378
        tree.commit('revision 1')
329
379
        source = self.make_branch('source')
330
 
        tree.bzrdir.open_repository().copy_content_into(source.repository)
331
 
        tree.bzrdir.open_branch().copy_content_into(source)
 
380
        tree.branch.repository.copy_content_into(source.repository)
 
381
        tree.branch.copy_content_into(source)
332
382
        try:
333
383
            self.make_repository('target', shared=True)
334
384
        except errors.IncompatibleFormat:
363
413
        # and clone it with a revision limit.
364
414
        # 
365
415
        tree = self.make_branch_and_tree('commit_tree')
366
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
416
        self.build_tree(['commit_tree/foo'])
367
417
        tree.add('foo')
368
418
        tree.commit('revision 1', rev_id='1')
369
419
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
370
420
        source = self.make_branch('source')
371
 
        tree.bzrdir.open_repository().copy_content_into(source.repository)
372
 
        tree.bzrdir.open_branch().copy_content_into(source)
 
421
        tree.branch.repository.copy_content_into(source.repository)
 
422
        tree.branch.copy_content_into(source)
373
423
        dir = source.bzrdir
374
424
        target = dir.clone(self.get_url('target'), revision_id='1')
375
425
        self.assertEqual('1', target.open_branch().last_revision())
376
426
        
377
427
    def test_clone_bzrdir_tree_branch_repo(self):
378
 
        tree = self.make_branch_and_tree('sourcce')
379
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
428
        tree = self.make_branch_and_tree('source')
 
429
        self.build_tree(['source/foo'])
380
430
        tree.add('foo')
381
431
        tree.commit('revision 1')
382
432
        dir = tree.bzrdir
385
435
        self.assertNotEqual(dir.transport.base, target.transport.base)
386
436
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
387
437
                                    ['./.bzr/stat-cache',
 
438
                                     './.bzr/checkout/dirstate',
388
439
                                     './.bzr/checkout/stat-cache',
 
440
                                     './.bzr/checkout/merge-hashes',
 
441
                                     './.bzr/merge-hashes',
389
442
                                     './.bzr/repository/inventory.knit',
390
443
                                     ])
391
444
 
392
445
        target.open_workingtree().revert([])
393
446
 
394
447
    def test_revert_inventory(self):
395
 
        tree = self.make_branch_and_tree('sourcce')
396
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
448
        tree = self.make_branch_and_tree('source')
 
449
        self.build_tree(['source/foo'])
397
450
        tree.add('foo')
398
451
        tree.commit('revision 1')
399
452
        dir = tree.bzrdir
401
454
        self.skipIfNoWorkingTree(target)
402
455
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
403
456
                                    ['./.bzr/stat-cache',
 
457
                                     './.bzr/checkout/dirstate',
404
458
                                     './.bzr/checkout/stat-cache',
 
459
                                     './.bzr/checkout/merge-hashes',
 
460
                                     './.bzr/merge-hashes',
405
461
                                     './.bzr/repository/inventory.knit',
406
462
                                     ])
407
463
 
408
464
        target.open_workingtree().revert([])
409
465
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
410
466
                                    ['./.bzr/stat-cache',
 
467
                                     './.bzr/checkout/dirstate',
411
468
                                     './.bzr/checkout/stat-cache',
 
469
                                     './.bzr/checkout/merge-hashes',
 
470
                                     './.bzr/merge-hashes',
412
471
                                     './.bzr/repository/inventory.knit',
413
472
                                     ])
414
473
 
415
 
 
416
474
    def test_clone_bzrdir_tree_branch_reference(self):
417
475
        # a tree with a branch reference (aka a checkout) 
418
476
        # should stay a checkout on clone.
431
489
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
432
490
                                    ['./.bzr/stat-cache',
433
491
                                     './.bzr/checkout/stat-cache',
 
492
                                     './.bzr/checkout/merge-hashes',
 
493
                                     './.bzr/merge-hashes',
434
494
                                     './.bzr/repository/inventory.knit',
435
495
                                     ])
436
496
 
441
501
        # This smoke test just checks the revision-id is right. Tree specific
442
502
        # tests will check corner cases.
443
503
        tree = self.make_branch_and_tree('source')
444
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
504
        self.build_tree(['source/foo'])
445
505
        tree.add('foo')
446
506
        tree.commit('revision 1', rev_id='1')
447
507
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
450
510
        self.skipIfNoWorkingTree(target)
451
511
        self.assertEqual(['1'], target.open_workingtree().get_parent_ids())
452
512
 
453
 
    def test_clone_bzrdir_incomplete_source_with_basis(self):
454
 
        # ensure that basis really does grab from the basis by having incomplete source
455
 
        tree = self.make_branch_and_tree('commit_tree')
456
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
457
 
        tree.add('foo')
458
 
        tree.commit('revision 1', rev_id='1')
459
 
        source = self.make_branch_and_tree('source')
460
 
        # this gives us an incomplete repository
461
 
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
462
 
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
463
 
        tree.bzrdir.open_branch().copy_content_into(source.branch)
464
 
        tree.copy_content_into(source)
465
 
        self.assertFalse(source.branch.repository.has_revision('2'))
466
 
        dir = source.bzrdir
467
 
        target = dir.clone(self.get_url('target'), basis=tree.bzrdir)
468
 
        self.assertEqual('2', target.open_branch().last_revision())
 
513
    def test_get_branch_reference_on_reference(self):
 
514
        """get_branch_reference should return the right url."""
 
515
        referenced_branch = self.make_branch('referenced')
 
516
        dir = self.make_bzrdir('source')
469
517
        try:
470
 
            self.assertEqual(['2'], target.open_workingtree().get_parent_ids())
471
 
        except errors.NoWorkingTree:
472
 
            # It should have a working tree if it's able to have one, so if
473
 
            # we're here make sure it really can't have one.
474
 
            self.assertRaises(errors.NotLocalUrl, target.create_workingtree)
475
 
        self.assertTrue(target.open_branch().repository.has_revision('2'))
 
518
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
 
519
                referenced_branch)
 
520
        except errors.IncompatibleFormat:
 
521
            # this is ok too, not all formats have to support references.
 
522
            return
 
523
        self.assertEqual(referenced_branch.bzrdir.root_transport.abspath('') + '/',
 
524
            dir.get_branch_reference())
 
525
 
 
526
    def test_get_branch_reference_on_non_reference(self):
 
527
        """get_branch_reference should return None for non-reference branches."""
 
528
        branch = self.make_branch('referenced')
 
529
        self.assertEqual(None, branch.bzrdir.get_branch_reference())
 
530
 
 
531
    def test_get_branch_reference_no_branch(self):
 
532
        """get_branch_reference should not mask NotBranchErrors."""
 
533
        dir = self.make_bzrdir('source')
 
534
        if dir.has_branch():
 
535
            # this format does not support branchless bzrdirs.
 
536
            return
 
537
        self.assertRaises(errors.NotBranchError, dir.get_branch_reference)
476
538
 
477
539
    def test_sprout_bzrdir_empty(self):
478
540
        dir = self.make_bzrdir('source')
493
555
        target = self.sproutOrSkip(dir, self.get_url('target/child'))
494
556
        self.assertRaises(errors.NoRepositoryPresent, target.open_repository)
495
557
        target.open_branch()
496
 
        target.open_workingtree()
 
558
        try:
 
559
            target.open_workingtree()
 
560
        except errors.NoWorkingTree:
 
561
            # bzrdir's that never have working trees are allowed to pass;
 
562
            # whitelist them for now.
 
563
            self.assertIsInstance(target, RemoteBzrDir)
497
564
 
498
565
    def test_sprout_bzrdir_empty_under_shared_repo_force_new(self):
499
566
        # the force_new_repo parameter should force use of a new repo in an empty
518
585
        repo = dir.create_repository()
519
586
        repo.fetch(tree.branch.repository)
520
587
        self.assertTrue(repo.has_revision('1'))
 
588
        try:
 
589
            self.assertIs(dir.open_branch().last_revision(), None)
 
590
        except errors.NotBranchError:
 
591
            pass
521
592
        target = self.sproutOrSkip(dir, self.get_url('target'))
522
593
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
594
        # testing inventory isn't reasonable for repositories
523
595
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
524
 
                                    ['./.bzr/repository/inventory.knit',
 
596
                                    [
 
597
                                     './.bzr/branch',
 
598
                                     './.bzr/checkout',
 
599
                                     './.bzr/inventory',
 
600
                                     './.bzr/parent',
 
601
                                     './.bzr/repository/inventory.knit',
525
602
                                     ])
 
603
        try:
 
604
            # If we happen to have a tree, we'll guarantee everything
 
605
            # except for the tree root is the same.
 
606
            inventory_f = file(dir.transport.base+'inventory', 'rb')
 
607
            self.assertContainsRe(inventory_f.read(), 
 
608
                                  '<inventory file_id="TREE_ROOT[^"]*"'
 
609
                                  ' format="5">\n</inventory>\n')
 
610
            inventory_f.close()
 
611
        except IOError, e:
 
612
            if e.errno != errno.ENOENT:
 
613
                raise
526
614
 
527
615
    def test_sprout_bzrdir_with_repository_to_shared(self):
528
616
        tree = self.make_branch_and_tree('commit_tree')
529
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
617
        self.build_tree(['commit_tree/foo'])
530
618
        tree.add('foo')
531
619
        tree.commit('revision 1', rev_id='1')
532
620
        tree.bzrdir.open_branch().set_revision_history([])
533
621
        tree.set_parent_trees([])
534
622
        tree.commit('revision 2', rev_id='2')
535
623
        source = self.make_repository('source')
536
 
        tree.bzrdir.open_repository().copy_content_into(source)
 
624
        tree.branch.repository.copy_content_into(source)
537
625
        dir = source.bzrdir
538
626
        try:
539
627
            shared_repo = self.make_repository('target', shared=True)
549
637
        except errors.IncompatibleFormat:
550
638
            return
551
639
        tree = self.make_branch_and_tree('commit_tree')
552
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
640
        self.build_tree(['commit_tree/foo'])
553
641
        tree.add('foo')
554
642
        tree.commit('revision 1', rev_id='1')
555
643
        tree.bzrdir.open_branch().set_revision_history([])
556
644
        tree.set_parent_trees([])
557
645
        tree.commit('revision 2', rev_id='2')
558
 
        tree.bzrdir.open_repository().copy_content_into(shared_repo)
 
646
        tree.branch.repository.copy_content_into(shared_repo)
559
647
        dir = self.make_bzrdir('shared/source')
560
648
        dir.create_branch()
561
649
        target = self.sproutOrSkip(dir, self.get_url('shared/target'))
569
657
        except errors.IncompatibleFormat:
570
658
            return
571
659
        tree = self.make_branch_and_tree('commit_tree')
572
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
660
        self.build_tree(['commit_tree/foo'])
573
661
        tree.add('foo')
574
662
        tree.commit('revision 1', rev_id='1')
575
663
        tree.bzrdir.open_branch().set_revision_history([])
576
664
        tree.set_parent_trees([])
577
665
        tree.commit('revision 2', rev_id='2')
578
 
        tree.bzrdir.open_repository().copy_content_into(shared_repo)
579
 
        shared_repo.set_make_working_trees(False)
580
 
        self.assertFalse(shared_repo.make_working_trees())
 
666
        tree.branch.repository.copy_content_into(shared_repo)
 
667
        if shared_repo.make_working_trees():
 
668
            shared_repo.set_make_working_trees(False)
 
669
            self.assertFalse(shared_repo.make_working_trees())
581
670
        self.assertTrue(shared_repo.has_revision('1'))
582
671
        dir = self.make_bzrdir('shared/source')
583
672
        dir.create_branch()
586
675
        self.assertNotEqual(dir.transport.base, shared_repo.bzrdir.transport.base)
587
676
        branch = target.open_branch()
588
677
        self.assertTrue(branch.repository.has_revision('1'))
589
 
        self.assertTrue(branch.repository.make_working_trees())
 
678
        if not isinstance(branch.bzrdir, RemoteBzrDir):
 
679
            self.assertTrue(branch.repository.make_working_trees())
590
680
        self.assertFalse(branch.repository.is_shared())
591
681
 
592
682
    def test_sprout_bzrdir_repository_under_shared_force_new_repo(self):
593
683
        tree = self.make_branch_and_tree('commit_tree')
594
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
684
        self.build_tree(['commit_tree/foo'])
595
685
        tree.add('foo')
596
686
        tree.commit('revision 1', rev_id='1')
597
687
        tree.bzrdir.open_branch().set_revision_history([])
598
688
        tree.set_parent_trees([])
599
689
        tree.commit('revision 2', rev_id='2')
600
690
        source = self.make_repository('source')
601
 
        tree.bzrdir.open_repository().copy_content_into(source)
 
691
        tree.branch.repository.copy_content_into(source)
602
692
        dir = source.bzrdir
603
693
        try:
604
694
            shared_repo = self.make_repository('target', shared=True)
615
705
        # and sprout it with a revision limit.
616
706
        # 
617
707
        tree = self.make_branch_and_tree('commit_tree')
618
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
708
        self.build_tree(['commit_tree/foo'])
619
709
        tree.add('foo')
620
710
        tree.commit('revision 1', rev_id='1')
621
711
        tree.bzrdir.open_branch().set_revision_history([])
622
712
        tree.set_parent_trees([])
623
713
        tree.commit('revision 2', rev_id='2')
624
714
        source = self.make_repository('source')
625
 
        tree.bzrdir.open_repository().copy_content_into(source)
 
715
        tree.branch.repository.copy_content_into(source)
626
716
        dir = source.bzrdir
627
717
        target = self.sproutOrSkip(dir, self.get_url('target'), revision_id='2')
628
718
        raise TestSkipped('revision limiting not strict yet')
629
719
 
630
720
    def test_sprout_bzrdir_branch_and_repo(self):
631
721
        tree = self.make_branch_and_tree('commit_tree')
632
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
722
        self.build_tree(['commit_tree/foo'])
633
723
        tree.add('foo')
634
724
        tree.commit('revision 1')
635
725
        source = self.make_branch('source')
636
 
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
726
        tree.branch.repository.copy_content_into(source.repository)
637
727
        tree.bzrdir.open_branch().copy_content_into(source)
638
728
        dir = source.bzrdir
639
729
        target = self.sproutOrSkip(dir, self.get_url('target'))
640
730
        self.assertNotEqual(dir.transport.base, target.transport.base)
641
731
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
642
 
                                    ['./.bzr/stat-cache',
 
732
                                    [
 
733
                                     './.bzr/basis-inventory-cache',
 
734
                                     './.bzr/branch/branch.conf',
 
735
                                     './.bzr/branch/parent',
 
736
                                     './.bzr/checkout',
 
737
                                     './.bzr/checkout/inventory',
643
738
                                     './.bzr/checkout/stat-cache',
644
739
                                     './.bzr/inventory',
645
 
                                     './.bzr/checkout/inventory',
 
740
                                     './.bzr/parent',
646
741
                                     './.bzr/repository/inventory.knit',
 
742
                                     './.bzr/stat-cache',
 
743
                                     './foo',
647
744
                                     ])
648
745
 
649
746
    def test_sprout_bzrdir_branch_and_repo_shared(self):
650
747
        # sprouting a branch with a repo into a shared repo uses the shared
651
748
        # repo
652
749
        tree = self.make_branch_and_tree('commit_tree')
653
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
750
        self.build_tree(['commit_tree/foo'])
654
751
        tree.add('foo')
655
752
        tree.commit('revision 1', rev_id='1')
656
753
        source = self.make_branch('source')
657
 
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
754
        tree.branch.repository.copy_content_into(source.repository)
658
755
        tree.bzrdir.open_branch().copy_content_into(source)
659
756
        dir = source.bzrdir
660
757
        try:
668
765
        # sprouting a branch with a repo into a shared repo uses the shared
669
766
        # repo
670
767
        tree = self.make_branch_and_tree('commit_tree')
671
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
768
        self.build_tree(['commit_tree/foo'])
672
769
        tree.add('foo')
673
770
        tree.commit('revision 1', rev_id='1')
674
771
        source = self.make_branch('source')
675
 
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
772
        tree.branch.repository.copy_content_into(source.repository)
676
773
        tree.bzrdir.open_branch().copy_content_into(source)
677
774
        dir = source.bzrdir
678
775
        try:
761
858
        # and sprout it with a revision limit.
762
859
        # 
763
860
        tree = self.make_branch_and_tree('commit_tree')
764
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
861
        self.build_tree(['commit_tree/foo'])
765
862
        tree.add('foo')
766
863
        tree.commit('revision 1', rev_id='1')
767
864
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
768
865
        source = self.make_branch('source')
769
 
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
866
        tree.branch.repository.copy_content_into(source.repository)
770
867
        tree.bzrdir.open_branch().copy_content_into(source)
771
868
        dir = source.bzrdir
772
869
        target = self.sproutOrSkip(dir, self.get_url('target'), revision_id='1')
773
870
        self.assertEqual('1', target.open_branch().last_revision())
774
871
        
775
872
    def test_sprout_bzrdir_tree_branch_repo(self):
776
 
        tree = self.make_branch_and_tree('sourcce')
 
873
        tree = self.make_branch_and_tree('source')
777
874
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
778
875
        tree.add('foo')
779
876
        tree.commit('revision 1')
781
878
        target = self.sproutOrSkip(dir, self.get_url('target'))
782
879
        self.assertNotEqual(dir.transport.base, target.transport.base)
783
880
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
784
 
                                    ['./.bzr/stat-cache',
 
881
                                    [
 
882
                                     './.bzr/branch/branch.conf',
 
883
                                     './.bzr/branch/parent',
 
884
                                     './.bzr/checkout/dirstate',
785
885
                                     './.bzr/checkout/stat-cache',
 
886
                                     './.bzr/checkout/inventory',
786
887
                                     './.bzr/inventory',
787
 
                                     './.bzr/checkout/inventory',
 
888
                                     './.bzr/parent',
788
889
                                     './.bzr/repository/inventory.knit',
 
890
                                     './.bzr/stat-cache',
789
891
                                     ])
790
892
 
791
893
    def test_sprout_bzrdir_tree_branch_reference(self):
801
903
            return
802
904
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
803
905
        tree = self.createWorkingTreeOrSkip(dir)
804
 
        tree.bzrdir.root_transport.mkdir('subdir')
 
906
        self.build_tree(['source/subdir/'])
805
907
        tree.add('subdir')
806
908
        target = self.sproutOrSkip(dir, self.get_url('target'))
807
909
        self.assertNotEqual(dir.transport.base, target.transport.base)
827
929
            return
828
930
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
829
931
        tree = self.createWorkingTreeOrSkip(dir)
830
 
        self.build_tree(['foo'], transport=dir.root_transport)
 
932
        self.build_tree(['source/foo'])
831
933
        tree.add('foo')
832
934
        tree.commit('revision 1', rev_id='1')
833
935
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
850
952
        # This smoke test just checks the revision-id is right. Tree specific
851
953
        # tests will check corner cases.
852
954
        tree = self.make_branch_and_tree('source')
853
 
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
 
955
        self.build_tree(['source/foo'])
854
956
        tree.add('foo')
855
957
        tree.commit('revision 1', rev_id='1')
856
958
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
858
960
        target = self.sproutOrSkip(dir, self.get_url('target'), revision_id='1')
859
961
        self.assertEqual(['1'], target.open_workingtree().get_parent_ids())
860
962
 
861
 
    def test_sprout_bzrdir_incomplete_source_with_basis(self):
862
 
        # ensure that basis really does grab from the basis by having incomplete source
863
 
        tree = self.make_branch_and_tree('commit_tree')
864
 
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
865
 
        tree.add('foo')
866
 
        tree.commit('revision 1', rev_id='1')
867
 
        source = self.make_branch_and_tree('source')
868
 
        # this gives us an incomplete repository
869
 
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
870
 
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
871
 
        tree.bzrdir.open_branch().copy_content_into(source.branch)
872
 
        tree.copy_content_into(source)
873
 
        self.assertFalse(source.branch.repository.has_revision('2'))
874
 
        dir = source.bzrdir
875
 
        target = self.sproutOrSkip(dir, self.get_url('target'),
876
 
                                   basis=tree.bzrdir)
877
 
        self.assertEqual('2', target.open_branch().last_revision())
878
 
        self.assertEqual(['2'], target.open_workingtree().get_parent_ids())
879
 
        self.assertTrue(target.open_branch().repository.has_revision('2'))
880
 
 
881
963
    def test_format_initialize_find_open(self):
882
964
        # loopback test to check the current format initializes to itself.
883
965
        if not self.bzrdir_format.is_supported():
945
1027
        t = get_transport(self.get_url())
946
1028
        made_control = self.bzrdir_format.initialize(t.base)
947
1029
        made_repo = made_control.create_repository()
948
 
        self.failUnless(isinstance(made_repo, repository.Repository))
 
1030
        # Check that we have a repository object.
 
1031
        made_repo.has_revision('foo')
949
1032
        self.assertEqual(made_control, made_repo.bzrdir)
950
1033
 
951
1034
    def test_create_repository_shared(self):
1013
1096
        source = self.make_branch_and_tree('source')
1014
1097
        source.commit('a', rev_id='a', allow_pointless=True)
1015
1098
        source.commit('b', rev_id='b', allow_pointless=True)
1016
 
        self.build_tree(['new/'])
 
1099
        t.mkdir('new')
1017
1100
        t_new = t.clone('new')
1018
1101
        made_control = self.bzrdir_format.initialize_on_transport(t_new)
1019
1102
        source.branch.repository.clone(made_control)
1030
1113
            # because the default open will not open them and
1031
1114
            # they may not be initializable.
1032
1115
            return
1033
 
        # this has to be tested with local access as we still support creating 
 
1116
        # this has to be tested with local access as we still support creating
1034
1117
        # format 6 bzrdirs
1035
 
        t = get_transport('.')
1036
 
        made_control = self.bzrdir_format.initialize(t.base)
1037
 
        made_repo = made_control.create_repository()
1038
 
        made_branch = made_control.create_branch()
1039
 
        made_tree = made_control.create_workingtree()
 
1118
        t = self.get_transport()
 
1119
        try:
 
1120
            made_control = self.bzrdir_format.initialize(t.base)
 
1121
            made_repo = made_control.create_repository()
 
1122
            made_branch = made_control.create_branch()
 
1123
            made_tree = made_control.create_workingtree()
 
1124
        except errors.NotLocalUrl:
 
1125
            raise TestSkipped("Can't initialize %r on transport %r"
 
1126
                              % (self.bzrdir_format, t))
1040
1127
        opened_tree = made_control.open_workingtree()
1041
1128
        self.assertEqual(made_control, opened_tree.bzrdir)
1042
1129
        self.failUnless(isinstance(opened_tree, made_tree.__class__))
1070
1157
        self.assertTrue(isinstance(dir.get_repository_transport(None),
1071
1158
                                   transport.Transport))
1072
1159
        # with a given format, either the bzr dir supports identifiable
1073
 
        # repositoryes, or it supports anonymous  repository formats, but not both.
1074
 
        anonymous_format = repository.RepositoryFormat6()
1075
 
        identifiable_format = repository.RepositoryFormat7()
 
1160
        # repositories, or it supports anonymous  repository formats, but not both.
 
1161
        anonymous_format = weaverepo.RepositoryFormat6()
 
1162
        identifiable_format = weaverepo.RepositoryFormat7()
1076
1163
        try:
1077
1164
            found_transport = dir.get_repository_transport(anonymous_format)
1078
1165
            self.assertRaises(errors.IncompatibleFormat,
1225
1312
        dir = self.make_bzrdir('.')
1226
1313
        if dir.can_convert_format():
1227
1314
            # if its default updatable there must be an updater 
1228
 
            # (we change the default to match the lastest known format
1229
 
            # as downgrades may not be available
1230
 
            old_format = bzrdir.BzrDirFormat.get_default_format()
1231
 
            bzrdir.BzrDirFormat.set_default_format(dir._format)
1232
 
            try:
1233
 
                self.assertTrue(isinstance(dir._format.get_converter(),
1234
 
                                           bzrdir.Converter))
1235
 
            finally:
1236
 
                bzrdir.BzrDirFormat.set_default_format(old_format)
 
1315
            # (we force the latest known format as downgrades may not be
 
1316
            # available
 
1317
            self.assertTrue(isinstance(dir._format.get_converter(
 
1318
                format=dir._format), bzrdir.Converter))
1237
1319
        dir.needs_format_conversion(None)
1238
1320
 
1239
1321
    def test_upgrade_new_instance(self):
1245
1327
        self.createWorkingTreeOrSkip(dir)
1246
1328
        if dir.can_convert_format():
1247
1329
            # if its default updatable there must be an updater 
1248
 
            # (we change the default to match the lastest known format
1249
 
            # as downgrades may not be available
1250
 
            old_format = bzrdir.BzrDirFormat.get_default_format()
1251
 
            bzrdir.BzrDirFormat.set_default_format(dir._format)
 
1330
            # (we force the latest known format as downgrades may not be
 
1331
            # available
1252
1332
            pb = ui.ui_factory.nested_progress_bar()
1253
1333
            try:
1254
 
                dir._format.get_converter(None).convert(dir, pb)
 
1334
                dir._format.get_converter(format=dir._format).convert(dir, pb)
1255
1335
            finally:
1256
 
                bzrdir.BzrDirFormat.set_default_format(old_format)
1257
1336
                pb.finished()
1258
1337
            # and it should pass 'check' now.
1259
1338
            check(bzrdir.BzrDir.open(self.get_url('.')).open_branch(), False)
1263
1342
        text = dir._format.get_format_description()
1264
1343
        self.failUnless(len(text))
1265
1344
 
 
1345
    def test_retire_bzrdir(self):
 
1346
        bd = self.make_bzrdir('.')
 
1347
        transport = bd.root_transport
 
1348
        # must not overwrite existing directories
 
1349
        self.build_tree(['.bzr.retired.0/', '.bzr.retired.0/junk',],
 
1350
            transport=transport)
 
1351
        self.failUnless(transport.has('.bzr'))
 
1352
        bd.retire_bzrdir()
 
1353
        self.failIf(transport.has('.bzr'))
 
1354
        self.failUnless(transport.has('.bzr.retired.1'))
1266
1355
 
1267
1356
class TestBreakLock(TestCaseWithBzrDir):
1268
1357
 
1358
1447
        bzrlib.ui.ui_factory.stdin = StringIO("y\ny\ny\ny\n")
1359
1448
        try:
1360
1449
            tree.bzrdir.break_lock()
1361
 
        except NotImplementedError:
 
1450
        except (NotImplementedError, errors.LockActive):
1362
1451
            # bzrdir does not support break_lock
 
1452
            # or one of the locked objects (currently only tree does this)
 
1453
            # raised a LockActive because we do still have a live locked
 
1454
            # object.
1363
1455
            tree.unlock()
1364
1456
            return
1365
1457
        self.assertEqual("y\n", bzrlib.ui.ui_factory.stdin.read())
1380
1472
            # they may not be initializable.
1381
1473
            return
1382
1474
        # supported formats must be able to init and open
1383
 
        url = self.get_url('subdir')
1384
 
        get_transport(self.get_url()).mkdir('subdir')
1385
 
        made_control = self.bzrdir_format.initialize(url)
 
1475
        # - do the vfs initialisation over the basic vfs transport
 
1476
        # XXX: TODO this should become a 'bzrdirlocation' api call.
 
1477
        url = self.get_vfs_only_url('subdir')
 
1478
        get_transport(self.get_vfs_only_url()).mkdir('subdir')
 
1479
        made_control = self.bzrdir_format.initialize(self.get_url('subdir'))
1386
1480
        try:
1387
1481
            repo = made_control.open_repository()
1388
1482
            # if there is a repository, then the format cannot ever hit this 
1390
1484
            return
1391
1485
        except errors.NoRepositoryPresent:
1392
1486
            pass
1393
 
        opened_control = bzrdir.BzrDir.open(self.get_readonly_url('subdir'))
 
1487
        made_control = bzrdir.BzrDir.open(self.get_readonly_url('subdir'))
1394
1488
        self.assertRaises(errors.NoRepositoryPresent,
1395
 
                          opened_control.find_repository)
 
1489
                          made_control.find_repository)
1396
1490