Esempio n. 1
0
File: svn_fs.py Progetto: t2y/trac
    def __init__(self, path, rev, repos, pool=None, parent_root=None):
        self.fs_ptr = repos.fs_ptr
        self.scope = repos.scope
        self.pool = Pool(pool)
        pool = self.pool()
        self._scoped_path_utf8 = _to_svn(pool, self.scope, path)

        if parent_root:
            self.root = parent_root
        else:
            self.root = fs.revision_root(self.fs_ptr, rev, pool)
        node_type = fs.check_path(self.root, self._scoped_path_utf8, pool)
        if not node_type in _kindmap:
            raise NoSuchNode(path, rev)
        cp_utf8 = fs.node_created_path(self.root, self._scoped_path_utf8, pool)
        cp = _from_svn(cp_utf8)
        cr = fs.node_created_rev(self.root, self._scoped_path_utf8, pool)
        # Note: `cp` differs from `path` if the last change was a copy,
        #        In that case, `path` doesn't even exist at `cr`.
        #        The only guarantees are:
        #          * this node exists at (path,rev)
        #          * the node existed at (created_path,created_rev)
        # Also, `cp` might well be out of the scope of the repository,
        # in this case, we _don't_ use the ''create'' information.
        if _is_path_within_scope(self.scope, cp):
            self.created_rev = cr
            self.created_path = _path_within_scope(self.scope, cp)
        else:
            self.created_rev, self.created_path = rev, path
        # TODO: check node id
        Node.__init__(self, repos, path, rev, _kindmap[node_type])
Esempio n. 2
0
    def __init__(self, git, path, rev, tree_ls_info=None):
        self.git = git
        self.sha = rev
        self.perm = None
        self.data_len = None

        kind = Node.DIRECTORY
        p = path.strip('/')
        if p != "":
            if tree_ls_info == None or tree_ls_info == "":
                tree_ls_info = git.tree_ls(rev, p)
                if tree_ls_info != []:
                    [tree_ls_info] = tree_ls_info
                else:
                    tree_ls_info = None

            if tree_ls_info is None:
                raise NoSuchNode(path, rev)

            (self.perm, k, self.sha, fn) = tree_ls_info

            rev = self.git.last_change(rev, p)

            if k == 'tree':
                pass
            elif k == 'blob':
                kind = Node.FILE
            else:
                self.log.debug("kind is " + k)

        Node.__init__(self, path, rev, kind)

        self.created_path = path
        self.created_rev = rev
Esempio n. 3
0
 def _get_kind(self):
     if self._node.isDirectory:
         return Node.DIRECTORY
     elif self._node.isFile:
         return Node.FILE
     else:
         raise NoSuchNode(self._nodePath.path, self._nodePath.rev)
Esempio n. 4
0
def _get_node(path, rev=None):
    if path == 'foo':
        return Mock(path=path, rev=rev, isfile=False,
                    is_viewable=lambda resource: True)
    elif path == 'missing/file':
        raise NoSuchNode(path, rev)
    else:
        return Mock(path=path, rev=rev, isfile=True,
                    is_viewable=lambda resource: True)
Esempio n. 5
0
 def _init_path(self, log, path):
     kind = None
     if path in self.manifest:  # then it's a file
         kind = Node.FILE
         file_n = self.manifest[path]
         log_rev = self.repos.repo.file(path).linkrev(file_n)
         node = log.node(log_rev)
     else:  # it will be a directory if there are matching entries
         dir = path and path + '/' or ''
         entries = {}
         newest = -1
         for file in self.manifest.keys():
             if file.startswith(dir):
                 entry = file[len(dir):].split('/', 1)[0]
                 entries[entry] = 1
                 if path:  # small optimization: we skip this for root node
                     file_n = self.manifest[file]
                     log_rev = self.repos.repo.file(file).linkrev(file_n)
                     newest = max(log_rev, newest)
         if entries:
             kind = Node.DIRECTORY
             self.entries = entries.keys()
             if newest >= 0:
                 node = log.node(newest)
             else:  # ... as it's the youngest anyway
                 node = log.tip()
     if not kind:
         if log.tip() == nullid:  # empty repository
             kind = Node.DIRECTORY
             self.entries = []
             node = nullid
         else:
             raise NoSuchNode(path, self.repos.hg_display(self.n))
     self.time = self.repos.hg_time(log.read(node)[2])
     rev = self.repos.hg_display(node)
     Node.__init__(self, path, rev, kind)
     self.created_path = path
     self.created_rev = rev
     self.data = None
