def test_pull_internal(self):
        repos_url = self.make_repository("a")

        dc = self.get_commit_editor(repos_url)
        dc.add_dir("trunk")
        dc.close()

        dc = self.get_commit_editor(repos_url)
        branches = dc.add_dir("branches")
        branches.add_dir("branches/foo", "trunk", 1)
        dc.close()

        otherbranch = Branch.open(urlutils.join(repos_url, "branches", "foo"))
        branch = Branch.open(urlutils.join(repos_url, "trunk"))
        old_last_revid = branch.last_revision()
        result = branch.pull(otherbranch)

        self.assertEquals(branch.last_revision(), otherbranch.last_revision())
        self.assertEquals(result.new_revid, otherbranch.last_revision())
        self.assertEquals(result.old_revid, old_last_revid)
        self.assertEquals(result.old_revno, 1)
        self.assertEquals(result.new_revno, 2)
        self.assertEquals(result.master_branch, branch)
        self.assertEquals(result.source_branch, otherbranch)
        self.assertEquals(result.target_branch, branch)
Exemple #2
0
 def _add_project(self, path, project=None):
     if project is None:
         project = u"*/" * self.level
     if path == u"trunk":
         return urlutils.join(path, project)
     else:
         return urlutils.join(urlutils.join(path, project), u"*")
Exemple #3
0
    def get_tag_path(self, name, project=u""):
        """Return the path at which the tag with specified name should be found.

        :param name: Name of the tag.
        :param project: Optional name of the project the tag is for. Can include slashes.
        :return: Path of the tag.
        """
        subpath = urlutils.join(u"tags", name.strip(u"/"))
        if project in (None, u""):
            return subpath
        return urlutils.join(project, subpath)
Exemple #4
0
    def get_branch_path(self, name, project=""):
        """Return the path at which the branch with specified name should be found.

        :param name: Name of the branch.
        :param project: Optional name of the project the branch is for. Can include slashes.
        :return: Path of the branch.
        """
        if name == u"":
            return urlutils.join(project, u"trunk").strip(u"/")
        else:
            return urlutils.join(project, u"branches", name).strip(u"/")
Exemple #5
0
 def get_branch_path(self, name, project=""):
     # Only implemented for level 0
     if name == u"trunk":
         if project == u"":
             return u"trunk"
         else:
             return urlutils.join(project, u"trunk")
     else:
         if project == u"":
             return urlutils.join(u"branches", name)
         else:
             return urlutils.join(project, u"branches", name)
Exemple #6
0
def url_join_unescaped_path(url, path):
    (scheme, netloc, basepath, query, fragment) = urlparse.urlsplit(url)
    path = urlutils.join(urllib.unquote(basepath), path)
    if scheme in ("http", "https"):
        # Without this, URLs with + in them break
        path = urllib.quote(path, safe="/+%")
    return urlparse.urlunsplit((scheme, netloc, path, query, fragment))
Exemple #7
0
def keyword_url(revid, rev, relpath, revmeta):
    # URL in the svn repository
    # See if c.revision() can be traced back to a subversion revision
    if revmeta is not None:
        return urlutils.join(revmeta.repository.base, revmeta.branch_path,
                             relpath)
    return relpath
 def test_multi_stack(self):
     """base + stacked + stacked-on-stacked"""
     base_tree, stacked_tree = self.make_stacked_target()
     self.build_tree(['stacked/f3.txt'])
     stacked_tree.add(['f3.txt'], [b'f3.txt-id'])
     stacked_key = (b'stacked-rev-id', )
     stacked_tree.commit('add f3', rev_id=stacked_key[0])
     stacked_only_repo = self.get_only_repo(stacked_tree)
     self.assertPresent([self.r2_key], stacked_only_repo.inventories,
                        [self.r1_key, self.r2_key])
     # This ensures we get a Remote URL, rather than a local one.
     stacked2_url = urlutils.join(base_tree.branch.base, '../stacked2')
     stacked2_bzrdir = stacked_tree.controldir.sprout(
         stacked2_url, revision_id=self.r1_key[0], stacked=True)
     if isinstance(stacked2_bzrdir, remote.RemoteBzrDir):
         stacked2_branch = stacked2_bzrdir.open_branch()
         stacked2_tree = stacked2_branch.create_checkout('stacked2',
                                                         lightweight=True)
     else:
         stacked2_tree = stacked2_bzrdir.open_workingtree()
     # stacked2 is stacked on stacked, but its content is rev1, so
     # it needs to pull the basis information from a fallback-of-fallback.
     self.build_tree(['stacked2/f3.txt'])
     stacked2_only_repo = self.get_only_repo(stacked2_tree)
     self.assertPresent([], stacked2_only_repo.inventories,
                        [self.r1_key, self.r2_key])
     stacked2_tree.add(['f3.txt'], [b'f3.txt-id'])
     stacked2_tree.commit('add f3', rev_id=b'stacked2-rev-id')
     # We added data to this read-locked repo, so refresh it
     stacked2_only_repo.refresh_data()
     self.assertPresent([self.r1_key], stacked2_only_repo.inventories,
                        [self.r1_key, self.r2_key])
