Ejemplo n.º 1
0
def main(pool, repos_dir, txn):
    # Construct a ChangeCollector to fetch our changes.
    fs_ptr = repos.svn_repos_fs(repos.svn_repos_open(repos_dir, pool))
    root = fs.txn_root(fs.open_txn(fs_ptr, txn, pool), pool)
    cc = repos.ChangeCollector(fs_ptr, root, pool)

    # Call the transaction property validator.  Might as well get the
    # cheap checks outta the way first.
    retval = test_props(cc.get_root_props())
    if retval:
        return retval

    # Generate the path-based changes list.
    e_ptr, e_baton = delta.make_editor(cc, pool)
    repos.svn_repos_replay(root, e_ptr, e_baton, pool)

    # Call the path change validator.
    changes = cc.get_changes()
    paths = changes.keys()
    paths.sort(lambda a, b: core.svn_path_compare_paths(a, b))
    for path in paths:
        change = changes[path]
        retval = test_path_change(path, change)
        if retval:
            return retval

    return 0
Ejemplo n.º 2
0
def main(pool, repos_dir, txn):
  # Construct a ChangeCollector to fetch our changes.
  fs_ptr = repos.svn_repos_fs(repos.svn_repos_open(repos_dir, pool))
  root = fs.txn_root(fs.open_txn(fs_ptr, txn, pool), pool)
  cc = repos.ChangeCollector(fs_ptr, root, pool)

  # Call the transaction property validator.  Might as well get the
  # cheap checks outta the way first.
  retval = test_props(cc.get_root_props())
  if retval:
    return retval

  # Generate the path-based changes list.
  e_ptr, e_baton = delta.make_editor(cc, pool)
  repos.svn_repos_replay(root, e_ptr, e_baton, pool)

  # Call the path change validator.
  changes = cc.get_changes()
  paths = changes.keys()
  paths.sort(lambda a, b: core.svn_path_compare_paths(a, b))
  for path in paths:
    change = changes[path]
    retval = test_path_change(path, change)
    if retval:
      return retval
    
  return 0
Ejemplo n.º 3
0
def inner(pool, path, rev):
    repos_ptr = repos.svn_repos_open(path, pool)
    fs_ptr = repos.svn_repos_fs(repos_ptr)

    root = fs.revision_root(fs_ptr, rev, pool)
    base_rev = rev - 1

    # get all changes
    editor = repos.RevisionChangeCollector(fs_ptr, rev, pool)
    e_ptr, e_baton = delta.make_editor(editor, pool)
    repos.svn_repos_replay(root, e_ptr, e_baton, pool)

    changelist = editor.changes.items()
    changelist.sort()

    base_root = fs.revision_root(fs_ptr, base_rev, pool)

    l = []
    for filepath, change in changelist:
        d = {'path': filepath, 'info': ''}
        if change.path:
            if change.added:
                d['action'] = 'new'
            else:
                d['action'] = 'modify'
                differ = fs.FileDiff(base_root, change.path, root, filepath,
                    pool, '-L \t(original) -L \t(new) -u'.split(' '))
                d['info'] = differ.get_pipe().read()
        else:
            d['action'] = 'delete'
        l.append(d)
    return l
