~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

Branch now uses BzrDir reasonably sanely.

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
        If you need a specific format, consider creating an instance
55
55
        of that and calling initialize().
56
56
        """
 
57
        segments = base.split('/')
 
58
        if segments and segments[-1] not in ('', '.'):
 
59
            parent = '/'.join(segments[:-1])
 
60
            t = bzrlib.transport.get_transport(parent)
 
61
            try:
 
62
                t.mkdir(segments[-1])
 
63
            except errors.FileExists:
 
64
                pass
57
65
        return BzrDirFormat.get_default_format().initialize(safe_unicode(base))
58
66
 
 
67
    def create_branch(self):
 
68
        """Create a branch in this BzrDir.
 
69
 
 
70
        The bzrdirs format will control what branch format is created.
 
71
        For more control see BranchFormatXX.create(a_bzrdir).
 
72
        """
 
73
        raise NotImplementedError(self.create_branch)
 
74
 
 
75
    @staticmethod
 
76
    def create_branch_and_repo(base):
 
77
        """Create a new BzrDir, Branch and Repository at the url 'base'.
 
78
 
 
79
        This will use the current default BzrDirFormat, and use whatever 
 
80
        repository format that that uses via bzrdir.create_branch and
 
81
        create_repository.
 
82
 
 
83
        The created Branch object is returned.
 
84
        """
 
85
        bzrdir = BzrDir.create(base)
 
86
        bzrdir.create_repository()
 
87
        return bzrdir.create_branch()
 
88
        
59
89
    @staticmethod
60
90
    def create_repository(base):
61
91
        """Create a new BzrDir and Repository at the url 'base'.
82
112
        _transport: the transport this dir is based at.
83
113
        """
84
114
        self._format = _format
85
 
        self.transport = _transport
 
115
        self.transport = _transport.clone('.bzr')
86
116
 
87
117
    @staticmethod
88
118
    def open_unsupported(base):
101
131
        if not _unsupported and not format.is_supported():
102
132
            # see open_downlevel to open legacy branches.
103
133
            raise errors.UnsupportedFormatError(
104
 
                    'sorry, branch format %s not supported' % format,
 
134
                    'sorry, format %s not supported' % format,
105
135
                    ['use a different bzr version',
106
136
                     'or remove the .bzr directory'
107
137
                     ' and "bzr init" again'])
108
 
        return format.open(t)
 
138
        return format.open(t, _found=True)
 
139
 
 
140
    def open_branch(self):
 
141
        """Open the branch object at this BzrDir if one is present.
 
142
        
 
143
        TODO: static convenience version of this?
 
144
        """
 
145
        raise NotImplementedError(self.open_branch)
109
146
 
110
147
    @staticmethod
111
148
    def open_containing(url):
146
183
class BzrDir4(BzrDir):
147
184
    """A .bzr version 4 control object."""
148
185
 
 
186
    def create_branch(self):
 
187
        """See BzrDir.create_branch."""
 
188
        from bzrlib.branch import BzrBranchFormat4
 
189
        return BzrBranchFormat4().initialize(self)
 
190
 
149
191
    def create_repository(self):
150
192
        """See BzrDir.create_repository."""
151
193
        from bzrlib.repository import RepositoryFormat4
152
194
        return RepositoryFormat4().initialize(self)
153
195
 
 
196
    def open_branch(self):
 
197
        """See BzrDir.open_branch."""
 
198
        from bzrlib.branch import BzrBranchFormat4
 
199
        return BzrBranchFormat4().open(self, _found=True)
 
200
 
154
201
    def open_repository(self):
155
202
        """See BzrDir.open_repository."""
156
203
        from bzrlib.repository import RepositoryFormat4
160
207
class BzrDir5(BzrDir):
161
208
    """A .bzr version 5 control object."""
162
209
 
 
210
    def create_branch(self):
 
211
        """See BzrDir.create_branch."""
 
212
        from bzrlib.branch import BzrBranchFormat4
 
213
        return BzrBranchFormat4().initialize(self)
 
214
 
163
215
    def create_repository(self):
164
216
        """See BzrDir.create_repository."""
165
217
        from bzrlib.repository import RepositoryFormat5
166
218
        return RepositoryFormat5().initialize(self)
167
219
 
 
220
    def open_branch(self):
 
221
        """See BzrDir.open_branch."""
 
222
        from bzrlib.branch import BzrBranchFormat4
 
223
        return BzrBranchFormat4().open(self, _found=True)
 
224
 
168
225
    def open_repository(self):
169
226
        """See BzrDir.open_repository."""
170
227
        from bzrlib.repository import RepositoryFormat5
174
231
class BzrDir6(BzrDir):
175
232
    """A .bzr version 6 control object."""
176
233
 
 
234
    def create_branch(self):
 
235
        """See BzrDir.create_branch."""
 
236
        from bzrlib.branch import BzrBranchFormat4
 
237
        return BzrBranchFormat4().initialize(self)
 
238
 
177
239
    def create_repository(self):
178
240
        """See BzrDir.create_repository."""
179
241
        from bzrlib.repository import RepositoryFormat6
180
242
        return RepositoryFormat6().initialize(self)
181
243
 
 
244
    def open_branch(self):
 
245
        """See BzrDir.open_branch."""
 
246
        from bzrlib.branch import BzrBranchFormat4
 
247
        return BzrBranchFormat4().open(self, _found=True)
 
248
 
182
249
    def open_repository(self):
183
250
        """See BzrDir.open_repository."""
184
251
        from bzrlib.repository import RepositoryFormat6
305
372
 
306
373
    This format is a combined format for working tree, branch and repository.
307
374
    It has:
308
 
     - flat stores
309
 
     - TextStores for texts, inventories,revisions.
 
375
     - Format 1 working trees
 
376
     - Format 4 branches
 
377
     - Format 4 repositories
310
378
 
311
379
    This format is deprecated: it indexes texts using a text it which is
312
380
    removed in format 5; write support for this format has been removed.
339
407
 
340
408
    This format is a combined format for working tree, branch and repository.
341
409
    It has:
342
 
     - weaves for file texts and inventory
343
 
     - flat stores
344
 
     - TextStores for revisions and signatures.
 
410
     - Format 2 working trees
 
411
     - Format 4 branches
 
412
     - Format 6 repositories
345
413
    """
