Beispiel #1
0
    def get_changes(self):
        root = fs.revision_root(self.fs_ptr, self.rev)
        editor = repos.RevisionChangeCollector(self.fs_ptr, self.rev)
        e_ptr, e_baton = delta.make_editor(editor)
        repos.svn_repos_replay(root, e_ptr, e_baton)

        idx = 0
        # Variables to record copy/deletes for later move detection
        copies, deletions = {}, {}
        changes = []
        for path, change in core._as_list(editor.changes.items()):
            if not self.authz.has_permission(path):
                # FIXME: what about base_path?
                continue
            if not path.startswith(self.scope[1:]):
                continue
            base_path = None
            if change.base_path:
                if change.base_path.startswith(self.scope):
                    base_path = change.base_path[len(self.scope):]
                else:
                    base_path = None
            action = ''
            if change.action == repos.CHANGE_ACTION_DELETE:
                action = Changeset.DELETE
                # Save off the index within changes of this deletion
                deletions[change.base_path] = idx
            elif change.added:
                if change.base_path and change.base_rev:
                    action = Changeset.COPY
                    # Save off the index within changes of this copy
                    copies[change.base_path] = idx
                else:
                    action = Changeset.ADD
            else:
                action = Changeset.EDIT
            kind = _kindmap[change.item_kind]
            path = path[len(self.scope) - 1:]
            changes.append([path, kind, action, base_path, change.base_rev])
            idx += 1

        # Detect moves by checking for copies whose source was deleted in this
        # change set.
        moves = set()
        for k, v in core._as_list(copies.items()):
            if k in deletions:
                changes[v][2] = Changeset.MOVE
                # Record the index of the now redundant delete action.
                moves.add(deletions[k])

        for i, change in enumerate(changes):
            # Do not return the 'delete' changes that were part of moves.
            if i not in moves:
                yield tuple(change)
Beispiel #2
0
    def get_changes(self):
        pool = Pool(self.pool)
        root = fs.revision_root(self.fs_ptr, self.rev, pool())
        editor = repos.RevisionChangeCollector(self.fs_ptr, self.rev, pool())
        e_ptr, e_baton = delta.make_editor(editor, pool())
        repos.svn_repos_replay(root, e_ptr, e_baton, pool())

        idx = 0
        copies, deletions = {}, {}
        changes = []
        for path, change in editor.changes.items():
            if not self.authz.has_permission(path):
                # FIXME: what about base_path?
                continue
            if not path.startswith(self.scope[1:]):
                continue
            base_path = None
            if change.base_path:
                if change.base_path.startswith(self.scope):
                    base_path = change.base_path[len(self.scope):]
                else:
                    base_path = None
            action = ''
            if not change.path:
                action = Changeset.DELETE
                deletions[change.base_path] = idx
            elif change.added:
                if change.base_path and change.base_rev:
                    action = Changeset.COPY
                    copies[change.base_path] = idx
                else:
                    action = Changeset.ADD
            else:
                action = Changeset.EDIT
            kind = _kindmap[change.item_kind]
            path = path[len(self.scope) - 1:]
            changes.append([path, kind, action, base_path, change.base_rev])
            idx += 1

        moves = []
        for k, v in copies.items():
            if k in deletions:
                changes[v][2] = Changeset.MOVE
                moves.append(deletions[k])
        offset = 0
        for i in moves:
            del changes[i - offset]
            offset += 1

        changes.sort()
        for change in changes:
            yield tuple(change)