Ejemplo n.º 4
0
        def _get_changed_paths(fsroot):
            """Return a 3-tuple: found_readable, found_unreadable, changed_paths."""
            editor = repos.ChangeCollector(self.fs_ptr, fsroot)
            e_ptr, e_baton = delta.make_editor(editor)
            repos.svn_repos_replay(fsroot, e_ptr, e_baton)
            changedpaths = {}
            changes = editor.get_changes()

            # Copy the Subversion changes into a new hash, checking
            # authorization and converting them into ChangedPath objects.
            found_readable = found_unreadable = 0
            for path in changes.keys():
                spath = _to_str(path)
                change = changes[path]
                if change.path:
                    change.path = _cleanup_path(change.path)
                if change.base_path:
                    change.base_path = _cleanup_path(change.base_path)
                is_copy = 0
                action = {
                    repos.CHANGE_ACTION_ADD: vclib.ADDED,
                    repos.CHANGE_ACTION_DELETE: vclib.DELETED,
                    repos.CHANGE_ACTION_REPLACE: vclib.REPLACED,
                }.get(change.action, vclib.MODIFIED)
                if ((action == vclib.ADDED or action == vclib.REPLACED)
                        and change.base_path and change.base_rev):
                    is_copy = 1
                pathtype = _kind2type(change.item_kind)
                parts = _path_parts(spath)
                if vclib.check_path_access(self, parts, pathtype, rev):
                    if is_copy and change.base_path and (change.base_path !=
                                                         path):
                        parts = _path_parts(_to_str(change.base_path))
                        if not vclib.check_path_access(self, parts, pathtype,
                                                       change.base_rev):
                            is_copy = 0
                            change.base_path = None
                            change.base_rev = None
                            found_unreadable = 1
                    if change.base_path:
                        base_path = _to_str(change.base_path)
                    else:
                        base_path = None
                    changedpaths[spath] = SVNChangedPath(
                        spath,
                        rev,
                        pathtype,
                        base_path,
                        change.base_rev,
                        action,
                        is_copy,
                        change.text_changed,
                        change.prop_changes,
                    )
                    found_readable = 1
                else:
                    found_unreadable = 1
            return found_readable, found_unreadable, list(
                changedpaths.values())
Ejemplo n.º 5
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)
Ejemplo n.º 6
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)
Ejemplo n.º 7
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
        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

        for change in changes:
            yield tuple(change)
Ejemplo n.º 8
0
def get_revision_info(svnrepos, rev):
    fsroot = svnrepos._getroot(rev)

    # Get the changes for the revision
    cps = ChangedPathSet()
    editor = repos.ChangeCollector(svnrepos.fs_ptr, fsroot, svnrepos.pool,
                                   cps.add_change)
    e_ptr, e_baton = delta.make_editor(editor, svnrepos.pool)
    repos.svn_repos_replay(fsroot, e_ptr, e_baton, svnrepos.pool)

    # Now get the revision property info.  Would use
    # editor.get_root_props(), but something is broken there...
    datestr, author, msg = _fs_rev_props(svnrepos.fs_ptr, rev, svnrepos.pool)
    date = _datestr_to_date(datestr, svnrepos.pool)

    return date, author, msg, cps.get_changes()
Ejemplo n.º 9
0
def get_revision_info(svnrepos, rev):
  fsroot = svnrepos._getroot(rev)

  # Get the changes for the revision
  cps = ChangedPathSet()
  editor = repos.ChangeCollector(svnrepos.fs_ptr, fsroot,
                                 svnrepos.pool, cps.add_change)
  e_ptr, e_baton = delta.make_editor(editor, svnrepos.pool)
  repos.svn_repos_replay(fsroot, e_ptr, e_baton, svnrepos.pool)

  # Now get the revision property info.  Would use
  # editor.get_root_props(), but something is broken there...
  datestr, author, msg = _fs_rev_props(svnrepos.fs_ptr, rev, svnrepos.pool)
  date = _datestr_to_date(datestr, svnrepos.pool)

  return date, author, msg, cps.get_changes()
Ejemplo n.º 10
0
Archivo: svn_fs.py Proyecto: t2y/trac
    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)
