def do_ls(self, arg): """list the contents of the current directory or provided path""" parent = self.path if not len(arg): # no arg -- show a listing for the current directory. entries = fs.dir_entries(self.root, self.path) else: # arg? show a listing of that path. newpath = self._parse_path(arg) kind = fs.check_path(self.root, newpath) if kind == core.svn_node_dir: parent = newpath entries = fs.dir_entries(self.root, parent) elif kind == core.svn_node_file: parts = self._path_to_parts(newpath) name = parts.pop(-1) parent = self._parts_to_path(parts) print(parent + ':' + name) tmpentries = fs.dir_entries(self.root, parent) if not tmpentries.get(name, None): return entries = {} entries[name] = tmpentries[name] else: print("Path '%s' not found." % newpath) return keys = sorted(entries.keys()) print(" REV AUTHOR NODE-REV-ID SIZE DATE NAME") print( "----------------------------------------------------------------------------" ) for entry in keys: fullpath = parent + '/' + entry size = '' is_dir = fs.is_dir(self.root, fullpath) if is_dir: name = entry + '/' else: size = str(fs.file_length(self.root, fullpath)) name = entry node_id = fs.unparse_id(entries[entry].id) created_rev = fs.node_created_rev(self.root, fullpath) author = fs.revision_prop(self.fs_ptr, created_rev, core.SVN_PROP_REVISION_AUTHOR) if not author: author = "" date = fs.revision_prop(self.fs_ptr, created_rev, core.SVN_PROP_REVISION_DATE) if not date: date = "" else: date = self._format_date(date) print("%6s %8s %12s %8s %12s %s" % (created_rev, author[:8], node_id, size, date, name))
def do_ls(self, arg): """list the contents of the current directory or provided path""" parent = self.path if not len(arg): # no arg -- show a listing for the current directory. entries = fs.dir_entries(self.root, self.path) else: # arg? show a listing of that path. newpath = self._parse_path(arg) kind = fs.check_path(self.root, newpath) if kind == core.svn_node_dir: parent = newpath entries = fs.dir_entries(self.root, parent) elif kind == core.svn_node_file: parts = self._path_to_parts(newpath) name = parts.pop(-1) parent = self._parts_to_path(parts) print(parent + ':' + name) tmpentries = fs.dir_entries(self.root, parent) if not tmpentries.get(name, None): return entries = {} entries[name] = tmpentries[name] else: print("Path '%s' not found." % newpath) return keys = sorted(entries.keys()) print(" REV AUTHOR NODE-REV-ID SIZE DATE NAME") print("----------------------------------------------------------------------------") for entry in keys: fullpath = parent + '/' + entry size = '' is_dir = fs.is_dir(self.root, fullpath) if is_dir: name = entry + '/' else: size = str(fs.file_length(self.root, fullpath)) name = entry node_id = fs.unparse_id(entries[entry].id) created_rev = fs.node_created_rev(self.root, fullpath) author = fs.revision_prop(self.fs_ptr, created_rev, core.SVN_PROP_REVISION_AUTHOR) if not author: author = "" date = fs.revision_prop(self.fs_ptr, created_rev, core.SVN_PROP_REVISION_DATE) if not date: date = "" else: date = self._format_date(date) print("%6s %8s %12s %8s %12s %s" % (created_rev, author[:8], node_id, size, date, name))
def dump_tree(fsob, root, pool, path, indent=0): path = path + '/' entries = fs.dir_entries(root, path, pool) names = entries.keys() names.sort() subpool = _util.svn_pool_create(pool) for name in names: child = path + name line = ' '*indent + name id = fs.dirent_t_id_get(entries[name]) is_dir = fs.is_dir(root, child, subpool) if is_dir: print line + '/' dump_tree(fsob, root, subpool, child, indent+2) else: rev = fs.node_created_rev(root, child, subpool) author = fs.revision_prop(fsob, rev, 'svn:author', pool) print line, author, rev _util.svn_pool_clear(subpool) _util.svn_pool_destroy(subpool)
def children(self): if not self.isdir: return k = fs.dir_entries(self._revision._root, self.path).keys() k.sort() for i in k: yield SvnFile(self._revision, misc.join(self.path,i))
def get_entries(self): if self.isfile: return pool = Pool(self.pool) entries = fs.dir_entries(self.root, self._scoped_path_utf8, pool()) for item in entries.keys(): path = posixpath.join(self.path, _from_svn(item)) yield SubversionNode(path, self._requested_rev, self.repos, self.pool, self.root)
def get_entries(self): if self.isfile: return entries = fs.dir_entries(self.root, self.scoped_path) for item in entries.keys(): path = '/'.join((self.path, item)) if not self.authz.has_permission(path): continue yield SubversionNode(path, self._requested_rev, self.authz, self.scope, self.fs_ptr)
def get_entries(self): if self.isfile: return entries = fs.dir_entries(self.root, self.scoped_path) for item in entries: path = b'/'.join((self.path, item)) if not self.authz.has_permission(path): continue yield SubversionNode(path, self._requested_rev, self.authz, self.scope, self.fs_ptr)
def get_entries(self): if self.isfile: return pool = Pool(self.pool) entries = fs.dir_entries(self.root, self._scoped_path_utf8, pool()) for item in entries.keys(): path = posixpath.join(self.path, _from_svn(item)) if not self.authz.has_permission(posixpath.join(self.scope, path.strip("/"))): continue yield SubversionNode(path, self._requested_rev, self.repos, self.pool, self.root)
def get_entries(self): if self.isfile: return pool = Pool(self.pool) entries = fs.dir_entries(self.root, self._scoped_svn_path, pool()) for item in entries.keys(): path = posixpath.join(self.path, _from_svn(item)) if not self.authz.has_permission(path): continue yield SubversionNode(path, self._requested_rev, self.repos, self.pool)
def get_entries(self): """Yield `SubversionNode` corresponding to entries in this directory. (wraps ``fs.dir_entries``) """ if self.isfile: return pool = Pool(self.pool) entries = fs.dir_entries(self.root, self._scoped_path_utf8, pool()) for item in entries.keys(): path = posixpath.join(self.path, _from_svn(item)) yield SubversionNode(path, self.rev, self.repos, self.pool, self.root)
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 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 get_entries(self, path): # lots of conversions from and to utf-8 disk_url = directory(self.name).encode('utf-8') root_path_utf8 = repos.svn_repos_find_root_path(disk_url) if root_path_utf8 is None or not os.path.exists(root_path_utf8): if os.path.exists(disk_url): raise EncodingError(disk_url) raise DoesNotExistError(disk_url) try: repository = repos.svn_repos_open(root_path_utf8) except SubversionException as e: # check for messages like the following: # "Expected FS Format 'x'; found format 'y'" # there are different errorcodes for each version, so do a string # match instead of errorcode match errstr = str(e) if "Expected" in errstr and "format" in errstr and "found" in errstr: raise VersionError raise PermissionError fs_ptr = repos.svn_repos_fs(repository) path_utf8 = path youngest_revision_number = fs.youngest_rev(fs_ptr) try: root = fs.revision_root(fs_ptr, youngest_revision_number) except SubversionException as e: raise PermissionError entries = fs.dir_entries(root, path_utf8) # returns list of bytes-strings dirs = [] for entry in entries.keys(): entry_utf8 = entry.decode('utf-8') d = {} node_type = fs.check_path(root, os.path.join(path_utf8, entry_utf8)) if (node_type == core.svn_node_dir): d['kind'] = 'dir' elif (node_type == core.svn_node_file): d['kind'] = 'file' else: d['kind'] = 'unknown' d['name'] = entry_utf8 dirs.append(d) return dirs
def listdir(self, path_parts, rev, options): basepath = self._getpath(path_parts) if self.itemtype(path_parts, rev) != vclib.DIR: raise vclib.Error("Path '%s' is not a directory." % basepath) rev = self._getrev(rev) fsroot = self._getroot(rev) dirents = fs.dir_entries(fsroot, basepath, self.scratch_pool) 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 entries.append(vclib.DirEntry(entry.name, kind)) self._scratch_clear() return entries
def listdir(self, path_parts, rev, options): basepath = self._getpath(path_parts) if self.itemtype(path_parts, rev) != vclib.DIR: raise vclib.Error("Path '%s' is not a directory." % basepath) rev = self._getrev(rev) fsroot = self._getroot(rev) dirents = fs.dir_entries(fsroot, basepath, self.scratch_pool) 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 entries.append(vclib.DirEntry(entry.name, kind)) self._scratch_clear() return entries
def get_entries(self, path): # lots of conversions from and to utf-8 disk_url = directory(self.name) root_path_utf8 = repos.svn_repos_find_root_path(disk_url) if root_path_utf8 is None or not os.path.exists(root_path_utf8): raise DoesNotExistError(disk_url) try: repository = repos.svn_repos_open(root_path_utf8) except SubversionException as e: # check for messages like the following: # "Expected FS Format 'x'; found format 'y'" # there are different errorcodes for each version, so do a string # match instead of errorcode match errstr = str(e) if "Expected" in errstr and "format" in errstr and "found" in errstr: raise VersionError raise PermissionError fs_ptr = repos.svn_repos_fs(repository) path_utf8 = uc_to_svn(uc_str(path)) youngest_revision_number = fs.youngest_rev(fs_ptr) try: root = fs.revision_root(fs_ptr, youngest_revision_number) except SubversionException as e: raise PermissionError entries = fs.dir_entries(root, path_utf8) dirs = [] for entry in entries.keys(): d = {} node_type = fs.check_path(root, os.path.join(path_utf8, entry)) if (node_type == core.svn_node_dir): d['kind'] = 'dir' elif (node_type == core.svn_node_file): d['kind'] = 'file' else: d['kind'] = 'unknown' d['name'] = uc_from_svn(entry) dirs.append(d) return dirs
def _complete(self, text, line, begidx, endidx, limit_node_kind=None): """Generic tab completer. Takes the 4 standard parameters passed to a cmd.Cmd completer function, plus LIMIT_NODE_KIND, which should be a svn.core.svn_node_foo constant to restrict the returned completions to, or None for no limit. Catches and displays exceptions, because otherwise they are silently ignored - which is quite frustrating when debugging!""" try: args = line.split() if len(args) > 1: arg = args[1] else: arg = "" dirs = arg.split('/') user_elem = dirs[-1] user_dir = "/".join(dirs[:-1] + ['']) canon_dir = self._parse_path(user_dir) entries = fs.dir_entries(self.root, canon_dir) acceptable_completions = [] for name, dirent_t in entries.items(): if not name.startswith(user_elem): continue if limit_node_kind and dirent_t.kind != limit_node_kind: continue if dirent_t.kind == core.svn_node_dir: name += '/' acceptable_completions.append(name) if limit_node_kind == core.svn_node_dir or not limit_node_kind: if user_elem in ('.', '..'): for extraname in ('.', '..'): if extraname.startswith(user_elem): acceptable_completions.append(extraname + '/') return acceptable_completions except: ei = sys.exc_info() sys.stderr.write("EXCEPTION WHILST COMPLETING\n") import traceback traceback.print_tb(ei[2]) sys.stderr.write("%s: %s\n" % (ei[0], ei[1])) raise
def walk_tree(root, path): for name in fs.dir_entries(root, path).keys(): full = path + '/' + name print_props(root, full) if fs.is_dir(root, full): walk_tree(root, full)
def get_nodes(self): entries = fs.dir_entries(self.root, self.file_path) for file_path in entries.keys(): full_file_path = os.path.join(self.file_path, file_path) yield SubversionNode(self.path, full_file_path, self.rev)
def MakeRecordsFromPath(srcrepo, srcrev, srcpath, dstpath, record_source): """Generate Records adding the contents of a given repo/rev/path. Args: srcrepo: path to the source repository srcrev: revision number srcpath: path within the source repository dstpath: destination path in the repository being filtered record_source: the source attribute of the Records generated Returns: a list of Records Raises: RuntimeError: if svnrdump seems to have failed This is the fundamental feature of a working svndumpfilter replacement. In the upstream svndumpfilter, copyfrom operations that reference paths that are excluded by filtering cannot be resolved. To fix that, each svndumpfilter replacement must find a way to turn that copy operation into a series of add operations. svndumpfilter2 originally did this by calling the svnlook utility to list the directory structure, grab file contents, list property names, and grab property values. This resulted in calling svnlook once per tree, twice per file, and once per property. For a time, we tried instead making a single call to svnrdump which, unlike svnadmin dump (which is used by svndumpfilter3 with disastrous results for performance) can output a dump file containing only the desired subdirectory. The dump file is parsed into Records, the paths have the destination path prepended, and the Records are inserted into the dump. Unfortunately, svnrdump always produces format 3 dumps which use deltas. Even though it was only used for a single non-incremental revision, every file's contents were in the form of a delta. Since some tools (such as p4convert-svn) do not support deltas, svnrdump was done away with, replaced by the SVN SWIG bindings. It turns out that this same functionality is critical to 'internalizing' SVN externals. By generating Records that add all of the files and directories in the repo/rev/path referenced by an svn:external property, the history can be made to look as though the actual files had been there all along, not just a reference to them. Further filtering of these generated Records must be done in the case of externals to delete externals when they are removed and modify the filesystem when the revision is changed, rather than deleting and reading it every time (see externals.FromRev, externals.Diff, Diff). """ srcrepo = svn_core.svn_path_canonicalize(srcrepo) repo_ptr = svn_repos.open(srcrepo) fs = svn_repos.fs(repo_ptr) root = svn_fs.revision_root(fs, srcrev) output = [] # Perform a depth-first search stack = [srcpath] while stack: path = stack.pop() if srcpath: relative_path = path[len(srcpath):] node_path = dstpath + relative_path else: node_path = (dstpath + '/' + path) if path else dstpath if svn_fs.is_dir(root, path): record = Record(action='add', kind='dir', path=node_path, source=record_source) # Add children to the stack prefix = (path + '/') if path else '' for name in svn_fs.dir_entries(root, path).keys(): stack.append(prefix + name) else: record = Record(action='add', kind='file', path=node_path, source=record_source) # Fetch file content stream = svn_fs.file_contents(root, path) record.text = _ReadSVNStream(stream) checksum = svn_fs.file_md5_checksum(root, path) record.headers['Text-content-md5'] = checksum.encode('hex_codec') # Fetch properties props = svn_fs.node_proplist(root, path) record.props = {key: str(value) for key, value in props.iteritems()} output.append(record) return output
def ensure_names(path, names, txn_root): if (not names.has_key(path)): names[path] = [] for name, dirent in fs.dir_entries(txn_root, path).iteritems(): names[path].append([canonicalize(name), name])
def ensure_names(path, names, txn_root): if (path not in names): names[path] = [] for name, dirent in fs.dir_entries(txn_root, path).items(): name = name.decode('utf-8') names[path].append([canonicalize(name), name])