Esempio n. 6
0
File: svn_fs.py Progetto: t2y/trac
    def get_changes(self, old_path, old_rev, new_path, new_rev,
                    ignore_ancestry=0):
        """Determine differences between two arbitrary pairs of paths
        and revisions.

        (wraps ``repos.svn_repos_dir_delta``)
        """
        old_node = new_node = None
        old_rev = self.normalize_rev(old_rev)
        new_rev = self.normalize_rev(new_rev)
        if self.has_node(old_path, old_rev):
            old_node = self.get_node(old_path, old_rev)
        else:
            raise NoSuchNode(old_path, old_rev, 'The Base for Diff is invalid')
        if self.has_node(new_path, new_rev):
            new_node = self.get_node(new_path, new_rev)
        else:
            raise NoSuchNode(new_path, new_rev,
                             'The Target for Diff is invalid')
        if new_node.kind != old_node.kind:
            raise TracError(_('Diff mismatch: Base is a %(oldnode)s '
                              '(%(oldpath)s in revision %(oldrev)s) and '
                              'Target is a %(newnode)s (%(newpath)s in '
                              'revision %(newrev)s).', oldnode=old_node.kind,
                              oldpath=old_path, oldrev=old_rev,
                              newnode=new_node.kind, newpath=new_path,
                              newrev=new_rev))
        subpool = Pool(self.pool)
        if new_node.isdir:
            editor = DiffChangeEditor()
            e_ptr, e_baton = delta.make_editor(editor, subpool())
            old_root = fs.revision_root(self.fs_ptr, old_rev, subpool())
            new_root = fs.revision_root(self.fs_ptr, new_rev, subpool())
            def authz_cb(root, path, pool):
                return 1
            text_deltas = 0 # as this is anyway re-done in Diff.py...
            entry_props = 0 # "... typically used only for working copy updates"
            repos.svn_repos_dir_delta(old_root,
                                      _to_svn(subpool(), self.scope, old_path),
                                      '', new_root,
                                      _to_svn(subpool(), self.scope, new_path),
                                      e_ptr, e_baton, authz_cb,
                                      text_deltas,
                                      1, # directory
                                      entry_props,
                                      ignore_ancestry,
                                      subpool())
            # sort deltas by path before creating `SubversionNode`s to reduce
            # memory usage (#10978)
            deltas = sorted(((_from_svn(path), kind, change)
                             for path, kind, change in editor.deltas),
                            key=lambda entry: entry[0])
            for path, kind, change in deltas:
                old_node = new_node = None
                if change != Changeset.ADD:
                    old_node = self.get_node(posixpath.join(old_path, path),
                                             old_rev)
                if change != Changeset.DELETE:
                    new_node = self.get_node(posixpath.join(new_path, path),
                                             new_rev)
                else:
                    kind = _kindmap[fs.check_path(old_root,
                                                  _to_svn(subpool(),
                                                          self.scope,
                                                          old_node.path),
                                                  subpool())]
                yield  (old_node, new_node, kind, change)
        else:
            old_root = fs.revision_root(self.fs_ptr, old_rev, subpool())
            new_root = fs.revision_root(self.fs_ptr, new_rev, subpool())
            if fs.contents_changed(old_root,
                                   _to_svn(subpool(), self.scope, old_path),
                                   new_root,
                                   _to_svn(subpool(), self.scope, new_path),
                                   subpool()):
                yield (old_node, new_node, Node.FILE, Changeset.EDIT)