Ejemplo n.º 11
0
        def _get_changed_paths(fsroot):
            """Return a 3-tuple: found_readable, found_unreadable, changed_paths."""
            editor = repos.ChangeCollector(self.fs_ptr, fsroot)
            e_ptr, e_baton = delta.make_editor(editor)
            repos.svn_repos_replay(fsroot, e_ptr, e_baton)
            changedpaths = {}
            changes = editor.get_changes()

            # Copy the Subversion changes into a new hash, checking
            # authorization and converting them into ChangedPath objects.
            found_readable = found_unreadable = 0
            for path in changes.keys():
                change = changes[path]
                if change.path:
                    change.path = _cleanup_path(change.path)
                if change.base_path:
                    change.base_path = _cleanup_path(change.base_path)
                is_copy = 0
                if not hasattr(change, 'action'):  # new to subversion 1.4.0
                    action = vclib.MODIFIED
                    if not change.path:
                        action = vclib.DELETED
                    elif change.added:
                        action = vclib.ADDED
                        replace_check_path = path
                        if change.base_path and change.base_rev:
                            replace_check_path = change.base_path
                        if changedpaths.has_key(replace_check_path) \
                           and changedpaths[replace_check_path].action == vclib.DELETED:
                            action = vclib.REPLACED
                else:
                    if change.action == repos.CHANGE_ACTION_ADD:
                        action = vclib.ADDED
                    elif change.action == repos.CHANGE_ACTION_DELETE:
                        action = vclib.DELETED
                    elif change.action == repos.CHANGE_ACTION_REPLACE:
                        action = vclib.REPLACED
                    else:
                        action = vclib.MODIFIED
                if (action == vclib.ADDED or action == vclib.REPLACED) \
                   and change.base_path \
                   and change.base_rev:
                    is_copy = 1
                if change.item_kind == core.svn_node_dir:
                    pathtype = vclib.DIR
                elif change.item_kind == core.svn_node_file:
                    pathtype = vclib.FILE
                else:
                    pathtype = None

                parts = _path_parts(path)
                if vclib.check_path_access(self, parts, pathtype, rev):
                    if is_copy and change.base_path and (change.base_path !=
                                                         path):
                        parts = _path_parts(change.base_path)
                        if not vclib.check_path_access(self, parts, pathtype,
                                                       change.base_rev):
                            is_copy = 0
                            change.base_path = None
                            change.base_rev = None
                            found_unreadable = 1
                    changedpaths[path] = SVNChangedPath(
                        path, rev, pathtype, change.base_path, change.base_rev,
                        action, is_copy, change.text_changed,
                        change.prop_changes)
                    found_readable = 1
                else:
                    found_unreadable = 1
            return found_readable, found_unreadable, changedpaths.values()
Ejemplo n.º 12
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)
Ejemplo n.º 13
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)
Ejemplo n.º 14
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():
         if not (_is_path_within_scope(self.scope, path)):
             continue
         
         path = change.path
         base_path = change.base_path
         base_rev = change.base_rev
         
         if not (_is_path_within_scope(self.scope, base_path)):
             base_path, base_rev = None, -1
         
         if not path:
             if base_path:
                 if base_path in deletions:
                     continue
                 action = 'D'
                 deletions[base_path] = idx
             elif self.scope == '/':
                 action = 'E'
             else:
                 continue
         elif change.added or not base_path:
             action = 'A'
             if base_path and base_rev:
                 action = 'C'
                 copies[base_path] = idx
         else:
             action = 'E'
             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())
             
             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': path, 'kind': kind, 'action': action,
                         'base_path': base_path, 'base_rev': base_rev})
         idx += 1
     
     moves = []
     for k,v in copies.items():
         if k in deletions:
             changes[v]['action'] = 'M'
             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 change
