def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}): p1 = self._getpath(path_parts1) p2 = self._getpath(path_parts2) r1 = self._getrev(rev1) r2 = self._getrev(rev2) if not vclib.check_path_access(self, path_parts1, vclib.FILE, rev1): raise vclib.ItemNotFound(path_parts1) if not vclib.check_path_access(self, path_parts2, vclib.FILE, rev2): raise vclib.ItemNotFound(path_parts2) args = vclib._diff_args(type, options) def _date_from_rev(rev): date, author, msg, revprops, changes = self._revinfo(rev) return date try: temp1 = cat_to_tempfile(self, p1, r1) temp2 = cat_to_tempfile(self, p2, r2) info1 = p1, _date_from_rev(r1), r1 info2 = p2, _date_from_rev(r2), r2 return vclib._diff_fp(temp1, temp2, info1, info2, self.diff_cmd, args) except core.SubversionException, e: _fix_subversion_exception(e) if e.apr_err == vclib.svn.core.SVN_ERR_FS_NOT_FOUND: raise vclib.InvalidRevision raise
def _simple_auth_check(fsroot): """Return a 2-tuple: found_readable, found_unreadable.""" found_unreadable = found_readable = 0 if hasattr(fs, "paths_changed2"): changes = fs.paths_changed2(fsroot) else: changes = fs.paths_changed(fsroot) paths = list(changes.keys()) for path in paths: change = changes[path] pathtype = None if hasattr(change, "node_kind"): if change.node_kind == core.svn_node_file: pathtype = vclib.FILE elif change.node_kind == core.svn_node_dir: pathtype = vclib.DIR parts = _path_parts(path) if pathtype is None: # Figure out the pathtype so we can query the authz subsystem. if change.change_kind == fs.path_change_delete: # Deletions are annoying, because they might be underneath # copies (make their previous location non-trivial). prev_parts = parts prev_rev = rev - 1 parent_parts = parts[:-1] while parent_parts: parent_path = "/" + self._getpath(parent_parts) pchange = changes.get(parent_path) if not ( pchange and ( pchange.change_kind == fs.path_change_replace or pchange.change_kind == fs.path_change_add ) ): del parent_parts[-1] continue copyfrom_path, copyfrom_rev = _get_change_copyinfo( fsroot, parent_path, pchange ) if copyfrom_path: prev_rev = copyfrom_rev prev_parts = _path_parts(copyfrom_path) + parts[len(parent_parts) :] break del parent_parts[-1] pathtype = self._gettype(self._getpath(prev_parts), prev_rev) else: pathtype = self._gettype(self._getpath(parts), rev) if vclib.check_path_access(self, parts, pathtype, rev): found_readable = 1 copyfrom_path, copyfrom_rev = _get_change_copyinfo(fsroot, path, change) if copyfrom_path and copyfrom_path != path: parts = _path_parts(copyfrom_path) if not vclib.check_path_access(self, parts, pathtype, copyfrom_rev): found_unreadable = 1 else: found_unreadable = 1 if found_readable and found_unreadable: break return found_readable, found_unreadable
def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}): p1 = self._getpath(path_parts1) p2 = self._getpath(path_parts2) r1 = self._getrev(rev1) r2 = self._getrev(rev2) if not vclib.check_path_access(self, path_parts1, vclib.FILE, rev1): raise vclib.ItemNotFound(path_parts1) if not vclib.check_path_access(self, path_parts2, vclib.FILE, rev2): raise vclib.ItemNotFound(path_parts2) args = vclib._diff_args(type, options) def _date_from_rev(rev): date, author, msg, changes = self.revinfo(rev) return date try: temp1 = temp_checkout(self, p1, r1) temp2 = temp_checkout(self, p2, r2) info1 = p1, _date_from_rev(r1), r1 info2 = p2, _date_from_rev(r2), r2 return vclib._diff_fp(temp1, temp2, info1, info2, self.diff_cmd, args) except core.SubversionException, e: _fix_subversion_exception(e) if e.apr_err == vclib.svn.core.SVN_ERR_FS_NOT_FOUND: raise vclib.InvalidRevision raise
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 _simple_auth_check(fsroot): """Return a 2-tuple: found_readable, found_unreadable.""" found_unreadable = found_readable = 0 if hasattr(fs, 'paths_changed2'): changes = fs.paths_changed2(fsroot) else: changes = fs.paths_changed(fsroot) paths = changes.keys() for path in paths: change = changes[path] pathtype = None if hasattr(change, 'node_kind'): if change.node_kind == core.svn_node_file: pathtype = vclib.FILE elif change.node_kind == core.svn_node_dir: pathtype = vclib.DIR parts = _path_parts(path) if pathtype is None: # Figure out the pathtype so we can query the authz subsystem. if change.change_kind == fs.path_change_delete: # Deletions are annoying, because they might be underneath # copies (make their previous location non-trivial). prev_parts = parts prev_rev = rev - 1 parent_parts = parts[:-1] while parent_parts: parent_path = '/' + self._getpath(parent_parts) parent_change = changes.get(parent_path) if not (parent_change and \ (parent_change.change_kind == fs.path_change_add or parent_change.change_kind == fs.path_change_replace)): del(parent_parts[-1]) continue copyfrom_path, copyfrom_rev = \ _get_change_copyinfo(fsroot, parent_path, parent_change) if copyfrom_path: prev_rev = copyfrom_rev prev_parts = _path_parts(copyfrom_path) + \ parts[len(parent_parts):] break del(parent_parts[-1]) pathtype = self._gettype(self._getpath(prev_parts), prev_rev) else: pathtype = self._gettype(self._getpath(parts), rev) if vclib.check_path_access(self, parts, pathtype, rev): found_readable = 1 copyfrom_path, copyfrom_rev = \ _get_change_copyinfo(fsroot, path, change) if copyfrom_path and copyfrom_path != path: parts = _path_parts(copyfrom_path) if not vclib.check_path_access(self, parts, pathtype, copyfrom_rev): found_unreadable = 1 else: found_unreadable = 1 if found_readable and found_unreadable: break return found_readable, found_unreadable
def _log_cb(changed_paths, revision, author, datestr, message, pool, retval=revs): date = _datestr_to_date(datestr) action_map = { 'D' : vclib.DELETED, 'A' : vclib.ADDED, 'R' : vclib.REPLACED, 'M' : vclib.MODIFIED, } paths = (changed_paths or {}).keys() paths.sort(lambda a, b: _compare_paths(a, b)) changes = [] found_readable = found_unreadable = 0 for path in paths: pathtype = None change = changed_paths[path] action = action_map.get(change.action, vclib.MODIFIED) ### Wrong, diddily wrong wrong wrong. Can you say, ### "Manufacturing data left and right because it hurts to ### figure out the right stuff?" if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 ### Check authz rules (we lie about the path type) parts = _path_parts(path) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(base_path) if vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None changes.append(SVNChangedPath(path, revision, pathtype, base_path, base_rev, action, is_copy, 0, 0)) found_readable = 1 else: found_unreadable = 1 if found_unreadable: message = None if not found_readable: author = None date = None revs.append([date, author, message, changes])
def _get_dirents(self, path, rev): """Return a 2-type of dirents and locks, possibly reading/writing from a local cache of that information. This functions performs authz checks, stripping out unreadable dirents.""" dir_url = self._geturl(path) path_parts = _path_parts(path) if path: key = str(rev) + '/' + path else: key = str(rev) # Ensure that the cache gets filled... dirents_locks = self._dirent_cache.get(key) if not dirents_locks: tmp_dirents, locks = list_directory(dir_url, _rev2optrev(rev), _rev2optrev(rev), 0, self.ctx) dirents = {} for name, dirent in tmp_dirents.items(): dirent_parts = path_parts + [name] kind = dirent.kind if (kind == core.svn_node_dir or kind == core.svn_node_file) \ and vclib.check_path_access(self, dirent_parts, kind == core.svn_node_dir \ and vclib.DIR or vclib.FILE, rev): lh_rev, c_rev = self._get_last_history_rev(dirent_parts, rev) dirent.created_rev = lh_rev dirents[name] = dirent dirents_locks = [dirents, locks] self._dirent_cache[key] = dirents_locks # ...then return the goodies from the cache. return dirents_locks[0], dirents_locks[1]
def dirlogs(self, path_parts, rev, entries, options): """see vclib.Repository.dirlogs docstring rev can be a tag name or None. if set only information from revisions matching the tag will be retrieved Option values recognized by this implementation: cvs_subdirs boolean. true to fetch logs of the most recently modified file in each subdirectory Option values returned by this implementation: cvs_tags, cvs_branches lists of tag and branch names encountered in the directory """ if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % (_path_join(path_parts))) subdirs = options.get('cvs_subdirs', 0) entries_to_fetch = [] for entry in entries: if vclib.check_path_access(self, path_parts + [entry.name], None, rev): entries_to_fetch.append(entry) alltags = _get_logs(self, path_parts, entries_to_fetch, rev, subdirs) branches = options['cvs_branches'] = [] tags = options['cvs_tags'] = [] for name, rev in alltags.items(): if Tag(None, rev).is_branch: branches.append(name) else: tags.append(name)
def _get_history(self, path, rev, path_type, limit=0, options={}): if self.youngest == 0: return [] rev_paths = [] fsroot = self._getroot(rev) show_all_logs = options.get("svn_show_all_dir_logs", 0) if not show_all_logs: # See if the path is a file or directory. kind = fs.check_path(fsroot, path) if kind is core.svn_node_file: show_all_logs = 1 # Instantiate a NodeHistory collector object, and use it to collect # history items for PATH@REV. history = NodeHistory(self.fs_ptr, show_all_logs, limit) try: repos.svn_repos_history(self.fs_ptr, path, history.add_history, 1, rev, options.get("svn_cross_copies", 0)) except core.SubversionException as e: if e.apr_err != core.SVN_ERR_CEASE_INVOCATION: raise # Now, iterate over those history items, checking for changes of # location, pruning as necessitated by authz rules. for hist_rev, hist_path in history: hist_path = _to_str(hist_path) path_parts = _path_parts(hist_path) if not vclib.check_path_access(self, path_parts, path_type, hist_rev): break rev_paths.append([hist_rev, hist_path]) return rev_paths
def _get_dirents(self, path, rev): """Return a 2-type of dirents and locks, possibly reading/writing from a local cache of that information. This functions performs authz checks, stripping out unreadable dirents.""" dir_url = self._geturl(path) path_parts = _path_parts(path) if path: key = str(rev) + '/' + path else: key = str(rev) # Ensure that the cache gets filled... dirents_locks = self._dirent_cache.get(key) if not dirents_locks: tmp_dirents, locks = list_directory(dir_url, _rev2optrev(rev), _rev2optrev(rev), 0, self.ctx) dirents = {} for name, dirent in tmp_dirents.items(): dirent_parts = path_parts + [name] kind = dirent.kind if (kind == core.svn_node_dir or kind == core.svn_node_file) \ and vclib.check_path_access(self, dirent_parts, kind == core.svn_node_dir \ and vclib.DIR or vclib.FILE, rev): lh_rev, c_rev = self._get_last_history_rev( dirent_parts, rev) dirent.created_rev = lh_rev dirents[name] = dirent dirents_locks = [dirents, locks] self._dirent_cache[key] = dirents_locks # ...then return the goodies from the cache. return dirents_locks[0], dirents_locks[1]
def dirlogs(self, path_parts, rev, entries, options): """see vclib.Repository.dirlogs docstring rev can be a tag name or None. if set only information from revisions matching the tag will be retrieved Option values recognized by this implementation: cvs_subdirs boolean. true to fetch logs of the most recently modified file in each subdirectory Option values returned by this implementation: cvs_tags, cvs_branches lists of tag and branch names encountered in the directory """ if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % (part2path(path_parts))) entries_to_fetch = [] for entry in entries: if vclib.check_path_access(self, path_parts + [entry.name], None, rev): entries_to_fetch.append(entry) subdirs = options.get('cvs_subdirs', 0) dirpath = self._getpath(path_parts) alltags = { # all the tags seen in the files of this dir 'MAIN': '', 'HEAD': '1.1' } for entry in entries_to_fetch: entry.rev = entry.date = entry.author = None entry.dead = entry.absent = entry.log = entry.lockinfo = None path = _log_path(entry, dirpath, subdirs) if path: entry.path = path try: rcsparse.parse( open(path, 'rb'), InfoSink(entry, rev, alltags, self.encoding)) except IOError as e: entry.errors.append("rcsparse error: %s" % e) except RuntimeError as e: entry.errors.append("rcsparse error: %s" % e) except rcsparse.RCSStopParser: pass branches = options['cvs_branches'] = [] tags = options['cvs_tags'] = [] for name, rev in alltags.items(): if Tag(None, rev).is_branch: branches.append(name) else: tags.append(name)
def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}): if path_parts1: p1 = self._getpath(path_parts1) r1 = self._getrev(rev1) if not vclib.check_path_access(self, path_parts1, vclib.FILE, rev1): raise vclib.ItemNotFound(path_parts1) else: p1 = None if path_parts2: p2 = self._getpath(path_parts2) r2 = self._getrev(rev2) if not vclib.check_path_access(self, path_parts2, vclib.FILE, rev2): raise vclib.ItemNotFound(path_parts2) else: if not p1: raise vclib.ItemNotFound(path_parts2) p2 = None args = vclib._diff_args(type, options) def _date_from_rev(rev): date, author, msg, revprops, changes = self._revinfo(rev) return date try: if p1: temp1 = temp_checkout(self, p1, r1) info1 = p1, _date_from_rev(r1), r1 else: temp1 = '/dev/null' info1 = '/dev/null', _date_from_rev(rev1), rev1 if p2: temp2 = temp_checkout(self, p2, r2) info2 = p2, _date_from_rev(r2), r2 else: temp2 = '/dev/null' info2 = '/dev/null', _date_from_rev(rev2), rev2 return vclib._diff_fp(temp1, temp2, info1, info2, self.diff_cmd, args) except core.SubversionException, e: _fix_subversion_exception(e) if e.apr_err == core.SVN_ERR_FS_NOT_FOUND: raise vclib.InvalidRevision if e.apr_err != _SVN_ERR_CEASE_INVOCATION: raise
def itemtype(self, path_parts, rev): rev = self._getrev(rev) basepath = self._getpath(path_parts) pathtype = self._gettype(basepath, rev) if pathtype is None: raise vclib.ItemNotFound(path_parts) if not vclib.check_path_access(self, path_parts, pathtype, rev): raise vclib.ItemNotFound(path_parts) return pathtype
def listdir(self, path_parts, rev, options): if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % (_path_join(path_parts))) # Only RCS files (*,v) and subdirs are returned. data = [] full_name = self._getpath(path_parts) for file in os.listdir(full_name): name = None kind, errors = _check_path(os.path.join(full_name, file)) if kind == vclib.FILE: if file[-2:] == ',v': name = file[:-2] elif kind == vclib.DIR: if file != 'Attic' and file != 'CVS': # CVS directory is for fileattr name = file else: name = file if not name: continue if vclib.check_path_access(self, path_parts + [name], kind, rev): data.append(CVSDirEntry(name, kind, errors, 0)) full_name = os.path.join(full_name, 'Attic') if os.path.isdir(full_name): for file in os.listdir(full_name): name = None kind, errors = _check_path(os.path.join(full_name, file)) if kind == vclib.FILE: if file[-2:] == ',v': name = file[:-2] elif kind != vclib.DIR: name = file if not name: continue if vclib.check_path_access(self, path_parts + [name], kind, rev): data.append(CVSDirEntry(name, kind, errors, 1)) return data
def listdir(self, path_parts, rev, options): if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % (_path_join(path_parts))) # Only RCS files (*,v) and subdirs are returned. data = [ ] full_name = self._getpath(path_parts) for file in os.listdir(full_name): name = None kind, errors = _check_path(os.path.join(full_name, file)) if kind == vclib.FILE: if file[-2:] == ',v': name = file[:-2] elif kind == vclib.DIR: if file != 'Attic' and file != 'CVS': # CVS directory is for fileattr name = file else: name = file if not name: continue if vclib.check_path_access(self, path_parts + [name], kind, rev): data.append(CVSDirEntry(name, kind, errors, 0)) full_name = os.path.join(full_name, 'Attic') if os.path.isdir(full_name): for file in os.listdir(full_name): name = None kind, errors = _check_path(os.path.join(full_name, file)) if kind == vclib.FILE: if file[-2:] == ',v': name = file[:-2] elif kind != vclib.DIR: name = file if not name: continue if vclib.check_path_access(self, path_parts + [name], kind, rev): data.append(CVSDirEntry(name, kind, errors, 1)) return data
def dirlogs(self, path_parts, rev, entries, options): """see vclib.Repository.dirlogs docstring rev can be a tag name or None. if set only information from revisions matching the tag will be retrieved Option values recognized by this implementation: cvs_subdirs boolean. true to fetch logs of the most recently modified file in each subdirectory Option values returned by this implementation: cvs_tags, cvs_branches lists of tag and branch names encountered in the directory """ if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % (part2path(path_parts))) entries_to_fetch = [] for entry in entries: if vclib.check_path_access(self, path_parts + [entry.name], None, rev): entries_to_fetch.append(entry) subdirs = options.get('cvs_subdirs', 0) dirpath = self._getpath(path_parts) alltags = { # all the tags seen in the files of this dir 'MAIN' : '', 'HEAD' : '1.1' } for entry in entries_to_fetch: entry.rev = entry.date = entry.author = None entry.dead = entry.absent = entry.log = entry.lockinfo = None path = _log_path(entry, dirpath, subdirs) if path: entry.path = path try: rcsparse.parse(open(path, 'rb'), InfoSink(entry, rev, alltags)) if self.guesser: entry.log = self.guesser.utf8(entry.log) except IOError, e: entry.errors.append("rcsparse error: %s" % e) except RuntimeError, e: entry.errors.append("rcsparse error: %s" % e) except rcsparse.RCSStopParser: pass
def listdir(self, path_parts, rev, options): path = self._getpath(path_parts) if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % path) rev = self._getrev(rev) fsroot = self._getroot(rev) dirents = fs.dir_entries(fsroot, path) entries = [] for entry in dirents.values(): kind = _kind2type(entry.kind) ent_path = _to_str(entry.name) if vclib.check_path_access(self, path_parts + [ent_path], kind, rev): entries.append(vclib.DirEntry(ent_path, kind)) return entries
def itemtype(self, path_parts, rev): basepath = self._getpath(path_parts) kind = None if os.path.isdir(basepath): kind = vclib.DIR elif os.path.isfile(basepath + ',v'): kind = vclib.FILE else: atticpath = self._getpath(self._atticpath(path_parts)) if os.path.isfile(atticpath + ',v'): kind = vclib.FILE if not kind: raise vclib.ItemNotFound(path_parts) if not vclib.check_path_access(self, path_parts, kind, rev): raise vclib.ItemNotFound(path_parts) return kind
def listdir(self, path_parts, rev, options): path = self._getpath(path_parts) if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % path) rev = self._getrev(rev) entries = [] dirents, locks = self._get_dirents(path, rev) for name in dirents.keys(): entry = dirents[name] if entry.kind == core.svn_node_dir: kind = vclib.DIR elif entry.kind == core.svn_node_file: kind = vclib.FILE if vclib.check_path_access(self, path_parts + [name], kind, rev): entries.append(vclib.DirEntry(name, kind)) return entries
def listdir(self, path_parts, rev, options): path = self._getpath(path_parts) if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % path) rev = self._getrev(rev) fsroot = self._getroot(rev) dirents = fs.dir_entries(fsroot, path) entries = [ ] for entry in dirents.values(): if entry.kind == core.svn_node_dir: kind = vclib.DIR elif entry.kind == core.svn_node_file: kind = vclib.FILE if vclib.check_path_access(self, path_parts + [entry.name], kind, rev): entries.append(vclib.DirEntry(entry.name, kind)) return entries
def listdir(self, path_parts, rev, options): path = self._getpath(path_parts) if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % path) rev = self._getrev(rev) entries = [ ] dirents, locks = self._get_dirents(path, rev) for name in dirents.keys(): entry = dirents[name] if entry.kind == core.svn_node_dir: kind = vclib.DIR elif entry.kind == core.svn_node_file: kind = vclib.FILE if vclib.check_path_access(self, path_parts + [name], kind, rev): entries.append(vclib.DirEntry(name, kind)) return entries
def get_location(self, path, rev, old_rev): try: results = ra.get_locations(self.ra_session, path, rev, [old_rev]) except core.SubversionException as e: if e.apr_err == core.SVN_ERR_FS_NOT_FOUND: raise vclib.ItemNotFound(path) raise try: old_path = results[old_rev] except KeyError: raise vclib.ItemNotFound(path) old_path = _cleanup_path(_to_str(old_path)) old_path_parts = _path_parts(old_path) # Check access (lying about path types) if not vclib.check_path_access(self, old_path_parts, vclib.FILE, old_rev): raise vclib.ItemNotFound(path) return old_path
def itemtype(self, path_parts, rev): pathtype = None if not len(path_parts): pathtype = vclib.DIR else: path = self._getpath(path_parts) rev = self._getrev(rev) try: kind = ra.svn_ra_check_path(self.ra_session, path, rev) pathtype = _kind2type(kind) except Exception: pass if pathtype is None: raise vclib.ItemNotFound(path_parts) if not vclib.check_path_access(self, path_parts, pathtype, rev): raise vclib.ItemNotFound(path_parts) return pathtype
def dirlogs(self, path_parts, rev, entries, options): path = self._getpath(path_parts) if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % path) rev = self._getrev(rev) dirents, locks = self._get_dirents(path, rev) for entry in entries: entry_path_parts = path_parts + [entry.name] if not vclib.check_path_access(self, entry_path_parts, entry.kind, rev): continue dirent = dirents[entry.name] entry.date, entry.author, entry.log, changes = \ self.revinfo(dirent.created_rev) entry.rev = str(dirent.created_rev) entry.size = dirent.size entry.lockinfo = None if locks.has_key(entry.name): entry.lockinfo = locks[entry.name].owner
def dirlogs(self, path_parts, rev, entries, options): path = self._getpath(path_parts) if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % path) rev = self._getrev(rev) dirents, locks = self._get_dirents(path, rev) for entry in entries: entry_path_parts = path_parts + [entry.name] if not vclib.check_path_access(self, entry_path_parts, entry.kind, rev): continue dirent = dirents[entry.name] entry.date, entry.author, entry.log, revprops, changes = \ self.revinfo(dirent.created_rev) entry.rev = str(dirent.created_rev) entry.size = dirent.size entry.lockinfo = None if locks.has_key(entry.name): entry.lockinfo = locks[entry.name].owner
def itemtype(self, path_parts, rev): pathtype = None if not len(path_parts): pathtype = vclib.DIR else: path = self._getpath(path_parts) rev = self._getrev(rev) try: kind = ra.svn_ra_check_path(self.ra_session, path, rev) if kind == core.svn_node_file: pathtype = vclib.FILE elif kind == core.svn_node_dir: pathtype = vclib.DIR except: pass if pathtype is None: raise vclib.ItemNotFound(path_parts) if not vclib.check_path_access(self, path_parts, pathtype, rev): raise vclib.ItemNotFound(path_parts) return pathtype
def dirlogs(self, path_parts, rev, entries, options): path = self._getpath(path_parts) if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check raise vclib.Error("Path '%s' is not a directory." % path) fsroot = self._getroot(self._getrev(rev)) rev = self._getrev(rev) for entry in entries: entry_path_parts = path_parts + [entry.name] if not vclib.check_path_access(self, entry_path_parts, entry.kind, rev): continue path = self._getpath(entry_path_parts) entry_rev = _get_last_history_rev(fsroot, path) date, author, msg, revprops, changes = self._revinfo(entry_rev) entry.rev = str(entry_rev) entry.date = date entry.author = author entry.log = msg if entry.kind == vclib.FILE: entry.size = fs.file_length(fsroot, path) lock = fs.get_lock(self.fs_ptr, path) entry.lockinfo = lock and lock.owner or None
def _log_cb(log_entry, pool, retval=revs): # If Subversion happens to call us more than once, we choose not # to care. if retval: return revision = log_entry.revision msg, author, date, revprops = _split_revprops(log_entry.revprops) action_map = { 'D': vclib.DELETED, 'A': vclib.ADDED, 'R': vclib.REPLACED, 'M': vclib.MODIFIED, } # Easy out: if we won't use the changed-path info, just return a # changes-less tuple. if not need_changes: return revs.append([date, author, msg, revprops, None]) # Subversion 1.5 and earlier didn't offer the 'changed_paths2' # hash, and in Subversion 1.6, it's offered but broken. try: changed_paths = log_entry.changed_paths2 paths = (changed_paths or {}).keys() except: changed_paths = log_entry.changed_paths paths = (changed_paths or {}).keys() paths.sort(lambda a, b: _compare_paths(a, b)) # If we get this far, our caller needs changed-paths, or we need # them for authz-related sanitization. changes = [] found_readable = found_unreadable = 0 for path in paths: change = changed_paths[path] # svn_log_changed_path_t (which we might get instead of the # svn_log_changed_path2_t we'd prefer) doesn't have the # 'node_kind' member. pathtype = None if hasattr(change, 'node_kind'): if change.node_kind == core.svn_node_dir: pathtype = vclib.DIR elif change.node_kind == core.svn_node_file: pathtype = vclib.FILE # svn_log_changed_path2_t only has the 'text_modified' and # 'props_modified' bits in Subversion 1.7 and beyond. And # svn_log_changed_path_t is without. text_modified = props_modified = 0 if hasattr(change, 'text_modified'): if change.text_modified == core.svn_tristate_true: text_modified = 1 if hasattr(change, 'props_modified'): if change.props_modified == core.svn_tristate_true: props_modified = 1 # Wrong, diddily wrong wrong wrong. Can you say, # "Manufacturing data left and right because it hurts to # figure out the right stuff?" action = action_map.get(change.action, vclib.MODIFIED) if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 # Check authz rules (sadly, we have to lie about the path type) parts = _path_parts(path) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(base_path) if not vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None found_unreadable = 1 changes.append( SVNChangedPath(path, revision, pathtype, base_path, base_rev, action, is_copy, text_modified, props_modified)) found_readable = 1 else: found_unreadable = 1 # If our caller doesn't want changed-path stuff, and we have # the info we need to make an authz determination already, # quit this loop and get on with it. if (not include_changed_paths ) and found_unreadable and found_readable: break # Filter unreadable information. if found_unreadable: msg = None if not found_readable: author = None date = None # Drop unrequested changes. if not include_changed_paths: changes = None # Add this revision information to the "return" array. retval.append([date, author, msg, revprops, changes])
def _log_cb(log_entry, pool, retval=revs): ### Subversion 1.5 and earlier didn't offer the 'changed_paths2' ### hash, and in Subversion 1.6, it's offered but broken. try: changed_paths = log_entry.changed_paths2 paths = (changed_paths or {}).keys() except: changed_paths = log_entry.changed_paths paths = (changed_paths or {}).keys() paths.sort(lambda a, b: _compare_paths(a, b)) revision = log_entry.revision msg, author, date, revprops = _split_revprops(log_entry.revprops) action_map = { 'D': vclib.DELETED, 'A': vclib.ADDED, 'R': vclib.REPLACED, 'M': vclib.MODIFIED, } changes = [] found_readable = found_unreadable = 0 for path in paths: change = changed_paths[path] ### svn_log_changed_path_t (which we might get instead of the ### svn_log_changed_path2_t we'd prefer) doesn't have the ### 'node_kind' member. pathtype = None if hasattr(change, 'node_kind'): if change.node_kind == core.svn_node_dir: pathtype = vclib.DIR elif change.node_kind == core.svn_node_file: pathtype = vclib.FILE ### svn_log_changed_path2_t only has the 'text_modified' and ### 'props_modified' bits in Subversion 1.7 and beyond. And ### svn_log_changed_path_t is without. text_modified = props_modified = 0 if hasattr(change, 'text_modified'): if change.text_modified == core.svn_tristate_true: text_modified = 1 if hasattr(change, 'props_modified'): if change.props_modified == core.svn_tristate_true: props_modified = 1 ### Wrong, diddily wrong wrong wrong. Can you say, ### "Manufacturing data left and right because it hurts to ### figure out the right stuff?" action = action_map.get(change.action, vclib.MODIFIED) if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 ### Check authz rules (we lie about the path type) parts = _path_parts(path) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(base_path) if vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None changes.append( SVNChangedPath(path, revision, pathtype, base_path, base_rev, action, is_copy, text_modified, props_modified)) found_readable = 1 else: found_unreadable = 1 if found_unreadable: msg = None if not found_readable: author = None date = None revs.append([date, author, msg, revprops, changes])
def _access_checker(check_path, check_rev): return vclib.check_path_access(self, _path_parts(check_path), path_type, check_rev)
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_location(self, path, rev, old_rev): try: results = ra.get_locations(self.ra_session, path, rev, [old_rev]) except core.SubversionException, e: _fix_subversion_exception(e) if e.apr_err == core.SVN_ERR_FS_NOT_FOUND: raise vclib.ItemNotFound(path) raise try: old_path = results[old_rev] except KeyError: raise vclib.ItemNotFound(path) old_path = _cleanup_path(old_path) old_path_parts = _path_parts(old_path) # Check access (lying about path types) if not vclib.check_path_access(self, old_path_parts, vclib.FILE, old_rev): raise vclib.ItemNotFound(path) return old_path def created_rev(self, path, rev): lh_rev, c_rev = self._get_last_history_rev(_path_parts(path), rev) return lh_rev def last_rev(self, path, peg_revision, limit_revision=None): """Given PATH, known to exist in PEG_REVISION, find the youngest revision older than, or equal to, LIMIT_REVISION in which path exists. Return that revision, and the path at which PATH exists in that revision.""" # Here's the plan, man. In the trivial case (where PEG_REVISION is # the same as LIMIT_REVISION), this is a no-brainer. If
def _log_cb(log_entry, pool, retval=revs): # If Subversion happens to call us more than once, we choose not # to care. if retval: return revision = log_entry.revision msg, author, date, revprops = _split_revprops(log_entry.revprops) action_map = { "D": vclib.DELETED, "A": vclib.ADDED, "R": vclib.REPLACED, "M": vclib.MODIFIED, } # Easy out: if we won't use the changed-path info, just return a # changes-less tuple. if not need_changes: return revs.append([date, author, msg, revprops, None]) # Subversion 1.5 and earlier didn't offer the 'changed_paths2' # hash, and in Subversion 1.6, it's offered but broken. try: changed_paths = log_entry.changed_paths2 paths = list((changed_paths or {}).keys()) except Exception: changed_paths = log_entry.changed_paths paths = list((changed_paths or {}).keys()) paths.sort(key=functools.cmp_to_key( lambda a, b: _compare_paths(_to_str(a), _to_str(b)))) # If we get this far, our caller needs changed-paths, or we need # them for authz-related sanitization. changes = [] found_readable = found_unreadable = 0 for path in paths: change = changed_paths[path] pathtype = _kind2type(change.node_kind) text_modified = (change.text_modified == core.svn_tristate_true and 1 or 0) props_modified = ( change.props_modified == core.svn_tristate_true and 1 or 0) # Wrong, diddily wrong wrong wrong. Can you say, # "Manufacturing data left and right because it hurts to # figure out the right stuff?" action = action_map.get(change.action, vclib.MODIFIED) if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 # Check authz rules (sadly, we have to lie about the path type) parts = _path_parts(_to_str(path)) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(_to_str(base_path)) if not vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None found_unreadable = 1 changes.append( SVNChangedPath( _to_str(path), revision, pathtype, _to_str(base_path), base_rev, action, is_copy, text_modified, props_modified, )) found_readable = 1 else: found_unreadable = 1 # If our caller doesn't want changed-path stuff, and we have # the info we need to make an authz determination already, # quit this loop and get on with it. if (not include_changed_paths ) and found_unreadable and found_readable: break # Filter unreadable information. if found_unreadable: msg = None if not found_readable: author = None date = None # Drop unrequested changes. if not include_changed_paths: changes = None # Add this revision information to the "return" array. retval.append([date, author, msg, revprops, changes])
# Instantiate a NodeHistory collector object, and use it to collect # history items for PATH@REV. history = NodeHistory(self.fs_ptr, show_all_logs, limit) try: repos.svn_repos_history(self.fs_ptr, path, history.add_history, 1, rev, options.get('svn_cross_copies', 0)) except core.SubversionException, e: _fix_subversion_exception(e) if e.apr_err != _SVN_ERR_CEASE_INVOCATION: raise # Now, iterate over those history items, checking for changes of # location, pruning as necessitated by authz rules. for hist_rev, hist_path in history: path_parts = _path_parts(hist_path) if not vclib.check_path_access(self, path_parts, path_type, hist_rev): break rev_paths.append([hist_rev, hist_path]) return rev_paths def _getpath(self, path_parts): return '/'.join(path_parts) def _getrev(self, rev): if rev is None or rev == 'HEAD': return self.youngest try: if type(rev) == type(''): while rev[0] == 'r': rev = rev[1:] rev = int(rev)
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 _log_cb(log_entry, pool, retval=revs): # If Subversion happens to call us more than once, we choose not # to care. if retval: return revision = log_entry.revision msg, author, date, revprops = _split_revprops(log_entry.revprops) action_map = { 'D' : vclib.DELETED, 'A' : vclib.ADDED, 'R' : vclib.REPLACED, 'M' : vclib.MODIFIED, } # Easy out: if we won't use the changed-path info, just return a # changes-less tuple. if not need_changes: return revs.append([date, author, msg, revprops, None]) # Subversion 1.5 and earlier didn't offer the 'changed_paths2' # hash, and in Subversion 1.6, it's offered but broken. try: changed_paths = log_entry.changed_paths2 paths = (changed_paths or {}).keys() except: changed_paths = log_entry.changed_paths paths = (changed_paths or {}).keys() paths.sort(lambda a, b: _compare_paths(a, b)) # If we get this far, our caller needs changed-paths, or we need # them for authz-related sanitization. changes = [] found_readable = found_unreadable = 0 for path in paths: change = changed_paths[path] # svn_log_changed_path_t (which we might get instead of the # svn_log_changed_path2_t we'd prefer) doesn't have the # 'node_kind' member. pathtype = None if hasattr(change, 'node_kind'): if change.node_kind == core.svn_node_dir: pathtype = vclib.DIR elif change.node_kind == core.svn_node_file: pathtype = vclib.FILE # svn_log_changed_path2_t only has the 'text_modified' and # 'props_modified' bits in Subversion 1.7 and beyond. And # svn_log_changed_path_t is without. text_modified = props_modified = 0 if hasattr(change, 'text_modified'): if change.text_modified == core.svn_tristate_true: text_modified = 1 if hasattr(change, 'props_modified'): if change.props_modified == core.svn_tristate_true: props_modified = 1 # Wrong, diddily wrong wrong wrong. Can you say, # "Manufacturing data left and right because it hurts to # figure out the right stuff?" action = action_map.get(change.action, vclib.MODIFIED) if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 # Check authz rules (sadly, we have to lie about the path type) parts = _path_parts(path) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(base_path) if not vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None found_unreadable = 1 changes.append(SVNChangedPath(path, revision, pathtype, base_path, base_rev, action, is_copy, text_modified, props_modified)) found_readable = 1 else: found_unreadable = 1 # If our caller doesn't want changed-path stuff, and we have # the info we need to make an authz determination already, # quit this loop and get on with it. if (not include_changed_paths) and found_unreadable and found_readable: break # Filter unreadable information. if found_unreadable: msg = None if not found_readable: author = None date = None # Drop unrequested changes. if not include_changed_paths: changes = None # Add this revision information to the "return" array. retval.append([date, author, msg, revprops, changes])
def itemlog(self, path_parts, rev, sortby, first, limit, options): """see vclib.Repository.itemlog docstring Option values recognized by this implementation svn_show_all_dir_logs boolean, default false. if set for a directory path, will include revisions where files underneath the directory have changed svn_cross_copies boolean, default false. if set for a path created by a copy, will include revisions from before the copy svn_latest_log boolean, default false. if set will return only newest single log entry """ assert sortby == vclib.SORTBY_DEFAULT or sortby == vclib.SORTBY_REV path = self._getpath(path_parts) path_type = self.itemtype(path_parts, rev) # does auth-check rev = self._getrev(rev) revs = [] lockinfo = None # See if this path is locked. try: lock = fs.get_lock(self.fs_ptr, path) if lock: lockinfo = _to_str(lock.owner) except NameError: pass # If our caller only wants the latest log, we'll invoke # _log_helper for just the one revision. Otherwise, we go off # into history-fetching mode. ### TODO: we could stand to have a # 'limit' parameter here as numeric cut-off for the depth of our # history search. if options.get("svn_latest_log", 0): revision = self._log_helper(path, rev, lockinfo) if revision: revision.prev = None revs.append(revision) else: history = self._get_history(path, rev, path_type, first + limit, options) if len(history) < first: history = [] if limit: history = history[first:(first + limit)] for hist_rev, hist_path in history: revision = self._log_helper(hist_path, hist_rev, lockinfo) if revision: # If we have unreadable copyfrom data, obscure it. if revision.copy_path is not None: cp_parts = _path_parts(revision.copy_path) if not vclib.check_path_access( self, cp_parts, path_type, revision.copy_rev): revision.copy_path = revision.copy_rev = None revision.prev = None if len(revs): revs[-1].prev = revision revs.append(revision) return revs
def _log_cb(log_entry, pool, retval=revs): ### Subversion 1.5 and earlier didn't offer the 'changed_paths2' ### hash, and in Subversion 1.6, it's offered but broken. try: changed_paths = log_entry.changed_paths2 paths = (changed_paths or {}).keys() except: changed_paths = log_entry.changed_paths paths = (changed_paths or {}).keys() paths.sort(lambda a, b: _compare_paths(a, b)) revision = log_entry.revision msg, author, date, revprops = _split_revprops(log_entry.revprops) action_map = { 'D' : vclib.DELETED, 'A' : vclib.ADDED, 'R' : vclib.REPLACED, 'M' : vclib.MODIFIED, } changes = [] found_readable = found_unreadable = 0 for path in paths: change = changed_paths[path] ### svn_log_changed_path_t (which we might get instead of the ### svn_log_changed_path2_t we'd prefer) doesn't have the ### 'node_kind' member. pathtype = None if hasattr(change, 'node_kind'): if change.node_kind == core.svn_node_dir: pathtype = vclib.DIR elif change.node_kind == core.svn_node_file: pathtype = vclib.FILE ### svn_log_changed_path2_t only has the 'text_modified' and ### 'props_modified' bits in Subversion 1.7 and beyond. And ### svn_log_changed_path_t is without. text_modified = props_modified = 0 if hasattr(change, 'text_modified'): if change.text_modified == core.svn_tristate_true: text_modified = 1 if hasattr(change, 'props_modified'): if change.props_modified == core.svn_tristate_true: props_modified = 1 ### Wrong, diddily wrong wrong wrong. Can you say, ### "Manufacturing data left and right because it hurts to ### figure out the right stuff?" action = action_map.get(change.action, vclib.MODIFIED) if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 ### Check authz rules (we lie about the path type) parts = _path_parts(path) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(base_path) if vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None changes.append(SVNChangedPath(path, revision, pathtype, base_path, base_rev, action, is_copy, text_modified, props_modified)) found_readable = 1 else: found_unreadable = 1 if found_unreadable: msg = None if not found_readable: author = None date = None revs.append([date, author, msg, revprops, changes])
def itemlog(self, path_parts, rev, sortby, first, limit, options): """see vclib.Repository.itemlog docstring Option values recognized by this implementation svn_show_all_dir_logs boolean, default false. if set for a directory path, will include revisions where files underneath the directory have changed svn_cross_copies boolean, default false. if set for a path created by a copy, will include revisions from before the copy svn_latest_log boolean, default false. if set will return only newest single log entry """ assert sortby == vclib.SORTBY_DEFAULT or sortby == vclib.SORTBY_REV path = self._getpath(path_parts) path_type = self.itemtype(path_parts, rev) # does auth-check rev = self._getrev(rev) revs = [] lockinfo = None # See if this path is locked. try: lock = fs.get_lock(self.fs_ptr, path) if lock: lockinfo = lock.owner except NameError: pass # If our caller only wants the latest log, we'll invoke # _log_helper for just the one revision. Otherwise, we go off # into history-fetching mode. ### TODO: we could stand to have a # 'limit' parameter here as numeric cut-off for the depth of our # history search. if options.get('svn_latest_log', 0): revision = self._log_helper(path, rev, lockinfo) if revision: revision.prev = None revs.append(revision) else: history = self._get_history(path, rev, path_type, first + limit, options) if len(history) < first: history = [] if limit: history = history[first:first+limit] for hist_rev, hist_path in history: revision = self._log_helper(hist_path, hist_rev, lockinfo) if revision: # If we have unreadable copyfrom data, obscure it. if revision.copy_path is not None: cp_parts = _path_parts(revision.copy_path) if not vclib.check_path_access(self, cp_parts, path_type, revision.copy_rev): revision.copy_path = revision.copy_rev = None revision.prev = None if len(revs): revs[-1].prev = revision revs.append(revision) return revs