~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

Merge repository so I dont trample on myself.

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
        if not allow_unsupported and not format.is_supported():
56
56
            raise errors.UnsupportedFormatError(format)
57
57
 
58
 
    def clone(self, url, revision_id=None, basis=None):
 
58
    def clone(self, url, revision_id=None, basis=None, force_new_repo=False):
59
59
        """Clone this bzrdir and its contents to url verbatim.
60
60
 
61
61
        If urls last component does not exist, it will be created.
62
62
 
63
63
        if revision_id is not None, then the clone operation may tune
64
64
            itself to download less data.
 
65
        :param force_new_repo: Do not use a shared repository for the target 
 
66
                               even if one is available.
65
67
        """
66
68
        self._make_tail(url)
 
69
        basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
67
70
        result = self._format.initialize(url)
68
 
        basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
69
71
        try:
70
 
            self.open_repository().clone(result, revision_id=revision_id, basis=basis_repo)
 
72
            local_repo = self.find_repository()
71
73
        except errors.NoRepositoryPresent:
72
 
            pass
 
74
            local_repo = None
 
75
        if local_repo:
 
76
            # may need to copy content in
 
77
            if force_new_repo:
 
78
                local_repo.clone(result, revision_id=revision_id, basis=basis_repo)
 
79
            else:
 
80
                try:
 
81
                    result_repo = result.find_repository()
 
82
                    # fetch content this dir needs.
 
83
                    if basis_repo:
 
84
                        # XXX FIXME RBC 20060214 need tests for this when the basis
 
85
                        # is incomplete
 
86
                        result_repo.fetch(basis_repo, revision_id=revision_id)
 
87
                    result_repo.fetch(local_repo, revision_id=revision_id)
 
88
                except errors.NoRepositoryPresent:
 
89
                    # needed to make one anyway.
 
90
                    local_repo.clone(result, revision_id=revision_id, basis=basis_repo)
 
91
        # 1 if there is a branch present
 
92
        #   make sure its content is available in the target repository
 
93
        #   clone it.
73
94
        try:
74
95
            self.open_branch().clone(result, revision_id=revision_id)
75
96
        except errors.NotBranchError:
140
161
        raise NotImplementedError(self.create_branch)
141
162
 
142
163
    @staticmethod
143
 
    def create_branch_and_repo(base):
 
164
    def create_branch_and_repo(base, force_new_repo=False):
144
165
        """Create a new BzrDir, Branch and Repository at the url 'base'.
145
166
 
146
167
        This will use the current default BzrDirFormat, and use whatever 
147
168
        repository format that that uses via bzrdir.create_branch and
148
 
        create_repository.
 
169
        create_repository. If a shared repository is available that is used
 
170
        preferentially.
149
171
 
150
172
        The created Branch object is returned.
 
173
 
 
174
        :param base: The URL to create the branch at.
 
175
        :param force_new_repo: If True a new repository is always created.
151
176
        """
152
177
        bzrdir = BzrDir.create(base)
153
 
        bzrdir.create_repository()
 
178
        if force_new_repo:
 
179
            bzrdir.create_repository()
 
180
        try:
 
181
            repo = bzrdir.find_repository()
 
182
        except errors.NoRepositoryPresent:
 
183
            bzrdir.create_repository()
154
184
        return bzrdir.create_branch()
155
185
        
156
186
    @staticmethod
157
 
    def create_repository(base):
 
187
    def create_branch_convenience(base, force_new_repo=False, force_new_tree=None):
 
188
        """Create a new BzrDir, Branch and Repository at the url 'base'.
 
189
 
 
190
        This is a convenience function - it will use an existing repository
 
191
        if possible, can be told explicitly whether to create a working tree or
 
192
        nor.
 
193
 
 
194
        This will use the current default BzrDirFormat, and use whatever 
 
195
        repository format that that uses via bzrdir.create_branch and
 
196
        create_repository. If a shared repository is available that is used
 
197
        preferentially. Whatever repository is used, its tree creation policy
 
198
        is followed.
 
199
 
 
200
        The created Branch object is returned.
 
201
        If a working tree cannot be made due to base not being a file:// url,
 
202
        no error is raised.
 
203
 
 
204
        :param base: The URL to create the branch at.
 
205
        :param force_new_repo: If True a new repository is always created.
 
206
        :param force_new_tree: If True or False force creation of a tree or 
 
207
                               prevent such creation respectively.
 
208
        """
 
