def revision(self, nodeorrev):
        """return an uncompressed revision of a given node or revision
        number.
        """
        if isinstance(nodeorrev, int):
            rev = nodeorrev
            node = self.node(rev)
        else:
            node = nodeorrev
            rev = None

        cachedrev = None
        if node == nullid:
            return ""
        if self._cache:
            if self._cache[0] == node:
                return self._cache[2]
            cachedrev = self._cache[1]

        # look up what we need to read
        text = None
        if rev is None:
            rev = self.rev(node)

        # check rev flags
        if self.flags(rev) & ~REVIDX_KNOWN_FLAGS:
            raise RevlogError(_('incompatible revision flag %x') %
                              (self.flags(rev) & ~REVIDX_KNOWN_FLAGS))

        # build delta chain
        chain = []
        index = self.index # for performance
        generaldelta = self._generaldelta
        iterrev = rev
        e = index[iterrev]
        while iterrev != e[3] and iterrev != cachedrev:
            chain.append(iterrev)
            if generaldelta:
                iterrev = e[3]
            else:
                iterrev -= 1
            e = index[iterrev]
        chain.reverse()
        base = iterrev

        if iterrev == cachedrev:
            # cache hit
            text = self._cache[2]

        # drop cache to save memory
        self._cache = None

        self._chunkraw(base, rev)
        if text is None:
            text = str(self._chunkbase(base))

        bins = [self._chunk(r) for r in chain]
        text = mdiff.patches(text, bins)

        text = self._checkhash(text, node, rev)

        self._cache = (node, rev, text)
        return text