Exemple #9
0
    def clone(self, offset=None):
        """See Transport.clone()."""
        if offset is None:
            newurl = self.base
        else:
            newurl = urlutils.join(self.base, offset)

        return SvnRaTransport(newurl, self)
Exemple #10
0
 def test_find_branches(self):
     repos_url = self.make_client("a", "dc")
     self.build_tree({
         'dc/branches/brancha': None,
         'dc/branches/branchab': None,
         'dc/branches/brancha/data': "data",
         "dc/branches/branchab/data": "data"
     })
     self.client_add("dc/branches")
     self.client_commit("dc", "My Message")
     repos = Repository.open(repos_url)
     repos.set_layout(TrunkLayout(0))
     branches = repos.find_branches()
     self.assertEquals(2, len(branches))
     self.assertEquals(urlutils.join(repos.base, "branches/brancha"),
                       branches[1].base)
     self.assertEquals(urlutils.join(repos.base, "branches/branchab"),
                       branches[0].base)
Exemple #11
0
    def get_tag_path(self, name, project=""):
        """Return the path at which the tag with specified name should be found.

        :param name: Name of the tag.
        :param project: Optional name of the project the tag is for. Can
            include slashes.
        :return: Path of the tag."
        """
        return urlutils.join("tags", project, name.strip("/"))
Exemple #12
0
 def get_paths_connection(self, paths):
     paths = [p.strip(u"/") for p in paths]
     prefix = common_prefix(paths)
     subpaths = [urlutils.determine_relative_path(prefix, p) for p in paths]
     conn, relprefix = self.get_path_connection(prefix)
     if relprefix == u"":
         relsubpaths = subpaths
     else:
         relsubpaths = [urlutils.join(relprefix, p) for p in subpaths]
     return (conn, relsubpaths)
Exemple #13
0
def convert_relocate_error(url, num, msg):
    """Convert a permanently moved error."""
    # Try to guess the new url
    if "'" in msg:
        new_url = msg.split("'")[1]
    elif "«" in msg:
        new_url = msg[msg.index("»")+2:msg.index("«")]
    else:
        raise AssertionError("Unable to parse error message: %s" % msg)
    raise RedirectRequested(source=_url_escape_uri(url),
        target=_url_escape_uri(urlutils.join(url, new_url)),
        is_permanent=True)
Exemple #14
0
    def test_get_branch_path_old(self):
        repos_url = self.make_repository("a")

        dc = self.get_commit_editor(repos_url)
        dc.add_dir("trunk")
        dc.close()

        dc = self.get_commit_editor(repos_url)
        dc.add_dir("trunk2", "trunk", 1)
        dc.close()

        branch = Branch.open(urlutils.join(repos_url, "trunk2"))
        self.assertEqual("trunk2", branch.get_branch_path(2))
        self.assertEqual("trunk", branch.get_branch_path(1))
