def run(self, path="."): from breezy import ( errors, urlutils, ) from breezy.branch import Branch from . import gettext from breezy.repository import Repository from . import errors as bzrsvn_errors try: branch, _ = Branch.open_containing(path) repos = branch.repository except (errors.NotBranchError, errors.NoColocatedBranchSupport): repos = Repository.open(path) branch = None if getattr(repos, "uuid", None) is None: raise errors.BzrCommandError( gettext("Not a Subversion branch or repository.")) layout = repos.get_layout() self.outf.write(gettext("Repository root: %s\n") % repos.base) self.outf.write(gettext("Layout: %s\n") % str(layout)) if branch is not None: self.outf.write( gettext("Branch path: %s\n") % branch.get_branch_path()) if branch.project: self.outf.write(gettext("Project: %s\n") % branch.project) try: test_tag_path = layout.get_tag_path("test", branch.project) except bzrsvn_errors.NoLayoutTagSetSupport: self.outf.write(gettext("No tag support\n")) else: if test_tag_path: self.outf.write( gettext("Tag container directory: %s\n") % urlutils.dirname(test_tag_path)) try: test_branch_path = layout.get_branch_path( "test", branch.project) except bzrsvn_errors.NoCustomBranchPaths: self.outf.write(gettext("No custom branch support\n")) else: if test_branch_path: self.outf.write( gettext("Branch container directory: %s\n") % urlutils.dirname(test_branch_path)) self.outf.write( gettext("Push merged revisions: %s\n") % branch.get_push_merged_revisions())
def delete_tag(self, tag_name): path = self.branch.layout.get_tag_path(tag_name, self.branch.project) parent = urlutils.dirname(path) conn = self.repository.svn_transport.get_connection(parent) try: if conn.check_path( urlutils.basename(path), self.repository.get_latest_revnum()) != subvertpy.NODE_DIR: raise bzr_errors.NoSuchTag(tag_name) ci = svn_errors.convert_svn_error(conn.get_commit_editor)( self._revprops("Remove tag %s" % tag_name.encode("utf-8"), {tag_name: ""})) try: root = ci.open_root() root.delete_entry(urlutils.basename(path)) root.close() except: ci.abort() raise ci.close() # FIXME: This shouldn't have to remove the entire cache, just update it self.repository._clear_cached_state() finally: assert not conn.busy self.repository.svn_transport.add_connection(conn)
def get_file_properties(self, path, file_id=None): """See SubversionTree.get_file_properties().""" abspath = self.workingtree.abspath(path) if not os.path.isdir(abspath.encode(osutils._fs_enc)): wc_path = urlutils.dirname(path) else: wc_path = path with self.workingtree._get_wc(wc_path) as wc: (_, orig_props) = wc.get_prop_diffs(abspath.encode("utf-8")) return orig_props
def set_tag(self, tag_name, tag_target): """Set a new tag in a Subversion repository.""" path = self.branch.layout.get_tag_path(tag_name, self.branch.project) parent = urlutils.dirname(path) try: (from_uuid, from_bp, from_revnum), mapping = self.repository.lookup_bzr_revision_id( tag_target, project=self.branch.project) except bzr_errors.NoSuchRevision: mutter("not setting tag %s; unknown revision %s", tag_name, tag_target) if GhostTagsNotSupported is not None: raise GhostTagsNotSupported(self.branch._format) return self._ensure_tag_parent_exists(parent) try: current_from_foreign_revid = self._lookup_tag_revmeta( path).metarev.get_foreign_revid() deletefirst = True except KeyError: current_from_foreign_revid = None deletefirst = False if current_from_foreign_revid == (from_uuid, from_bp, from_revnum): # Already present return mutter("setting tag %s from %r (deletefirst: %r)", path, (from_uuid, from_bp, from_revnum), deletefirst) conn = self.repository.svn_transport.get_connection(parent) try: with svn_errors.convert_svn_error( conn.get_commit_editor)(self._revprops( "Add tag %s" % tag_name.encode("utf-8"), {tag_name.encode("utf-8"): tag_target})) as ci: root = ci.open_root() if deletefirst: root.delete_entry(urlutils.basename(path)) tag_dir = root.add_directory( urlutils.basename(path), urlutils.join(self.repository.base, from_bp), from_revnum) tag_dir.close() root.close() # FIXME: This shouldn't have to remove the entire cache, just update it self.repository._clear_cached_state() finally: self.repository.svn_transport.add_connection(conn)
def create_branch_with_hidden_commit(repository, branch_path, revid, set_metadata=True, deletefirst=False): """Create a new branch using a simple "svn cp" operation. :param repository: Repository in which to create the branch. :param branch_path: Branch path :param revid: Revision id to keep as tip. :param deletefirst: Whether to delete an existing branch at this location first. :return: Revision id that was pushed and the related foreign revision id. """ revprops = {properties.PROP_REVISION_LOG: "Create new branch."} if revid == NULL_REVISION: old_fileprops = {} fileprops = {} mapping = repository.get_mapping() from_url = None from_revnum = -1 else: revmeta, mapping = repository._get_revmeta(revid) old_fileprops = revmeta.get_fileprops() fileprops = dict(old_fileprops.items()) from_url = url_join_unescaped_path(repository.base, revmeta.metarev.branch_path) from_revnum = revmeta.metarev.revnum if set_metadata: if not mapping.supports_hidden: raise AssertionError("mapping format %r doesn't support hidden" % mapping) to_url = urlutils.join(repository.base, branch_path) config = SvnBranchStack(to_url, repository.uuid) (set_custom_revprops, set_custom_fileprops) = repository._properties_to_set(mapping, config) if set_custom_revprops: mapping.export_hidden_revprops(branch_path, revprops) if (not set_custom_fileprops and not repository.svn_transport.has_capability("log-revprops")): # Tell clients about first approximate use of revision # properties mapping.export_revprop_redirect( repository.get_latest_revnum()+1, fileprops) if set_custom_fileprops: mapping.export_hidden_fileprops(fileprops) parent = urlutils.dirname(branch_path) bp_parts = branch_path.split("/") existing_bp_parts = check_dirs_exist(repository.svn_transport, bp_parts, -1) if len(bp_parts) not in (len(existing_bp_parts), len(existing_bp_parts)+1): raise MissingPrefix("/".join(bp_parts), "/".join(existing_bp_parts)) if deletefirst is None: deletefirst = (bp_parts == existing_bp_parts) foreign_revid = [repository.uuid, branch_path] def done(revno, *args): foreign_revid.append(revno) conn = repository.svn_transport.get_connection(parent) try: with convert_svn_error(conn.get_commit_editor)(revprops, done) as ci: root = ci.open_root() if deletefirst: try: root.delete_entry(urlutils.basename(branch_path)) except SubversionException as e: if e.args[1] == ERR_FS_ROOT_DIR: raise ChangesRootLHSHistory() raise branch_dir = root.add_directory( urlutils.basename(branch_path), from_url, from_revnum) for k, (ov, nv) in properties.diff(fileprops, old_fileprops).items(): branch_dir.change_prop(k, nv) branch_dir.close() root.close() repository._cache_add_new_revision(foreign_revid[2], revid, None) return revid, (tuple(foreign_revid), mapping) finally: repository.svn_transport.add_connection(conn)
def _build_generic_push_suggestion(self, master_url): master_parent = urlutils.dirname(master_url) branch_name = urlutils.basename(self.branch.base) return urlutils.join(master_parent, branch_name)