Beispiel #1
0
    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())
Beispiel #2
0
 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)
Beispiel #3
0
 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
Beispiel #4
0
 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)
Beispiel #5
0
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)
Beispiel #6
0
 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)