Exemple #15
0
    def test_set_get_parent(self):
        """Set, re-get and reset the parent"""
        b = self.make_branch('subdir')
        url = 'http://example.com/bzr/bzr.dev'
        b.set_parent(url)
        self.assertEqual(url, b.get_parent())
        self.assertEqual(url, b._get_parent_location())

        b.set_parent(None)
        self.assertEqual(None, b.get_parent())

        b.set_parent('../other_branch')

        expected_parent = urlutils.join(self.get_url('subdir'),
                                        '../other_branch')
        self.assertEqual(expected_parent, b.get_parent())
        path = urlutils.join(self.get_url('subdir'), '../yanb')
        b.set_parent(path)
        self.assertEqual('../yanb', b._get_parent_location())
        self.assertEqual(path, b.get_parent())

        self.assertRaises(urlutils.InvalidURL, b.set_parent, u'\xb5')
        b.set_parent(urlutils.escape(u'\xb5'))
        self.assertEqual('%C2%B5', b._get_parent_location())

        self.assertEqual(b.base + '%C2%B5', b.get_parent())

        # Handle the case for older style absolute local paths
        if sys.platform == 'win32':
            # TODO: jam 20060515 Do we want to special case Windows local
            #       paths as well? Nobody has complained about it.
            pass
        else:
            b.lock_write()
            b._set_parent_location('/local/abs/path')
            b.unlock()
            self.assertEqual('file:///local/abs/path', b.get_parent())
Exemple #16
0
    def __init__(self,
                 repository,
                 controldir,
                 branch_path,
                 mapping,
                 revnum=None,
                 project=None,
                 _skip_check=False):
        """Instantiate a new SvnBranch.

        :param repository: SvnRepository this branch is part of.
        :param controldir: Control dir this branch was opened on
        :param branch_path: Relative path inside the repository this
            branch is located at.
        :param revnum: Subversion revision number of the branch to
            look at; none for latest.
        :param _skip_check: If True, don't check if the branch actually exists.
        """
        self.repository = repository
        self.controldir = controldir
        self._format = SvnBranchFormat()
        self.layout = self.repository.get_layout()
        if not isinstance(branch_path, text_type):
            raise TypeError(branch_path)
        self._branch_path = branch_path.strip(u"/")
        self.base = urlutils.join(self.repository.base,
                                  urlutils.escape(
                                      self._branch_path)).rstrip("/")
        super(SvnBranch, self).__init__(mapping)
        self._lock_mode = None
        self._lock_count = 0
        self._clear_cached_state()
        if not _skip_check:
            try:
                if self.check_path() != NODE_DIR:
                    raise NotBranchError(self.base)
            except SubversionException as e:
                if e.args[1] == ERR_FS_NO_SUCH_REVISION:
                    raise NotBranchError(self.base)
                raise
        if project is None:
            try:
                project = self.layout.get_branch_project(branch_path)
            except NotSvnBranchPath:
                raise NotBranchError(branch_path)
        assert isinstance(project, text_type)
        self.project = project
        self.name = self.layout.get_branch_name(branch_path)
Exemple #17
0
 def check_file_revs(self, revid, branch_path, revnum, mapping, relpath):
     self._annotated = []
     for (revmeta, hidden, mapping) in self._repository._revmeta_provider._iter_reverse_revmeta_mapping_history(
             branch_path, revnum, to_revnum=0, mapping=mapping):
         if hidden:
             continue
         self._related_revs[revmeta.metarev.revnum] = revmeta, mapping
     self._text = ""
     path = urlutils.join(branch_path, relpath.encode("utf-8")).strip("/")
     try:
         self._repository.svn_transport.get_file_revs(path, -1, revnum,
             self._handler, include_merged_revisions=True)
     except subvertpy.SubversionException, (msg, num):
         if num == subvertpy.ERR_FS_NOT_FILE:
             return []
         raise