Esempio n. 7
0
    def get_changes(self,
                    old_path,
                    old_rev,
                    new_path,
                    new_rev,
                    ignore_ancestry=0):
        old_node = new_node = None
        old_rev = self.normalize_rev(old_rev)
        new_rev = self.normalize_rev(new_rev)
        if self.has_node(old_path, old_rev):
            old_node = self.get_node(old_path, old_rev)
        else:
            raise NoSuchNode(old_path, old_rev, 'The Base for Diff is invalid')
        if self.has_node(new_path, new_rev):
            new_node = self.get_node(new_path, new_rev)
        else:
            raise NoSuchNode(new_path, new_rev,
                             'The Target for Diff is invalid')
        if new_node.kind != old_node.kind:
            raise TracError('Diff mismatch: Base is a %s (%s in revision %s) '
                            'and Target is a %s (%s in revision %s).' \
                            % (old_node.kind, old_path, old_rev,
                               new_node.kind, new_path, new_rev))
        subpool = Pool(self.pool)
        if new_node.isdir:
            editor = DiffChangeEditor()
            e_ptr, e_baton = delta.make_editor(editor, subpool())
            old_root = fs.revision_root(self.fs_ptr, old_rev, subpool())
            new_root = fs.revision_root(self.fs_ptr, new_rev, subpool())

            def authz_cb(root, path, pool):
                return 1

            text_deltas = 0  # as this is anyway re-done in Diff.py...
            entry_props = 0  # "... typically used only for working copy updates"
            repos.svn_repos_dir_delta(
                old_root,
                _to_svn(self.scope + old_path),
                '',
                new_root,
                _to_svn(self.scope + new_path),
                e_ptr,
                e_baton,
                authz_cb,
                text_deltas,
                1,  # directory
                entry_props,
                ignore_ancestry,
                subpool())
            for path, kind, change in editor.deltas:
                path = _from_svn(path)
                old_node = new_node = None
                if change != Changeset.ADD:
                    old_node = self.get_node(posixpath.join(old_path, path),
                                             old_rev)
                if change != Changeset.DELETE:
                    new_node = self.get_node(posixpath.join(new_path, path),
                                             new_rev)
                else:
                    kind = _kindmap[fs.check_path(
                        old_root, _to_svn(self.scope, old_node.path),
                        subpool())]
                yield (old_node, new_node, kind, change)
        else:
            old_root = fs.revision_root(self.fs_ptr, old_rev, subpool())
            new_root = fs.revision_root(self.fs_ptr, new_rev, subpool())
            if fs.contents_changed(old_root, _to_svn(self.scope, old_path),
                                   new_root, _to_svn(self.scope, new_path),
                                   subpool()):
                yield (old_node, new_node, Node.FILE, Changeset.EDIT)