Beispiel #3
0
    def get_changes(self):
        """Retrieve file changes for a given revision.

        (wraps ``repos.svn_repos_replay``)
        """
        pool = Pool(self.pool)
        tmp = Pool(pool)
        root = fs.revision_root(self.fs_ptr, self.rev, pool())
        editor = repos.RevisionChangeCollector(self.fs_ptr, self.rev, pool())
        e_ptr, e_baton = delta.make_editor(editor, pool())
        repos.svn_repos_replay(root, e_ptr, e_baton, pool())

        idx = 0
        copies, deletions = {}, {}
        changes = []
        revroots = {}
        for path_utf8, change in editor.changes.items():
            new_path = _from_svn(path_utf8)

            # Filtering on `path`
            if not _is_path_within_scope(self.scope, new_path):
                continue

            path_utf8 = change.path
            base_path_utf8 = change.base_path
            path = _from_svn(path_utf8)
            base_path = _from_svn(base_path_utf8)
            base_rev = change.base_rev
            change_action = getattr(change, 'action', None)

            # Ensure `base_path` is within the scope
            if not _is_path_within_scope(self.scope, base_path):
                base_path, base_rev = None, -1

            # Determine the action
            if not path and not new_path and self.scope == '/':
                action = Changeset.EDIT # root property change
            elif not path or (change_action is not None
                              and change_action == repos.CHANGE_ACTION_DELETE):
                if new_path:            # deletion
                    action = Changeset.DELETE
                    deletions[new_path.lstrip('/')] = idx
                else:                   # deletion outside of scope, ignore
                    continue
            elif change.added or not base_path: # add or copy
                action = Changeset.ADD
                if base_path and base_rev:
                    action = Changeset.COPY
                    copies[base_path.lstrip('/')] = idx
            else:
                action = Changeset.EDIT
                # identify the most interesting base_path/base_rev
                # in terms of last changed information (see r2562)
                if base_rev in revroots:
                    b_root = revroots[base_rev]
                else:
                    b_root = fs.revision_root(self.fs_ptr, base_rev, pool())
                    revroots[base_rev] = b_root
                tmp.clear()
                cbase_path_utf8 = fs.node_created_path(b_root, base_path_utf8,
                                                       tmp())
                cbase_path = _from_svn(cbase_path_utf8)
                cbase_rev = fs.node_created_rev(b_root, base_path_utf8, tmp())
                # give up if the created path is outside the scope
                if _is_path_within_scope(self.scope, cbase_path):
                    base_path, base_rev = cbase_path, cbase_rev

            kind = _kindmap[change.item_kind]
            path = _path_within_scope(self.scope, new_path or base_path)
            base_path = _path_within_scope(self.scope, base_path)
            changes.append([path, kind, action, base_path, base_rev])
            idx += 1

        moves = []
        # a MOVE is a COPY whose `base_path` corresponds to a `new_path`
        # which has been deleted
        for k, v in copies.items():
            if k in deletions:
                changes[v][2] = Changeset.MOVE
                moves.append(deletions[k])
        offset = 0
        moves.sort()
        for i in moves:
            del changes[i - offset]
            offset += 1

        changes.sort()
        for change in changes:
            yield tuple(change)
Beispiel #4
0
    def get_changes(self):
        pool = Pool(self.pool)
        tmp = Pool(pool)
        root = fs.revision_root(self.fs_ptr, self.rev, pool())
        editor = repos.RevisionChangeCollector(self.fs_ptr, self.rev, pool())
        e_ptr, e_baton = delta.make_editor(editor, pool())
        repos.svn_repos_replay(root, e_ptr, e_baton, pool())

        idx = 0
        copies, deletions = {}, {}
        changes = []
        revroots = {}
        for path, change in editor.changes.items():

            # Filtering on `path`
            if not (_is_path_within_scope(self.scope, path) and \
                    self.authz.has_permission(path)):
                continue

            path = change.path
            base_path = change.base_path
            base_rev = change.base_rev

            # Ensure `base_path` is within the scope
            if not (_is_path_within_scope(self.scope, base_path) and \
                    self.authz.has_permission(base_path)):
                base_path, base_rev = None, -1

            # Determine the action
            if not path:  # deletion
                if base_path:
                    if base_path in deletions:
                        continue  # duplicates on base_path are possible (#3778)
                    action = Changeset.DELETE
                    deletions[base_path] = idx
                elif self.scope:  # root property change
                    action = Changeset.EDIT
                else:  # deletion outside of scope, ignore
                    continue
            elif change.added or not base_path:  # add or copy
                action = Changeset.ADD
                if base_path and base_rev:
                    action = Changeset.COPY
                    copies[base_path] = idx
            else:
                action = Changeset.EDIT
                # identify the most interesting base_path/base_rev
                # in terms of last changed information (see r2562)
                if revroots.has_key(base_rev):
                    b_root = revroots[base_rev]
                else:
                    b_root = fs.revision_root(self.fs_ptr, base_rev, pool())
                    revroots[base_rev] = b_root
                tmp.clear()
                cbase_path = fs.node_created_path(b_root, base_path, tmp())
                cbase_rev = fs.node_created_rev(b_root, base_path, tmp())
                # give up if the created path is outside the scope
                if _is_path_within_scope(self.scope, cbase_path):
                    base_path, base_rev = cbase_path, cbase_rev

            kind = _kindmap[change.item_kind]
            path = _path_within_scope(self.scope, _from_svn(path or base_path))
            base_path = _path_within_scope(self.scope, _from_svn(base_path))
            changes.append([path, kind, action, base_path, base_rev])
            idx += 1

        moves = []
        for k, v in copies.items():
            if k in deletions:
                changes[v][2] = Changeset.MOVE
                moves.append(deletions[k])
        offset = 0
        moves.sort()
        for i in moves:
            del changes[i - offset]
            offset += 1

        changes.sort()
        for change in changes:
            yield tuple(change)