346
414
 
347
415
    def get_format_string(self):
358
426
 
359
427
    This format is a combined format for working tree, branch and repository.
360
428
    It has:
361
 
     - weaves for file texts and inventory
362
 
     - hash subdirectory based stores.
363
 
     - TextStores for revisions and signatures.
 
429
     - Format 2 working trees
 
430
     - Format 4 branches
 
431
     - Format 6 repositories
364
432
    """
365
433
 
366
434
    def get_format_string(self):
406
474
            new_test.id = make_new_test_id()
407
475
            result.addTest(new_test)
408
476
        return result
 
477
 
 
478
 
 
479
class ScratchDir(BzrDir6):
 
480
    """Special test class: a bzrdir that cleans up itself..
 
481
 
 
482
    >>> d = ScratchDir()
 
483
    >>> base = d.transport.base
 
484
    >>> isdir(base)
 
485
    True
 
486
    >>> b.transport.__del__()
 
487
    >>> isdir(base)
 
488
    False
 
489
    """
 
490
 
 
491
    def __init__(self, files=[], dirs=[], transport=None):
 
492
        """Make a test branch.
 
493
 
 
494
        This creates a temporary directory and runs init-tree in it.
 
495
 
 
496
        If any files are listed, they are created in the working copy.
 
497
        """
 
498
        if transport is None:
 
499
            transport = bzrlib.transport.local.ScratchTransport()
 
500
            # local import for scope restriction
 
501
            BzrDirFormat6().initialize(transport.base)
 
502
            super(ScratchDir, self).__init__(transport, BzrDirFormat6())
 
503
            self.create_repository()
 
504
            self.create_branch()
 
505
            from bzrlib.workingtree import WorkingTree
 
506
            WorkingTree.create(self.open_branch(), transport.base)
 
507
        else:
 
508
            super(ScratchDir, self).__init__(transport, BzrDirFormat6())
 
509
 
 
510
        # BzrBranch creates a clone to .bzr and then forgets about the
 
511
        # original transport. A ScratchTransport() deletes itself and
 
512
        # everything underneath it when it goes away, so we need to
 
513
        # grab a local copy to prevent that from happening
 
514
        self._transport = transport
 
515
 
 
516
        for d in dirs:
 
517
            self._transport.mkdir(d)
 
518
            
 
519
        for f in files:
 
520
            self._transport.put(f, 'content of %s' % f)
 
521
 
 
522
    def clone(self):
 
523
        """
 
524
        >>> orig = ScratchDir(files=["file1", "file2"])
 
525
        >>> os.listdir(orig.base)
 
526
        [u'.bzr', u'file1', u'file2']
 
527
        >>> clone = orig.clone()
 
528
        >>> if os.name != 'nt':
 
529
        ...   os.path.samefile(orig.base, clone.base)
 
530
        ... else:
 
531
        ...   orig.base == clone.base
 
532
        ...
 
533
        False
 
534
        >>> os.listdir(clone.base)
 
535
        [u'.bzr', u'file1', u'file2']
 
536
        """
 
537
        from shutil import copytree
 
538
        from bzrlib.osutils import mkdtemp
 
539
        base = mkdtemp()
 
540
        os.rmdir(base)
 
541
        copytree(self.base, base, symlinks=True)
 
542
        return ScratchDir(
 
543
            transport=bzrlib.transport.local.ScratchTransport(base))