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
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
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())
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)
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)
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)
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()
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)
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()
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)
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)
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
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
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)
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)
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()