~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/controldir.py

Avoid reopening (and relocking) the same branches/repositories in ControlDir.sprout.  Still a few rough edges, but the tests I've run are passing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
import textwrap
28
28
 
29
29
from bzrlib import (
 
30
    cleanup,
30
31
    errors,
31
32
    graph,
32
33
    registry,
 
34
    repository,
33
35
    revision as _mod_revision,
34
36
    symbol_versioning,
35
37
    urlutils,
143
145
        """Destroy the repository in this ControlDir."""
144
146
        raise NotImplementedError(self.destroy_repository)
145
147
 
146
 
    def create_branch(self, name=None):
 
148
    def create_branch(self, name=None, repository=None):
147
149
        """Create a branch in this ControlDir.
148
150
 
149
151
        :param name: Name of the colocated branch to create, None for
364
366
        :param create_tree_if_local: If true, a working-tree will be created
365
367
            when working locally.
366
368
        """
 
369
        operation = cleanup.OperationWithCleanups(self._sprout)
 
370
        return operation.run(url, revision_id=revision_id,
 
371
            force_new_repo=force_new_repo, recurse=recurse,
 
372
            possible_transports=possible_transports,
 
373
            accelerator_tree=accelerator_tree, hardlink=hardlink,
 
374
            stacked=stacked, source_branch=source_branch,
 
375
            create_tree_if_local=create_tree_if_local)
 
376
 
 
377
    def _sprout(self, op, url, revision_id=None, force_new_repo=False,
 
378
               recurse='down', possible_transports=None,
 
379
               accelerator_tree=None, hardlink=False, stacked=False,
 
380
               source_branch=None, create_tree_if_local=True):
 
381
        add_cleanup = op.add_cleanup
367
382
        target_transport = get_transport(url, possible_transports)
368
383
        target_transport.ensure_base()
369
384
        cloning_format = self.cloning_metadir(stacked)
373
388
        # even if the origin was stacked
374
389
        stacked_branch_url = None
375
390
        if source_branch is not None:
 
391
            add_cleanup(source_branch.lock_read().unlock)
376
392
            if stacked:
377
393
                stacked_branch_url = self.root_transport.base
378
394
            source_repository = source_branch.repository
388
404
                    source_repository = self.open_repository()
389
405
                except errors.NoRepositoryPresent:
390
406
                    source_repository = None
 
407
                else:
 
408
                    add_cleanup(source_repository.lock_read().unlock)
 
409
            else:
 
410
                add_cleanup(source_branch.lock_read().unlock)
391
411
        repository_policy = result.determine_repository_policy(
392
412
            force_new_repo, stacked_branch_url, require_stacking=stacked)
393
413
        result_repo, is_new_repo = repository_policy.acquire_repository()
 
414
        add_cleanup(result_repo.lock_write().unlock)
394
415
        is_stacked = stacked or (len(result_repo._fallback_repositories) != 0)
395
416
        if is_new_repo and revision_id is not None and not is_stacked:
396
417
            fetch_spec = graph.PendingAncestryResult(
412
433
            result_branch = result.create_branch()
413
434
        else:
414
435
            result_branch = source_branch.sprout(result,
415
 
                revision_id=revision_id, repository_policy=repository_policy)
 
436
                revision_id=revision_id, repository_policy=repository_policy,
 
437
                repository=result_repo)
416
438
        mutter("created new branch %r" % (result_branch,))
417
439
 
418
440
        # Create/update the result working tree
420
442
            isinstance(target_transport, local.LocalTransport) and
421
443
            (result_repo is None or result_repo.make_working_trees())):
422
444
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
423
 
                hardlink=hardlink)
 
445
                hardlink=hardlink, from_branch=result_branch)
424
446
            wt.lock_write()
425
447
            try:
426
448
                if wt.path2id('') is None: