180
180
even if one is available.
182
182
transport.ensure_base()
183
result = self._format.initialize_on_transport(transport)
183
result = self.cloning_metadir().initialize_on_transport(transport)
184
repository_policy = None
185
186
local_repo = self.find_repository()
186
187
except errors.NoRepositoryPresent:
187
188
local_repo = None
189
190
# may need to copy content in
191
result_repo = local_repo.clone(
193
revision_id=revision_id)
194
result_repo.set_make_working_trees(local_repo.make_working_trees())
197
result_repo = result.find_repository()
198
# fetch content this dir needs.
199
result_repo.fetch(local_repo, revision_id=revision_id)
200
except errors.NoRepositoryPresent:
201
# needed to make one anyway.
202
result_repo = local_repo.clone(
204
revision_id=revision_id)
205
result_repo.set_make_working_trees(local_repo.make_working_trees())
191
repository_policy = result.determine_repository_policy(
193
make_working_trees = local_repo.make_working_trees()
194
result_repo = repository_policy.acquire_repository(
195
make_working_trees, local_repo.is_shared())
196
result_repo.fetch(local_repo, revision_id=revision_id)
206
197
# 1 if there is a branch present
207
198
# make sure its content is available in the target repository
210
self.open_branch().clone(result, revision_id=revision_id)
201
local_branch = self.open_branch()
211
202
except errors.NotBranchError:
205
result_branch = local_branch.clone(result, revision_id=revision_id)
206
if repository_policy is not None:
207
repository_policy.configure_branch(result_branch)
214
209
result_repo = result.find_repository()
215
210
except errors.NoRepositoryPresent:
356
351
bzrdir._find_or_create_repository(force_new_repo)
357
352
return bzrdir.create_branch()
354
def determine_repository_policy(self, force_new_repo=False):
355
"""Return an object representing a policy to use.
357
This controls whether a new repository is created, or a shared
358
repository used instead.
360
def repository_policy(found_bzrdir):
362
# does it have a repository ?
364
repository = found_bzrdir.open_repository()
365
except errors.NoRepositoryPresent:
368
if ((found_bzrdir.root_transport.base !=
369
self.root_transport.base) and not repository.is_shared()):
376
return UseExistingRepository(repository), True
378
return CreateRepository(self), True
380
if not force_new_repo:
381
policy = self._find_containing(repository_policy)
382
if policy is not None:
384
return CreateRepository(self)
359
386
def _find_or_create_repository(self, force_new_repo):
360
387
"""Create a new repository if needed, returning the repository."""
362
return self.create_repository()
364
return self.find_repository()
365
except errors.NoRepositoryPresent:
366
return self.create_repository()
388
policy = self.determine_repository_policy(force_new_repo)
389
return policy.acquire_repository()
369
392
def create_branch_convenience(base, force_new_repo=False,
370
393
force_new_tree=None, format=None,
509
532
raise NotImplementedError(self.destroy_workingtree_metadata)
534
def _find_containing(self, evaluate):
535
"""Find something in a containing control directory.
537
This method will scan containing control dirs, until it finds what
538
it is looking for, decides that it will never find it, or runs out
539
of containing control directories to check.
541
It is used to implement find_repository and
542
determine_repository_policy.
544
:param evaluate: A function returning (value, stop). If stop is True,
545
the value will be returned.
549
result, stop = evaluate(found_bzrdir)
552
next_transport = found_bzrdir.root_transport.clone('..')
553
if (found_bzrdir.root_transport.base == next_transport.base):
554
# top of the file system
556
# find the next containing bzrdir
558
found_bzrdir = BzrDir.open_containing_from_transport(
560
except errors.NotBranchError:
511
563
def find_repository(self):
512
564
"""Find the repository that should be used.
515
567
new branches as well as to hook existing branches up to their
519
return self.open_repository()
520
except errors.NoRepositoryPresent:
522
next_transport = self.root_transport.clone('..')
524
# find the next containing bzrdir
526
found_bzrdir = BzrDir.open_containing_from_transport(
528
except errors.NotBranchError:
530
raise errors.NoRepositoryPresent(self)
570
def usable_repository(found_bzrdir):
531
571
# does it have a repository ?
533
573
repository = found_bzrdir.open_repository()
534
574
except errors.NoRepositoryPresent:
535
next_transport = found_bzrdir.root_transport.clone('..')
536
if (found_bzrdir.root_transport.base == next_transport.base):
537
# top of the file system
541
if ((found_bzrdir.root_transport.base ==
542
self.root_transport.base) or repository.is_shared()):
576
if found_bzrdir.root_transport.base == self.root_transport.base:
577
return repository, True
578
elif repository.is_shared():
579
return repository, True
545
raise errors.NoRepositoryPresent(self)
546
raise errors.NoRepositoryPresent(self)
583
found_repo = self._find_containing(usable_repository)
584
if found_repo is None:
585
raise errors.NoRepositoryPresent(self)
548
588
def get_branch_reference(self):
549
589
"""Return the referenced URL for the branch in this bzrdir.
1010
1050
"""Pre-splitout bzrdirs do not suffer from stale locks."""
1011
1051
raise NotImplementedError(self.break_lock)
1053
def cloning_metadir(self):
1054
"""Produce a metadir suitable for cloning with."""
1055
return self._format.__class__()
1013
1057
def clone(self, url, revision_id=None, force_new_repo=False):
1014
1058
"""See BzrDir.clone()."""
1015
1059
from bzrlib.workingtree import WorkingTreeFormat2
2415
2459
def initialize_on_transport(self, transport):
2417
2461
# hand off the request to the smart server
2418
shared_medium = transport.get_shared_medium()
2462
client_medium = transport.get_smart_medium()
2419
2463
except errors.NoSmartMedium:
2420
2464
# TODO: lookup the local format from a server hint.
2421
2465
local_dir_format = BzrDirMetaFormat1()
2422
2466
return local_dir_format.initialize_on_transport(transport)
2423
client = _SmartClient(shared_medium)
2467
client = _SmartClient(client_medium, transport.base)
2424
2468
path = client.remote_path_from_transport(transport)
2425
response = _SmartClient(shared_medium).call('BzrDirFormat.initialize',
2469
response = client.call('BzrDirFormat.initialize', path)
2427
2470
assert response[0] in ('ok', ), 'unexpected response code %s' % (response,)
2428
2471
return remote.RemoteBzrDir(transport)
2656
class RepositoryAcquisitionPolicy(object):
2657
"""Abstract base class for repository acquisition policies.
2659
A repository acquisition policy decides how a BzrDir acquires a repository
2660
for a branch that is being created. The most basic policy decision is
2661
whether to create a new repository or use an existing one.
2664
def configure_branch(self, branch):
2665
"""Apply any configuration data from this policy to the branch.
2667
Default implementation does nothing.
2671
def acquire_repository(self, make_working_trees=None, shared=False):
2672
"""Acquire a repository for this bzrdir.
2674
Implementations may create a new repository or use a pre-exising
2676
:param make_working_trees: If creating a repository, set
2677
make_working_trees to this value (if non-None)
2678
:param shared: If creating a repository, make it shared if True
2679
:return: A repository
2681
raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
2684
class CreateRepository(RepositoryAcquisitionPolicy):
2685
"""A policy of creating a new repository"""
2687
def __init__(self, bzrdir):
2688
RepositoryAcquisitionPolicy.__init__(self)
2689
self._bzrdir = bzrdir
2691
def acquire_repository(self, make_working_trees=None, shared=False):
2692
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2694
Creates the desired repository in the bzrdir we already have.
2696
repository = self._bzrdir.create_repository(shared=shared)
2697
if make_working_trees is not None:
2698
repository.set_make_working_trees(make_working_trees)
2702
class UseExistingRepository(RepositoryAcquisitionPolicy):
2703
"""A policy of reusing an existing repository"""
2705
def __init__(self, repository):
2706
RepositoryAcquisitionPolicy.__init__(self)
2707
self._repository = repository
2709
def acquire_repository(self, make_working_trees=None, shared=False):
2710
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2712
Returns an existing repository to use
2714
return self._repository
2613
2717
format_registry = BzrDirFormatRegistry()
2614
2718
format_registry.register('weave', BzrDirFormat6,
2615
2719
'Pre-0.8 format. Slower than knit and does not'