209
        bzrdir = BzrDir.create(base)
 
210
        if force_new_repo:
 
211
            bzrdir.create_repository()
 
212
        try:
 
213
            repo = bzrdir.find_repository()
 
214
        except errors.NoRepositoryPresent:
 
215
            repo = bzrdir.create_repository()
 
216
        result = bzrdir.create_branch()
 
217
        if force_new_tree or (repo.make_working_trees() and 
 
218
                              force_new_tree is None):
 
219
            bzrdir.create_workingtree()
 
220
        return result
 
221
        
 
222
    @staticmethod
 
223
    def create_repository(base, shared=False):
158
224
        """Create a new BzrDir and Repository at the url 'base'.
159
225
 
160
226
        This will use the current default BzrDirFormat, and use whatever 
161
227
        repository format that that uses for bzrdirformat.create_repository.
162
228
 
 
229
        ;param shared: Create a shared repository rather than a standalone
 
230
                       repository.
163
231
        The Repository object is returned.
164
232
 
165
233
        This must be overridden as an instance method in child classes, where
184
252
        t = get_transport(safe_unicode(base))
185
253
        if not isinstance(t, LocalTransport):
186
254
            raise errors.NotLocalUrl(base)
187
 
        bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base)).bzrdir
 
255
        bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base),
 
256
                                               force_new_repo=True).bzrdir
188
257
        return bzrdir.create_workingtree()
189
258
 
190
259
    def create_workingtree(self, revision_id=None):
194
263
        """
195
264
        raise NotImplementedError(self.create_workingtree)
196
265
 
 
266
    def find_repository(self):
 
267
        """Find the repository that should be used for a_bzrdir.
 
268
 
 
269
        This does not require a branch as we use it to find the repo for
 
270
        new branches as well as to hook existing branches up to their
 
271
        repository.
 
272
        """
 
273
        try:
 
274
            return self.open_repository()
 
275
        except errors.NoRepositoryPresent:
 
276
            pass
 
277
        next_transport = self.root_transport.clone('..')
 
278
        while True:
 
279
            try:
 
280
                found_bzrdir = BzrDir.open_containing_transport(
 
281
                    next_transport)[0]
 
282
            except errors.NotBranchError:
 
283
                raise errors.NoRepositoryPresent(self)
 
284
            try:
 
285
                repository = found_bzrdir.open_repository()
 
286
            except errors.NoRepositoryPresent:
 
287
                next_transport = found_bzrdir.root_transport.clone('..')
 
288
                continue
 
289
            if ((found_bzrdir.root_transport.base == 
 
290
                 self.root_transport.base) or repository.is_shared()):
 
291
                return repository
 
292
            else:
 
293
                raise errors.NoRepositoryPresent(self)
 
294
        raise errors.NoRepositoryPresent(self)
 
295
 
197
296
    def get_branch_transport(self, branch_format):
198
297
        """Get the transport for use by branch format in this BzrDir.
199
298
 
283
382
    def open_containing(url):
284
383
        """Open an existing branch which contains url.
285
384
        
286
 
        This probes for a branch at url, and searches upwards from there.
 
385
        :param url: url to search from.
 
386
        See open_containing_transport for more detail.
 
387
        """
 
388
        return BzrDir.open_containing_transport(get_transport(url))
 
389
    
 
390
    @staticmethod
 
391
    def open_containing_transport(a_transport):
 
392
        """Open an existing branch which contains a_transport.base
 
393
 
 
394
        This probes for a branch at a_transport, and searches upwards from there.
287
395
 
288
396
        Basically we keep looking up until we find the control directory or
289
397
        run into the root.  If there isn't one, raises NotBranchError.
291
399
        format, UnknownFormatError or UnsupportedFormatError are raised.
292
400
        If there is one, it is returned, along with the unused portion of url.
293
401
        """
294
 
        t = get_transport(url)
295
402
        # this gets the normalised url back. I.e. '.' -> the full path.
296
 
        url = t.base
 
403
        url = a_transport.base
297
404
        while True:
298
405
            try:
299
 
                format = BzrDirFormat.find_format(t)
300
 
                return format.open(t), t.relpath(url)
 
406
                format = BzrDirFormat.find_format(a_transport)
 
407
                return format.open(a_transport), a_transport.relpath(url)
301
408
            except errors.NotBranchError, e:
302
 
                mutter('not a branch in: %r %s', t.base, e)
303
 
            new_t = t.clone('..')
304
 
            if new_t.base == t.base:
 
409
                mutter('not a branch in: %r %s', a_transport.base, e)
 
410
            new_t = a_transport.clone('..')
 
411
            if new_t.base == a_transport.base:
305
412
                # reached the root, whatever that may be
306
413
                raise errors.NotBranchError(path=url)
307
 
            t = new_t
 
414
            a_transport = new_t
308
415
 
309
416
    def open_repository(self, _unsupported=False):
310
417
        """Open the repository object at this BzrDir if one is present.
