Support for Subversion branches
"""
import bzrlib
-from bzrlib.bzrdir import BzrDirFormat
+from bzrlib.bzrdir import BzrDirFormat, format_registry
from bzrlib.commands import Command, register_command, display_command, Option
from bzrlib.help_topics import topic_registry
-from bzrlib.lazy_import import lazy_import
-from bzrlib.trace import warning, mutter
+from bzrlib.revisionspec import SPEC_TYPES
+from bzrlib.trace import warning
from bzrlib.transport import register_lazy_transport, register_transport_proto
-from bzrlib.repository import InterRepository
-from bzrlib.workingtree import WorkingTreeFormat
-lazy_import(globals(), """
-import branch
-import commit
-import fetch
import format
-import workingtree
-""")
+import revspec
# versions ending in 'exp' mean experimental mappings
# versions ending in 'dev' mean development version
-__version__ = '0.4.0exp'
-COMPATIBLE_BZR_VERSIONS = [(0, 19)]
+# versions ending in 'final' mean release (well tested, etc)
+version_info = (0, 4, 7, 'dev', 0)
+
+if version_info[3] == 'final':
+ version_string = '%d.%d.%d' % version_info[:3]
+else:
+ version_string = '%d.%d.%d%s%d' % version_info
+__version__ = version_string
+
+COMPATIBLE_BZR_VERSIONS = [(0, 93), (1, 0), (1, 1)]
def check_bzrlib_version(desired):
"""Check that bzrlib is compatible.
((bzrlib_version[0], bzrlib_version[1]-1) in desired and
bzrlib.version_info[3] == 'dev')):
return
+ from bzrlib.errors import BzrError
if bzrlib_version < desired[0]:
- warning('Installed bzr version %s is too old to be used with bzr-svn'
- ' %s.' % (bzrlib.__version__, __version__))
- # Not using BzrNewError, because it may not exist.
- raise Exception, ('Version mismatch', desired)
+ raise BzrError('Installed bzr version %s is too old to be used with bzr-svn, at least %s.%s required' % (bzrlib.__version__, desired[0][0], desired[0][1]))
else:
warning('bzr-svn is not up to date with installed bzr version %s.'
' \nThere should be a newer version of bzr-svn available.'
% (bzrlib.__version__))
if not (bzrlib_version[0], bzrlib_version[1]-1) in desired:
- raise Exception, 'Version mismatch'
+ raise BzrError('Version mismatch')
def check_bzrsvn_version():
"""Warn about use of experimental mappings."""
- if __version__.endswith("exp"):
+ if version_info[3] == "exp":
warning('version of bzr-svn is experimental; output may change between revisions')
def check_subversion_version():
'bzrlib.plugins.svn.scheme',
'help_schemes', 'Subversion branching schemes')
-BzrDirFormat.register_control_format(format.SvnFormat)
-BzrDirFormat.register_control_format(workingtree.SvnWorkingTreeDirFormat)
-
-bzrlib.branch.BranchFormat.register_format(branch.SvnBranchFormat())
-bzrlib.repository.format_registry.register_lazy(
- "Subversion Repository Format",
- "bzrlib.plugins.svn.repository",
- "SvnRepositoryFormat")
-WorkingTreeFormat.register_format(workingtree.SvnWorkingTreeFormat())
+BzrDirFormat.register_control_format(format.SvnRemoteFormat)
+BzrDirFormat.register_control_format(format.SvnWorkingTreeDirFormat)
+format_registry.register("subversion", format.SvnRemoteFormat,
+ "Subversion repository. ",
+ native=False)
+format_registry.register("subversion-wc", format.SvnWorkingTreeDirFormat,
+ "Subversion working copy. ",
+ native=False, hidden=True)
+SPEC_TYPES.append(revspec.RevisionSpec_svn)
versions_checked = False
def lazy_check_versions():
check_bzrlib_version(COMPATIBLE_BZR_VERSIONS)
check_bzrsvn_version()
-InterRepository.register_optimiser(fetch.InterFromSvnRepository)
-InterRepository.register_optimiser(commit.InterToSvnRepository)
+optimizers_registered = False
+def lazy_register_optimizers():
+ global optimizers_registered
+ if optimizers_registered:
+ return
+ from bzrlib.repository import InterRepository
+ import commit
+ import fetch
+ optimizers_registered = True
+ InterRepository.register_optimiser(fetch.InterFromSvnRepository)
+ InterRepository.register_optimiser(commit.InterToSvnRepository)
+
def get_scheme(schemename):
"""Parse scheme identifier and return a branching scheme."""
@display_command
def run(self, from_location, to_location=None, trees=False,
standalone=False, scheme=None, all=False, prefix=None):
- from bzrlib.errors import NoRepositoryPresent
+ from bzrlib.errors import BzrCommandError, NoRepositoryPresent
from bzrlib.bzrdir import BzrDir
- from bzrlib.trace import info
from convert import convert_repository
+ from repository import SvnRepository
import os
- from scheme import TrunkBranchingScheme
if to_location is None:
to_location = os.path.basename(from_location.rstrip("/\\"))
if all:
+ # All implies shared repository
+ # (otherwise there is no repository to store revisions in)
standalone = False
if os.path.isfile(from_location):
from convert import load_dumpfile
import tempfile
tmp_repos = tempfile.mkdtemp(prefix='bzr-svn-dump-')
- mutter('loading dumpfile %r to %r' % (from_location, tmp_repos))
load_dumpfile(from_location, tmp_repos)
from_location = tmp_repos
else:
try:
from_repos = from_dir.open_repository()
except NoRepositoryPresent, e:
- from bzrlib.errors import BzrCommandError
raise BzrCommandError("No Repository found at %s. "
"For individual branches, use 'bzr branch'." % from_location)
+ if not isinstance(from_repos, SvnRepository):
+ raise BzrCommandError(
+ "Not a Subversion repository: %s" % from_location)
+
def filter_branch((branch_path, revnum, exists)):
if prefix is not None and not branch_path.startswith(prefix):
return False
@display_command
def run(self, from_repository=None, verbose=False):
- from upgrade import upgrade_branch
+ from upgrade import upgrade_branch, upgrade_workingtree
from bzrlib.branch import Branch
from bzrlib.errors import NoWorkingTree, BzrCommandError
from bzrlib.repository import Repository
+ from bzrlib.trace import info
from bzrlib.workingtree import WorkingTree
try:
wt_to = WorkingTree.open(".")
else:
from_repository = Repository.open(from_repository)
- upgrade_branch(branch_to, from_repository, allow_changes=True,
- verbose=verbose)
+ if wt_to is not None:
+ renames = upgrade_workingtree(wt_to, from_repository,
+ allow_changes=True, verbose=verbose)
+ else:
+ renames = upgrade_branch(branch_to, from_repository,
+ allow_changes=True, verbose=verbose)
+
+ if renames == {}:
+ info("Nothing to do.")
if wt_to is not None:
wt_to.set_last_revision(branch_to.last_revision())
register_command(cmd_svn_upgrade)
-class cmd_svn_push_new(Command):
- """Create a new branch in Subversion.
+class cmd_svn_push(Command):
+ """Push revisions to Subversion, creating a new branch if necessary.
+
+ The behaviour of this command is the same as that of "bzr push", except
+ that it also creates new branches.
- This command is experimental and will be removed in the future.
+ This command is experimental and will be removed in the future when all
+ functionality is included in "bzr push".
"""
- takes_args = ['location']
- takes_options = ['revision']
+ takes_args = ['location?']
+ takes_options = ['revision', 'remember']
- def run(self, location, revision=None):
+ def run(self, location=None, revision=None, remember=False):
from bzrlib.bzrdir import BzrDir
from bzrlib.branch import Branch
+ from bzrlib.errors import NotBranchError, BzrCommandError
+ from bzrlib import urlutils
+
+ source_branch = Branch.open_containing(".")[0]
+ stored_loc = source_branch.get_push_location()
+ if location is None:
+ if stored_loc is None:
+ raise BzrCommandError("No push location known or specified.")
+ else:
+ display_url = urlutils.unescape_for_display(stored_loc,
+ self.outf.encoding)
+ self.outf.write("Using saved location: %s\n" % display_url)
+ location = stored_loc
+
bzrdir = BzrDir.open(location)
- branch = Branch.open(".")
if revision is not None:
if len(revision) > 1:
- raise errors.BzrCommandError(
- 'bzr svn-push-new --revision takes exactly one revision'
+ raise BzrCommandError(
+ 'bzr svn-push --revision takes exactly one revision'
' identifier')
- revision_id = revision[0].in_history(branch).rev_id
+ revision_id = revision[0].in_history(source_branch).rev_id
else:
revision_id = None
- bzrdir.import_branch(branch, revision_id)
+ try:
+ target_branch = bzrdir.open_branch()
+ target_branch.pull(source_branch, revision_id)
+ except NotBranchError:
+ target_branch = bzrdir.import_branch(source_branch, revision_id)
+ # We successfully created the target, remember it
+ if source_branch.get_push_location() is None or remember:
+ source_branch.set_push_location(target_branch.base)
+
+register_command(cmd_svn_push)
+
+
+class cmd_svn_branching_scheme(Command):
+ """Show or change the branching scheme for a Subversion repository.
+
+ See 'bzr help svn-branching-schemes' for details.
+ """
+ takes_args = ['location?']
+ takes_options = [
+ Option('set', help="Change the branching scheme. "),
+ Option('repository-wide',
+ help="Act on repository-wide setting rather than local.")
+ ]
+
+ def run(self, location=".", set=False, repository_wide=False):
+ from bzrlib.errors import BzrCommandError
+ from bzrlib.msgeditor import edit_commit_message
+ from bzrlib.repository import Repository
+ from bzrlib.trace import info
+ from repository import SvnRepository
+ from scheme import scheme_from_branch_list
+ def scheme_str(scheme):
+ if scheme is None:
+ return ""
+ return "".join(map(lambda x: x+"\n", scheme.to_lines()))
+ repos = Repository.open(location)
+ if not isinstance(repos, SvnRepository):
+ raise BzrCommandError("Not a Subversion repository: %s" % location)
+ if repository_wide:
+ scheme = repos._get_property_scheme()
+ else:
+ scheme = repos.get_scheme()
+ if set:
+ schemestr = edit_commit_message("",
+ start_message=scheme_str(scheme))
+ scheme = scheme_from_branch_list(
+ map(lambda x:x.strip("\n"), schemestr.splitlines()))
+ if repository_wide:
+ repos.set_property_scheme(scheme)
+ else:
+ repos.set_branching_scheme(scheme, mandatory=True)
+ elif scheme is not None:
+ info(scheme_str(scheme))
+
-register_command(cmd_svn_push_new)
+register_command(cmd_svn_branching_scheme)
+
+
+class cmd_svn_set_revprops(Command):
+ """Migrate Bazaar metadata to Subversion revision properties.
+
+ This requires that you have permission to change the
+ revision properties on the repository.
+
+ To change these permissions, edit the hooks/pre-revprop-change
+ file in the Subversion repository.
+ """
+ takes_args = ['location']
+
+ def run(self, location="."):
+ raise NotImplementedError(self.run)
+
+
+register_command(cmd_svn_set_revprops)
def test_suite():
suite.addTest(tests.test_suite())
return suite
+
if __name__ == '__main__':
print ("This is a Bazaar plugin. Copy this directory to ~/.bazaar/plugins "
"to use it.\n")