Exemple #18
0
    def _get_root_action(self,
                         path,
                         parent_ids,
                         overwrite,
                         append_revisions_only,
                         create_prefix=False):
        """Determine the action to take on the tree root.

        :param path: Branch path
        :param parent_ids: Parent ids
        :param overwrite: Whether to overwrite any existing history
        :param create_prefix: Whether to create the prefix for path
        :return: root_action tuple for use with SvnCommitBuilder
        """
        assert not append_revisions_only or not overwrite
        bp_parts = path.split("/")
        existing_bp_parts = check_dirs_exist(self.target.svn_transport,
                                             bp_parts, -1)
        if (len(existing_bp_parts) != len(bp_parts)
                and len(existing_bp_parts) + 1 != len(bp_parts)):
            existing_path = "/".join(existing_bp_parts)
            if create_prefix:
                create_branch_container(self.target.svn_transport, path,
                                        existing_path)
                return ("create", )
            raise MissingPrefix(path, existing_path)
        if len(existing_bp_parts) < len(bp_parts):
            # Branch doesn't exist yet
            return ("create", )
        (
            revmeta, hidden, mapping
        ) = self.target._revmeta_provider._iter_reverse_revmeta_mapping_history(
            path,
            self.target.get_latest_revnum(),
            to_revnum=0,
            mapping=self.target.get_mapping()).next()
        assert not hidden
        if tuple(parent_ids) == () or tuple(parent_ids) == (NULL_REVISION, ):
            return ("replace", revmeta.metarev.revnum)
        else:
            if revmeta.get_revision_id(mapping) != parent_ids[0]:
                if append_revisions_only:
                    raise AppendRevisionsOnlyViolation(
                        urlutils.join(self.target.base, path))
                return ("replace", revmeta.metarev.revnum)
            else:
                return ("open", revmeta.metarev.revnum)
 def make_stacked_target(self):
     base_tree = self.make_branch_and_tree('base')
     self.build_tree(['base/f1.txt'])
     base_tree.add(['f1.txt'], [b'f1.txt-id'])
     base_tree.commit('initial', rev_id=self.r1_key[0])
     self.build_tree(['base/f2.txt'])
     base_tree.add(['f2.txt'], [b'f2.txt-id'])
     base_tree.commit('base adds f2', rev_id=self.r2_key[0])
     stacked_url = urlutils.join(base_tree.branch.base, '../stacked')
     stacked_bzrdir = base_tree.controldir.sprout(stacked_url, stacked=True)
     if isinstance(stacked_bzrdir, remote.RemoteBzrDir):
         stacked_branch = stacked_bzrdir.open_branch()
         stacked_tree = stacked_branch.create_checkout('stacked',
                                                       lightweight=True)
     else:
         stacked_tree = stacked_bzrdir.open_workingtree()
     return base_tree, stacked_tree
Exemple #20
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)
Exemple #21
0
    def _get_colocated_branch(self, source_branch, prefix, remember_parent):
        target_dir = self.get_dir(prefix, prefix)

        if source_branch.project in (None, ""):
            name = source_branch.name
        else:
            if source_branch.name is None:
                name = source_branch.project
            else:
                name = urlutils.join(source_branch.project, source_branch.name)

        try:
            return target_dir.open_branch(name)
        except NotBranchError:
            target_branch = target_dir.create_branch(name)
            if remember_parent:
                target_branch.set_parent(source_branch.base)
            return target_branch
Exemple #22
0
 def app_for_non_branch(self, environ):
     segment = path_info_pop(environ)
     if segment is None:
         raise httpexceptions.HTTPMovedPermanently.relative_redirect(
             environ['SCRIPT_NAME'] + '/', environ)
     elif segment == '':
         if self.name:
             name = self.name
         else:
             name = '/'
         return DirectoryUI(environ['loggerhead.static.url'],
                            self.transport, name)
     else:
         new_transport = self.transport.clone(segment)
         if self.name:
             new_name = urlutils.join(self.name, segment)
         else:
             new_name = '/' + segment
         return BranchesFromTransportServer(new_transport, self.root,
                                            new_name)
Exemple #23
0
 def mkdir(self, relpath, mode=None, message=u"Creating directory"):
     relpath = urlutils.join(self.repos_path, relpath)
     dirname, basename = urlutils.split(relpath)
     conn = self.get_connection(dirname.strip("/"))
     try:
         with conn.get_commit_editor({"svn:log": message}) as ce:
             try:
                 with ce.open_root(-1) as node:
                     node.add_directory(relpath, None, -1).close()
             except subvertpy.SubversionException as e:
                 msg, num = e.args
                 if num == ERR_FS_NOT_FOUND:
                     raise NoSuchFile(msg)
                 if num == ERR_FS_NOT_DIRECTORY:
                     raise NoSuchFile(msg)
                 if num == subvertpy.ERR_FS_ALREADY_EXISTS:
                     raise FileExists(msg)
                 raise
     finally:
         self.add_connection(conn)
