Rev 5738: (jelmer) Move bzr-specific implementation of ControlDir.sprout to Bzrdir. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Thu Mar 24 01:23:37 UTC 2011
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 5738 [merge]
revision-id: pqm at pqm.ubuntu.com-20110324012335-s5uxw6v8vge1o4h3
parent: pqm at pqm.ubuntu.com-20110323154359-2air2wty7svt2p92
parent: jelmer at samba.org-20110324001412-7e8z8br9q751osck
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2011-03-24 01:23:35 +0000
message:
(jelmer) Move bzr-specific implementation of ControlDir.sprout to Bzrdir.
(Jelmer Vernooij)
modified:
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/controldir.py controldir.py-20100802102926-hvtvh0uae5epuibp-1
doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py 2011-03-22 12:11:20 +0000
+++ b/bzrlib/bzrdir.py 2011-03-24 01:23:35 +0000
@@ -33,9 +33,11 @@
import bzrlib
from bzrlib import (
+ cleanup,
config,
controldir,
errors,
+ fetch,
graph,
lockable_files,
lockdir,
@@ -60,6 +62,7 @@
""")
from bzrlib.trace import (
+ mutter,
note,
)
@@ -387,6 +390,161 @@
policy = self.determine_repository_policy(force_new_repo)
return policy.acquire_repository()[0]
+ def _find_source_repo(self, add_cleanup, source_branch):
+ """Find the source branch and repo for a sprout operation.
+
+ This is helper intended for use by _sprout.
+
+ :returns: (source_branch, source_repository). Either or both may be
+ None. If not None, they will be read-locked (and their unlock(s)
+ scheduled via the add_cleanup param).
+ """
+ if source_branch is not None:
+ add_cleanup(source_branch.lock_read().unlock)
+ return source_branch, source_branch.repository
+ try:
+ source_branch = self.open_branch()
+ source_repository = source_branch.repository
+ except errors.NotBranchError:
+ source_branch = None
+ try:
+ source_repository = self.open_repository()
+ except errors.NoRepositoryPresent:
+ source_repository = None
+ else:
+ add_cleanup(source_repository.lock_read().unlock)
+ else:
+ add_cleanup(source_branch.lock_read().unlock)
+ return source_branch, source_repository
+
+ def sprout(self, url, revision_id=None, force_new_repo=False,
+ recurse='down', possible_transports=None,
+ accelerator_tree=None, hardlink=False, stacked=False,
+ source_branch=None, create_tree_if_local=True):
+ """Create a copy of this controldir prepared for use as a new line of
+ development.
+
+ If url's last component does not exist, it will be created.
+
+ Attributes related to the identity of the source branch like
+ branch nickname will be cleaned, a working tree is created
+ whether one existed before or not; and a local branch is always
+ created.
+
+ if revision_id is not None, then the clone operation may tune
+ itself to download less data.
+ :param accelerator_tree: A tree which can be used for retrieving file
+ contents more quickly than the revision tree, i.e. a workingtree.
+ The revision tree will be used for cases where accelerator_tree's
+ content is different.
+ :param hardlink: If true, hard-link files from accelerator_tree,
+ where possible.
+ :param stacked: If true, create a stacked branch referring to the
+ location of this control directory.
+ :param create_tree_if_local: If true, a working-tree will be created
+ when working locally.
+ """
+ operation = cleanup.OperationWithCleanups(self._sprout)
+ return operation.run(url, revision_id=revision_id,
+ force_new_repo=force_new_repo, recurse=recurse,
+ possible_transports=possible_transports,
+ accelerator_tree=accelerator_tree, hardlink=hardlink,
+ stacked=stacked, source_branch=source_branch,
+ create_tree_if_local=create_tree_if_local)
+
+ def _sprout(self, op, url, revision_id=None, force_new_repo=False,
+ recurse='down', possible_transports=None,
+ accelerator_tree=None, hardlink=False, stacked=False,
+ source_branch=None, create_tree_if_local=True):
+ add_cleanup = op.add_cleanup
+ fetch_spec_factory = fetch.FetchSpecFactory()
+ if revision_id is not None:
+ fetch_spec_factory.add_revision_ids([revision_id])
+ fetch_spec_factory.source_branch_stop_revision_id = revision_id
+ target_transport = _mod_transport.get_transport(url,
+ possible_transports)
+ target_transport.ensure_base()
+ cloning_format = self.cloning_metadir(stacked)
+ # Create/update the result branch
+ result = cloning_format.initialize_on_transport(target_transport)
+ source_branch, source_repository = self._find_source_repo(
+ add_cleanup, source_branch)
+ fetch_spec_factory.source_branch = source_branch
+ # if a stacked branch wasn't requested, we don't create one
+ # even if the origin was stacked
+ if stacked and source_branch is not None:
+ stacked_branch_url = self.root_transport.base
+ else:
+ stacked_branch_url = None
+ repository_policy = result.determine_repository_policy(
+ force_new_repo, stacked_branch_url, require_stacking=stacked)
+ result_repo, is_new_repo = repository_policy.acquire_repository()
+ add_cleanup(result_repo.lock_write().unlock)
+ fetch_spec_factory.source_repo = source_repository
+ fetch_spec_factory.target_repo = result_repo
+ if stacked or (len(result_repo._fallback_repositories) != 0):
+ target_repo_kind = fetch.TargetRepoKinds.STACKED
+ elif is_new_repo:
+ target_repo_kind = fetch.TargetRepoKinds.EMPTY
+ else:
+ target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
+ fetch_spec_factory.target_repo_kind = target_repo_kind
+ if source_repository is not None:
+ fetch_spec = fetch_spec_factory.make_fetch_spec()
+ result_repo.fetch(source_repository, fetch_spec=fetch_spec)
+
+ if source_branch is None:
+ # this is for sprouting a controldir without a branch; is that
+ # actually useful?
+ # Not especially, but it's part of the contract.
+ result_branch = result.create_branch()
+ else:
+ result_branch = source_branch.sprout(result,
+ revision_id=revision_id, repository_policy=repository_policy,
+ repository=result_repo)
+ mutter("created new branch %r" % (result_branch,))
+
+ # Create/update the result working tree
+ if (create_tree_if_local and
+ isinstance(target_transport, local.LocalTransport) and
+ (result_repo is None or result_repo.make_working_trees())):
+ wt = result.create_workingtree(accelerator_tree=accelerator_tree,
+ hardlink=hardlink, from_branch=result_branch)
+ wt.lock_write()
+ try:
+ if wt.path2id('') is None:
+ try:
+ wt.set_root_id(self.open_workingtree.get_root_id())
+ except errors.NoWorkingTree:
+ pass
+ finally:
+ wt.unlock()
+ else:
+ wt = None
+ if recurse == 'down':
+ basis = None
+ if wt is not None:
+ basis = wt.basis_tree()
+ elif result_branch is not None:
+ basis = result_branch.basis_tree()
+ elif source_branch is not None:
+ basis = source_branch.basis_tree()
+ if basis is not None:
+ add_cleanup(basis.lock_read().unlock)
+ subtrees = basis.iter_references()
+ else:
+ subtrees = []
+ for path, file_id in subtrees:
+ target = urlutils.join(url, urlutils.escape(path))
+ sublocation = source_branch.reference_parent(file_id, path)
+ sublocation.bzrdir.sprout(target,
+ basis.get_reference_revision(file_id, path),
+ force_new_repo=force_new_repo, recurse=recurse,
+ stacked=stacked)
+ return result
+
+
+
@staticmethod
def create_branch_convenience(base, force_new_repo=False,
force_new_tree=None, format=None,
=== modified file 'bzrlib/controldir.py'
--- a/bzrlib/controldir.py 2011-03-23 14:31:38 +0000
+++ b/bzrlib/controldir.py 2011-03-24 01:23:35 +0000
@@ -27,9 +27,7 @@
import textwrap
from bzrlib import (
- cleanup,
errors,
- fetch,
revision as _mod_revision,
transport as _mod_transport,
ui,
@@ -38,9 +36,6 @@
from bzrlib.push import (
PushResult,
)
-from bzrlib.trace import (
- mutter,
- )
from bzrlib.transport import (
local,
)
@@ -336,131 +331,7 @@
:param create_tree_if_local: If true, a working-tree will be created
when working locally.
"""
- operation = cleanup.OperationWithCleanups(self._sprout)
- return operation.run(url, revision_id=revision_id,
- force_new_repo=force_new_repo, recurse=recurse,
- possible_transports=possible_transports,
- accelerator_tree=accelerator_tree, hardlink=hardlink,
- stacked=stacked, source_branch=source_branch,
- create_tree_if_local=create_tree_if_local)
-
- def _sprout(self, op, url, revision_id=None, force_new_repo=False,
- recurse='down', possible_transports=None,
- accelerator_tree=None, hardlink=False, stacked=False,
- source_branch=None, create_tree_if_local=True):
- add_cleanup = op.add_cleanup
- fetch_spec_factory = fetch.FetchSpecFactory()
- if revision_id is not None:
- fetch_spec_factory.add_revision_ids([revision_id])
- fetch_spec_factory.source_branch_stop_revision_id = revision_id
- target_transport = _mod_transport.get_transport(url,
- possible_transports)
- target_transport.ensure_base()
- cloning_format = self.cloning_metadir(stacked)
- # Create/update the result branch
- result = cloning_format.initialize_on_transport(target_transport)
- source_branch, source_repository = self._find_source_repo(
- add_cleanup, source_branch)
- fetch_spec_factory.source_branch = source_branch
- # if a stacked branch wasn't requested, we don't create one
- # even if the origin was stacked
- if stacked and source_branch is not None:
- stacked_branch_url = self.root_transport.base
- else:
- stacked_branch_url = None
- repository_policy = result.determine_repository_policy(
- force_new_repo, stacked_branch_url, require_stacking=stacked)
- result_repo, is_new_repo = repository_policy.acquire_repository()
- add_cleanup(result_repo.lock_write().unlock)
- fetch_spec_factory.source_repo = source_repository
- fetch_spec_factory.target_repo = result_repo
- if stacked or (len(result_repo._fallback_repositories) != 0):
- target_repo_kind = fetch.TargetRepoKinds.STACKED
- elif is_new_repo:
- target_repo_kind = fetch.TargetRepoKinds.EMPTY
- else:
- target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
- fetch_spec_factory.target_repo_kind = target_repo_kind
- if source_repository is not None:
- fetch_spec = fetch_spec_factory.make_fetch_spec()
- result_repo.fetch(source_repository, fetch_spec=fetch_spec)
-
- if source_branch is None:
- # this is for sprouting a controldir without a branch; is that
- # actually useful?
- # Not especially, but it's part of the contract.
- result_branch = result.create_branch()
- else:
- result_branch = source_branch.sprout(result,
- revision_id=revision_id, repository_policy=repository_policy,
- repository=result_repo)
- mutter("created new branch %r" % (result_branch,))
-
- # Create/update the result working tree
- if (create_tree_if_local and
- isinstance(target_transport, local.LocalTransport) and
- (result_repo is None or result_repo.make_working_trees())):
- wt = result.create_workingtree(accelerator_tree=accelerator_tree,
- hardlink=hardlink, from_branch=result_branch)
- wt.lock_write()
- try:
- if wt.path2id('') is None:
- try:
- wt.set_root_id(self.open_workingtree.get_root_id())
- except errors.NoWorkingTree:
- pass
- finally:
- wt.unlock()
- else:
- wt = None
- if recurse == 'down':
- basis = None
- if wt is not None:
- basis = wt.basis_tree()
- elif result_branch is not None:
- basis = result_branch.basis_tree()
- elif source_branch is not None:
- basis = source_branch.basis_tree()
- if basis is not None:
- add_cleanup(basis.lock_read().unlock)
- subtrees = basis.iter_references()
- else:
- subtrees = []
- for path, file_id in subtrees:
- target = urlutils.join(url, urlutils.escape(path))
- sublocation = source_branch.reference_parent(file_id, path)
- sublocation.bzrdir.sprout(target,
- basis.get_reference_revision(file_id, path),
- force_new_repo=force_new_repo, recurse=recurse,
- stacked=stacked)
- return result
-
- def _find_source_repo(self, add_cleanup, source_branch):
- """Find the source branch and repo for a sprout operation.
-
- This is helper intended for use by _sprout.
-
- :returns: (source_branch, source_repository). Either or both may be
- None. If not None, they will be read-locked (and their unlock(s)
- scheduled via the add_cleanup param).
- """
- if source_branch is not None:
- add_cleanup(source_branch.lock_read().unlock)
- return source_branch, source_branch.repository
- try:
- source_branch = self.open_branch()
- source_repository = source_branch.repository
- except errors.NotBranchError:
- source_branch = None
- try:
- source_repository = self.open_repository()
- except errors.NoRepositoryPresent:
- source_repository = None
- else:
- add_cleanup(source_repository.lock_read().unlock)
- else:
- add_cleanup(source_branch.lock_read().unlock)
- return source_branch, source_repository
+ raise NotImplementedError(self.sprout)
def push_branch(self, source, revision_id=None, overwrite=False,
remember=False, create_prefix=False):
=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt 2011-03-23 12:56:01 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt 2011-03-24 01:23:35 +0000
@@ -230,6 +230,10 @@
``import_last_revision_info_and_tags`` method instead.
(Andrew Bennetts)
+* Because it was too specific to BzrDir implementations,
+ ``ControlDir.sprout`` no longer has a default implementation; it now
+ raises ``NotImplementedError``. (Jelmer Vernooij, #717937)
+
* ``ControlDirFormat.register_format`` has been removed. Instead,
``Prober`` implementations should now implement a ``known_formats``
method. (Jelmer Vernooij)
More information about the bazaar-commits
mailing list