325
432
        """
326
433
        raise NotImplementedError(self.open_workingtree)
327
434
 
328
 
    def sprout(self, url, revision_id=None, basis=None):
 
435
    def sprout(self, url, revision_id=None, basis=None, force_new_repo=False):
329
436
        """Create a copy of this bzrdir prepared for use as a new line of
330
437
        development.
331
438
 
350
457
            try:
351
458
                source_repository = self.open_repository()
352
459
            except errors.NoRepositoryPresent:
353
 
                # copy the basis one if there is one
 
460
                # copy the entire basis one if there is one
 
461
                # but there is no repository.
354
462
                source_repository = basis_repo
355
 
        if source_repository is not None:
 
463
        if force_new_repo:
 
464
            result_repo = None
 
465
        else:
 
466
            try:
 
467
                result_repo = result.find_repository()
 
468
            except errors.NoRepositoryPresent:
 
469
                result_repo = None
 
470
        if source_repository is None and result_repo is not None:
 
471
            pass
 
472
        elif source_repository is None and result_repo is None:
 
473
            # no repo available, make a new one
 
474
            result.create_repository()
 
475
        elif source_repository is not None and result_repo is None:
 
476
            # have soure, and want to make a new target repo
356
477
            source_repository.clone(result,
357
478
                                    revision_id=revision_id,
358
479
                                    basis=basis_repo)
359
480
        else:
360
 
            # no repo available, make a new one
361
 
            result.create_repository()
 
481
            # fetch needed content into target.
 
482
            if basis_repo:
 
483
                # XXX FIXME RBC 20060214 need tests for this when the basis
 
484
                # is incomplete
 
485
                result_repo.fetch(basis_repo, revision_id=revision_id)
 
486
            result_repo.fetch(source_repository, revision_id=revision_id)
362
487
        if source_branch is not None:
363
488
            source_branch.sprout(result, revision_id=revision_id)
364
489
        else:
375
500
class BzrDirPreSplitOut(BzrDir):
376
501
    """A common class for the all-in-one formats."""
377
502
 
378
 
    def clone(self, url, revision_id=None, basis=None):
 
503
    def clone(self, url, revision_id=None, basis=None, force_new_repo=False):
379
504
        """See BzrDir.clone()."""
380
505
        from bzrlib.workingtree import WorkingTreeFormat2
381
506
        self._make_tail(url)
394
519
        """See BzrDir.create_branch."""
395
520
        return self.open_branch()
396
521
 
397
 
    def create_repository(self):
 
522
    def create_repository(self, shared=False):
398
523
        """See BzrDir.create_repository."""
 
524
        if shared:
 
525
            raise errors.IncompatibleFormat('shared repository', self._format)
399
526
        return self.open_repository()
400
527
 
401
528
    def create_workingtree(self, revision_id=None):
477
604
    This is a deprecated format and may be removed after sept 2006.
478
605
    """
479
606
 
480
 
    def create_repository(self):
 
607
    def create_repository(self, shared=False):
481
608
        """See BzrDir.create_repository."""
482
609
        from bzrlib.repository import RepositoryFormat4
483
 
        return RepositoryFormat4().initialize(self)
 
610
        return RepositoryFormat4().initialize(self, shared)
484
611
 
485
612
    def open_repository(self):
486
613
        """See BzrDir.open_repository."""
534
661
        from bzrlib.branch import BranchFormat
535
662
        return BranchFormat.get_default_format().initialize(self)
536
663
 
537
 
    def create_repository(self):
 
664
    def create_repository(self, shared=False):
538
665
        """See BzrDir.create_repository."""
539
666
        from bzrlib.repository import RepositoryFormat
540
 
        return RepositoryFormat.get_default_format().initialize(self)
 
667
        return RepositoryFormat.get_default_format().initialize(self, shared)
541
668
 
542
669
    def create_workingtree(self, revision_id=None):
543
670
        """See BzrDir.create_workingtree."""