Exemple #24
0
 def root_inventory(self):
     # FIXME
     if self._bzr_inventory is not None:
         return self._bzr_inventory
     self._bzr_inventory = Inventory()
     self._bzr_inventory.revision_id = self.get_revision_id()
     root_repos = self._repository.svn_transport.get_svn_repos_root()
     editor = TreeBuildEditor(self)
     conn = self._repository.svn_transport.get_connection()
     try:
         reporter = conn.do_switch(
             self._revmeta.metarev.revnum, "", True,
             urlutils.join(root_repos, self._revmeta.metarev.branch_path).rstrip("/"), editor)
         try:
             reporter.set_path("", 0, True, None)
             reporter.finish()
         except:
             reporter.abort()
             raise
     finally:
         self._repository.svn_transport.add_connection(conn)
     return self._bzr_inventory
Exemple #25
0
    def _create_lightweight_checkout(self, to_location, revision_id=None):
        """Create a new lightweight checkout of this branch.

        :param to_location: URL of location to create the checkout in.
        :param revision_id: Tip of the checkout.
        :return: WorkingTree object of the checkout.
        """
        from .workingtree import (
            SvnCheckout,
            SvnWorkingTreeDirFormat,
            update_wc,
        )
        if revision_id is None or revision_id == self.last_revision():
            bp = self.get_branch_path()
            uuid = self.repository.uuid
            revnum = self.get_revnum()
        else:
            (uuid, bp,
             revnum), mapping = self.lookup_bzr_revision_id(revision_id)

        transport = get_transport(to_location)
        transport.ensure_base()
        to_path = transport.local_abspath(".")
        svn_url, readonly = bzr_to_svn_url(
            urlutils.join(self.repository.base, bp))
        wc.ensure_adm(to_path.encode("utf-8"), uuid, svn_url,
                      bzr_to_svn_url(self.repository.base)[0], revnum)
        with wc.Adm(None, to_path.encode("utf-8"), write_lock=True) as adm:
            conn = self.repository.svn_transport.connections.get(svn_url)
            try:
                update_wc(adm, to_path.encode("utf-8"), conn, svn_url, revnum)
            finally:
                if not conn.busy:
                    self.repository.svn_transport.add_connection(conn)

        dir = SvnCheckout(transport, SvnWorkingTreeDirFormat())
        return dir.open_workingtree()
Exemple #26
0
 def _todo(self, target_branch, last_revid, last_foreign_revid, stop_revision, project,
         overwrite, append_revisions_only):
     graph = self.get_graph()
     todo = []
     if append_revisions_only:
         for revid in graph.iter_lefthand_ancestry(stop_revision,
                 (NULL_REVISION, None)):
             if revid == last_revid:
                 break
             todo.append(revid)
         else:
             if last_revid != NULL_REVISION:
                 url = urlutils.join(self.target.base, target_branch)
                 raise AppendRevisionsOnlyViolation(url)
         todo.reverse()
         return todo, ("open", last_foreign_revid[2])
     else:
         for revid in graph.iter_lefthand_ancestry(stop_revision,
                 (NULL_REVISION, None)):
             if self._target_has_revision(revid, project=project):
                 break
             todo.append(revid)
         todo.reverse()
         return todo, ("replace", last_foreign_revid[2])
Exemple #27
0
 def is_tag_parent(self, path, project=None):
     return self.is_tag(urlutils.join(path, u"trunk"), project)
Exemple #28
0
 def get_tag_path(self, name, project=""):
     if project == u"":
         return urlutils.join(u"tags", name)
     return urlutils.join(project, u"tags", name)
Exemple #29
0
 def _add_project(self, path, project=None):
     if project is None:
         return path
     return urlutils.join(project, path)
Exemple #30
0
 def test_local_abspath(self):
     repos_url = self.make_svn_repository('a')
     t = SvnRaTransport("%s" % repos_url)
     self.assertEquals(urlutils.join(self.test_dir, "a"),
                       t.local_abspath('.'))