Esempio n. 8
0
    def get_history(self, limit=None):
        self._log.debug('PerforceNode.get_history(%r %s)' %
                        (limit, self._nodePath.fullPath))
        if self._node.isFile:

            # Force population of the filelog history for efficiency
            from p4trac.repos import _P4FileLogOutputConsumer
            output = _P4FileLogOutputConsumer(self._repos)

            if limit is None:
                self._repos._connection.run('filelog',
                                            '-i',
                                            '-l',
                                            self._repos.fromUnicode(
                                                self._nodePath.fullPath),
                                            output=output)
            else:
                self._repos._connection.run('filelog',
                                            '-i',
                                            '-l',
                                            '-m',
                                            str(limit),
                                            self._repos.fromUnicode(
                                                self._nodePath.fullPath),
                                            output=output)

            from p4trac.repos import NodePath

            currentNode = self._node
            i = 0
            while i < limit and currentNode is not None:
                if currentNode.action in [u'add', u'branch', u'import']:
                    if currentNode.integrations:
                        nodePath, how = currentNode.integrations[0]

                        # TODO: Detect whether the copy was really a move
                        yield (normalisePath(currentNode.nodePath.path),
                               currentNode.change, Changeset.COPY)

                        currentNode = self._repos.getNode(nodePath)
                    else:
                        yield (normalisePath(currentNode.nodePath.path),
                               currentNode.change, Changeset.ADD)

                        if currentNode.fileRevision > 1:
                            # Get the previous revision
                            nodePath = NodePath(
                                currentNode.nodePath.path,
                                '#%i' % (currentNode.fileRevision - 1))
                            currentNode = self._repos.getNode(nodePath)
                        else:
                            currentNode = None

                elif currentNode.action in [u'edit', u'integrate']:

                    nextNode = None

                    if currentNode.integrations:
                        nodePath, how = currentNode.integrations[0]

                        if how == 'copy':
                            yield (normalisePath(currentNode.nodePath.path),
                                   currentNode.change, Changeset.COPY)
                            nextNode = self._repos.getNode(nodePath)
                        else:
                            yield (normalisePath(currentNode.nodePath.path),
                                   currentNode.change, Changeset.EDIT)
                    else:
                        yield (normalisePath(currentNode.nodePath.path),
                               currentNode.change, Changeset.EDIT)

                    if nextNode is None:
                        if currentNode.fileRevision > 1:
                            currentNode = self._repos.getNode(
                                NodePath(
                                    currentNode.nodePath.path,
                                    '#%i' % (currentNode.fileRevision - 1)))
                        else:
                            currentNode = None
                    else:
                        currentNode = nextNode

                elif currentNode.action in [u'delete']:
                    yield (normalisePath(currentNode.nodePath.path),
                           currentNode.change, Changeset.DELETE)

                    if currentNode.fileRevision > 1:
                        currentNode = self._repos.getNode(
                            NodePath(currentNode.nodePath.path,
                                     '#%i' % (currentNode.fileRevision - 1)))
                    else:
                        currentNode = None

                i += 1

        elif self._node.isDirectory:

            # List all changelists that have affected this directory
            from p4trac.repos import _P4ChangesOutputConsumer
            output = _P4ChangesOutputConsumer(self._repos)

            if self._nodePath.isRoot:
                queryPath = '@<=%s' % self._nodePath.rev[1:]
            else:
                queryPath = '%s/...@<=%s' % (self._nodePath.path,
                                             self._nodePath.rev[1:])

            if limit is None:
                self._repos._connection.run('changes',
                                            '-l',
                                            '-s',
                                            'submitted',
                                            self._repos.fromUnicode(queryPath),
                                            output=output)
            else:
                self._repos._connection.run('changes',
                                            '-l',
                                            '-s',
                                            'submitted',
                                            '-m',
                                            str(limit),
                                            self._repos.fromUnicode(queryPath),
                                            output=output)

            if output.errors:
                raise PerforceError(output.errors)

            changes = output.changes

            # And describe the contents of those changelists
            from p4trac.repos import _P4DescribeOutputConsumer
            output = _P4DescribeOutputConsumer(self._repos)
            self._repos._connection.run('describe',
                                        '-s',
                                        output=output,
                                        *[str(c) for c in changes])

            from p4trac.repos import NodePath

            for i in xrange(len(changes)):
                change = changes[i]
                nodePath = NodePath(self._nodePath.path, change)

                if i < len(changes) - 1:
                    prevChange = changes[i + 1]
                else:
                    prevChange = change - 1

                prevNodePath = NodePath(self._nodePath.path, prevChange)

                node = self._repos.getNode(nodePath)
                prevNode = self._repos.getNode(prevNodePath)

                if node.isDirectory:
                    if prevNode.isDirectory:
                        yield (normalisePath(self._nodePath.path), change,
                               Changeset.EDIT)
                    else:
                        yield (normalisePath(self._nodePath.path), change,
                               Changeset.ADD)
                elif prevNode.isDirectory:
                    yield (normalisePath(self._nodePath.path), change,
                           Changeset.DELETE)

        else:
            raise NoSuchNode(self._nodePath.path, self._nodePath.rev)