Beispiel #5
0
def main(pool, repos_dir, rev, config_fp):
    # Construct a ChangeCollector to fetch our changes.
    fs_ptr = repos.svn_repos_fs(repos.svn_repos_open(repos_dir, pool))
    root = fs.revision_root(fs_ptr, rev, pool)

    # Get revision properties we need. (Subversion 1.2)
    # cc = repos.ChangeCollector(fs_ptr, root, pool)
    # props = cc.get_root_props()
    # author = str(props.get(core.SVN_PROP_REVISION_AUTHOR, ''))
    # log = str(props.get(core.SVN_PROP_REVISION_LOG, ''))

    # Get revision properties we need. (Subversion 1.1)
    cc = repos.RevisionChangeCollector(fs_ptr, rev, pool)
    author = fs.revision_prop(fs_ptr, rev, core.SVN_PROP_REVISION_AUTHOR, pool)
    log = fs.revision_prop(fs_ptr, rev, core.SVN_PROP_REVISION_LOG, pool)

    ### Do any Subversion-to-Scarab author mappings here ###

    # Example:
    #  _authors = {
    #   'miw':'mick',
    #   'lif':'lisefr',
    #   'gni':'gunleik',
    #   'man':'Maja',
    #   'ako':'konand',
    #   'hho':'helga',
    #   'hba':'hilde',
    #   'rgc':'rgc'
    #   }
    #  author = _authors.get(author, author)

    # Now build the comment.  First we start with some header
    # information about the revision, and a link to the ViewCVS revision
    # view.
    e_ptr, e_baton = delta.make_editor(cc, pool)
    repos.svn_repos_replay(root, e_ptr, e_baton, pool)
    comment = "%s %d:    %s/?view=rev&rev=%d\n" \
              % (MSG_SUBVERSION_COMMIT, rev, VIEWCVS_URL, rev)
    comment = comment + \
  """-------------------------------------------------------------------------
%s
-------------------------------------------------------------------------
""" % log

    # Next, we'll figure out which paths changed and use that
    # information to generate ViewCVS links.
    #  changes = cc.get_changes() # Subversion 1.2
    changes = cc.changes  # Subversion 1.1
    paths = changes.keys()
    #  paths.sort(lambda a, b: core.svn_path_compare_paths(a, b)) # Subversion 1.2
    for path in paths:
        change = changes[path]
        diff_url = ''
        action = None
        if not change.path:  ### Deleted (show the last living version)
            action = MSG_ACTION_DELETED
            diff_url = '%s/%s?view=auto&rev=%d' \
                       % (VIEWCVS_URL,
                          urllib.quote(change.base_path[1:]), change.base_rev)
        elif change.added:  ### Added
            if change.base_path and (change.base_rev !=
                                     -1):  ### (with history)
                action = MSG_ACTION_COPIED
                diff_url = '%s/%s?view=diff&rev=%d&p1=%s&r1=%d&p2=%s&r2=%d' \
                           % (VIEWCVS_URL,
                              urllib.quote(change.path), rev,
                              urllib.quote(change.base_path[1:]), change.base_rev,
                              urllib.quote(change.path), rev)
            else:  ### (without history, show new file)
                action = MSG_ACTION_ADDED
                diff_url = '%s/%s?view=auto&rev=%d' \
                           % (VIEWCVS_URL,
                              urllib.quote(change.path), rev)
        elif change.text_changed:  ### Modified
            action = MSG_ACTION_MODIFIED
            diff_url = '%s/%s?view=diff&rev=%d&p1=%s&r1=%d&p2=%s&r2=%d' \
                       % (VIEWCVS_URL,
                          urllib.quote(change.path), rev,
                          urllib.quote(change.base_path[1:]), change.base_rev,
                          urllib.quote(change.path), rev)
        if action:
            comment = comment + "%s: %s\n    %s\n" % (action, path, diff_url)

    # Connect to the xmlrpc server, and transmit our data.
    Server(SCARAB_XMLRPC_URL).simple.addComment(log, author, comment,
                                                DISABLE_EMAILS)