Ejemplo n.º 15
0
def get_revision_info(svnrepos, rev):
  fsroot = svnrepos._getroot(rev)

  # Get the changes for the revision
  editor = repos.ChangeCollector(svnrepos.fs_ptr, fsroot, svnrepos.pool)
  e_ptr, e_baton = delta.make_editor(editor, svnrepos.pool)
  repos.svn_repos_replay(fsroot, e_ptr, e_baton, svnrepos.pool)
  changes = editor.get_changes()
  changedpaths = {}
  
  # Copy the Subversion changes into a new hash, converting them into
  # ChangedPath objects.
  for path in changes.keys():
    change = changes[path]
    if change.path:
      change.path = _cleanup_path(change.path)
    if change.base_path:
      change.base_path = _cleanup_path(change.base_path)
    is_copy = 0
    if not hasattr(change, 'action'): # new to subversion 1.4.0
      action = 'modified'
      if not change.path:
        action = 'deleted'
      elif change.added:
        action = 'added'
        replace_check_path = path
        if change.base_path and change.base_rev:
          replace_check_path = change.base_path
        if changedpaths.has_key(replace_check_path) \
           and changedpaths[replace_check_path].action == 'deleted':
          action = 'replaced'
    else:
      if change.action == repos.CHANGE_ACTION_ADD:
        action = 'added'
      elif change.action == repos.CHANGE_ACTION_DELETE:
        action = 'deleted'
      elif change.action == repos.CHANGE_ACTION_REPLACE:
        action = 'replaced'
      else:
        action = 'modified'
    if (action == 'added' or action == 'replaced') \
       and change.base_path \
       and change.base_rev:
      is_copy = 1
    if change.item_kind == core.svn_node_dir:
      pathtype = vclib.DIR
    elif change.item_kind == core.svn_node_file:
      pathtype = vclib.FILE
    else:
      pathtype = None
    changedpaths[path] = ChangedPath(path, pathtype, change.prop_changes,
                                     change.text_changed, change.base_path,
                                     change.base_rev, action, is_copy)

  # Actually, what we want is a sorted list of ChangedPath objects.
  change_items = changedpaths.values()
  change_items.sort(lambda a, b: _compare_paths(a.filename, b.filename))
  
  # Now get the revision property info.  Would use
  # editor.get_root_props(), but something is broken there...
  datestr, author, msg = _fs_rev_props(svnrepos.fs_ptr, rev, svnrepos.pool)
  date = _datestr_to_date(datestr, svnrepos.pool)

  return date, author, msg, change_items
Ejemplo n.º 16
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)
Ejemplo n.º 17
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 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_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)
Ejemplo n.º 18
0
   def _get_changed_paths(fsroot):
     """Return a 3-tuple: found_readable, found_unreadable, changed_paths."""
     editor = repos.ChangeCollector(self.fs_ptr, fsroot)
     e_ptr, e_baton = delta.make_editor(editor)
     repos.svn_repos_replay(fsroot, e_ptr, e_baton)
     changedpaths = {}
     changes = editor.get_changes()
   
     # Copy the Subversion changes into a new hash, checking
     # authorization and converting them into ChangedPath objects.
     found_readable = found_unreadable = 0
     for path in changes.keys():
       change = changes[path]
       if change.path:
         change.path = _cleanup_path(change.path)
       if change.base_path:
         change.base_path = _cleanup_path(change.base_path)
       is_copy = 0
       if not hasattr(change, 'action'): # new to subversion 1.4.0
         action = vclib.MODIFIED
         if not change.path:
           action = vclib.DELETED
         elif change.added:
           action = vclib.ADDED
           replace_check_path = path
           if change.base_path and change.base_rev:
             replace_check_path = change.base_path
           if changedpaths.has_key(replace_check_path) \
              and changedpaths[replace_check_path].action == vclib.DELETED:
             action = vclib.REPLACED
       else:
         if change.action == repos.CHANGE_ACTION_ADD:
           action = vclib.ADDED
         elif change.action == repos.CHANGE_ACTION_DELETE:
           action = vclib.DELETED
         elif change.action == repos.CHANGE_ACTION_REPLACE:
           action = vclib.REPLACED
         else:
           action = vclib.MODIFIED
       if (action == vclib.ADDED or action == vclib.REPLACED) \
          and change.base_path \
          and change.base_rev:
         is_copy = 1
       if change.item_kind == core.svn_node_dir:
         pathtype = vclib.DIR
       elif change.item_kind == core.svn_node_file:
         pathtype = vclib.FILE
       else:
         pathtype = None
 
       parts = _path_parts(path)
       if vclib.check_path_access(self, parts, pathtype, rev):
         if is_copy and change.base_path and (change.base_path != path):
           parts = _path_parts(change.base_path)
           if not vclib.check_path_access(self, parts, pathtype,
                                          change.base_rev):
             is_copy = 0
             change.base_path = None
             change.base_rev = None
             found_unreadable = 1
         changedpaths[path] = SVNChangedPath(path, rev, pathtype,
                                             change.base_path,
                                             change.base_rev, action,
                                             is_copy, change.text_changed,
                                             change.prop_changes)
         found_readable = 1
       else:
         found_unreadable = 1
     return found_readable, found_unreadable, changedpaths.values()