- 浏览: 36218 次
- 性别:
- 来自: 北京
文章分类
最新评论
#!/usr/bin/env python # # svnlook.py : a Python-based replacement for svnlook # ###################################################################### # Licensed to the Subversion Corporation (SVN Corp.) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The SVN Corp. licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ###################################################################### # import sys import time import os from svn import core, fs, delta, repos class SVNLook: def __init__(self, path, cmd, rev, txn): path = core.svn_path_canonicalize(path) repos_ptr = repos.open(path) self.fs_ptr = repos.fs(repos_ptr) if txn: self.txn_ptr = fs.open_txn(self.fs_ptr, txn) else: self.txn_ptr = None if rev is None: rev = fs.youngest_rev(self.fs_ptr) self.rev = rev getattr(self, 'cmd_' + cmd)() def cmd_default(self): self.cmd_info() self.cmd_tree() def cmd_author(self): # get the author property, or empty string if the property is not present author = self._get_property(core.SVN_PROP_REVISION_AUTHOR) or '' print(author) def cmd_changed(self): self._print_tree(ChangedEditor, pass_root=1) def cmd_date(self): if self.txn_ptr: print("") else: date = self._get_property(core.SVN_PROP_REVISION_DATE) if date: aprtime = core.svn_time_from_cstring(date) # ### convert to a time_t; this requires intimate knowledge of # ### the apr_time_t type secs = aprtime / 1000000 # aprtime is microseconds; make seconds # assume secs in local TZ, convert to tuple, and format ### we don't really know the TZ, do we? print(time.strftime('%Y-%m-%d %H:%M', time.localtime(secs))) else: print("") def cmd_diff(self): self._print_tree(DiffEditor, pass_root=1) def cmd_dirs_changed(self): self._print_tree(DirsChangedEditor) def cmd_ids(self): self._print_tree(Editor, base_rev=0, pass_root=1) def cmd_info(self): self.cmd_author() self.cmd_date() self.cmd_log(1) def cmd_log(self, print_size=0): # get the log property, or empty string if the property is not present log = self._get_property(core.SVN_PROP_REVISION_LOG) or '' if print_size: print(len(log)) print(log) def cmd_tree(self): self._print_tree(Editor, base_rev=0) def _get_property(self, name): if self.txn_ptr: return fs.txn_prop(self.txn_ptr, name) return fs.revision_prop(self.fs_ptr, self.rev, name) def _print_tree(self, e_factory, base_rev=None, pass_root=0): if base_rev is None: # a specific base rev was not provided. use the transaction base, # or the previous revision if self.txn_ptr: base_rev = fs.txn_base_revision(self.txn_ptr) else: base_rev = self.rev - 1 # get the current root if self.txn_ptr: root = fs.txn_root(self.txn_ptr) else: root = fs.revision_root(self.fs_ptr, self.rev) # the base of the comparison base_root = fs.revision_root(self.fs_ptr, base_rev) if pass_root: editor = e_factory(root, base_root) else: editor = e_factory() # construct the editor for printing these things out e_ptr, e_baton = delta.make_editor(editor) # compute the delta, printing as we go def authz_cb(root, path, pool): return 1 repos.dir_delta(base_root, '', '', root, '', e_ptr, e_baton, authz_cb, 0, 1, 0, 0) class Editor(delta.Editor): def __init__(self, root=None, base_root=None): self.root = root # base_root ignored self.indent = '' def open_root(self, base_revision, dir_pool): print('/' + self._get_id('/')) self.indent = self.indent + ' ' # indent one space def add_directory(self, path, *args): id = self._get_id(path) print(self.indent + _basename(path) + '/' + id) self.indent = self.indent + ' ' # indent one space # we cheat. one method implementation for two entry points. open_directory = add_directory def close_directory(self, baton): # note: if indents are being performed, this slice just returns # another empty string. self.indent = self.indent[:-1] def add_file(self, path, *args): id = self._get_id(path) print(self.indent + _basename(path) + id) # we cheat. one method implementation for two entry points. open_file = add_file def _get_id(self, path): if self.root: id = fs.node_id(self.root, path) return ' <%s>' % fs.unparse_id(id) return '' class DirsChangedEditor(delta.Editor): def open_root(self, base_revision, dir_pool): return [ 1, '' ] def delete_entry(self, path, revision, parent_baton, pool): self._dir_changed(parent_baton) def add_directory(self, path, parent_baton, copyfrom_path, copyfrom_revision, dir_pool): self._dir_changed(parent_baton) return [ 1, path ] def open_directory(self, path, parent_baton, base_revision, dir_pool): return [ 1, path ] def change_dir_prop(self, dir_baton, name, value, pool): self._dir_changed(dir_baton) def add_file(self, path, parent_baton, copyfrom_path, copyfrom_revision, file_pool): self._dir_changed(parent_baton) def open_file(self, path, parent_baton, base_revision, file_pool): # some kind of change is going to happen self._dir_changed(parent_baton) def _dir_changed(self, baton): if baton[0]: # the directory hasn't been printed yet. do it. print(baton[1] + '/') baton[0] = 0 class ChangedEditor(delta.Editor): def __init__(self, root, base_root): self.root = root self.base_root = base_root def open_root(self, base_revision, dir_pool): return [ 1, '' ] def delete_entry(self, path, revision, parent_baton, pool): ### need more logic to detect 'replace' if fs.is_dir(self.base_root, '/' + path): print('D ' + path + '/') else: print('D ' + path) def add_directory(self, path, parent_baton, copyfrom_path, copyfrom_revision, dir_pool): print('A ' + path + '/') return [ 0, path ] def open_directory(self, path, parent_baton, base_revision, dir_pool): return [ 1, path ] def change_dir_prop(self, dir_baton, name, value, pool): if dir_baton[0]: # the directory hasn't been printed yet. do it. print('_U ' + dir_baton[1] + '/') dir_baton[0] = 0 def add_file(self, path, parent_baton, copyfrom_path, copyfrom_revision, file_pool): print('A ' + path) return [ '_', ' ', None ] def open_file(self, path, parent_baton, base_revision, file_pool): return [ '_', ' ', path ] def apply_textdelta(self, file_baton, base_checksum): file_baton[0] = 'U' # no handler return None def change_file_prop(self, file_baton, name, value, pool): file_baton[1] = 'U' def close_file(self, file_baton, text_checksum): text_mod, prop_mod, path = file_baton # test the path. it will be None if we added this file. if path: status = text_mod + prop_mod # was there some kind of change? if status != '_ ': print(status + ' ' + path) class DiffEditor(delta.Editor): def __init__(self, root, base_root): self.root = root self.base_root = base_root self.target_revision = 0 def _do_diff(self, base_path, path): if base_path is None: print("Added: " + path) label = path elif path is None: print("Removed: " + base_path) label = base_path else: print("Modified: " + path) label = path print("===============================================================" + \ "===============") args = [] args.append("-L") args.append(label + "\t(original)") args.append("-L") args.append(label + "\t(new)") args.append("-u") differ = fs.FileDiff(self.base_root, base_path, self.root, path, diffoptions=args) pobj = differ.get_pipe() while True: line = pobj.readline() if not line: break sys.stdout.write("%s " % line) print("") def _do_prop_diff(self, path, prop_name, prop_val, pool): print("Property changes on: " + path) print("_______________________________________________________________" + \ "_______________") old_prop_val = None try: old_prop_val = fs.node_prop(self.base_root, path, prop_name, pool) except core.SubversionException: pass # Must be a new path if old_prop_val: if prop_val: print("Modified: " + prop_name) print(" - " + str(old_prop_val)) print(" + " + str(prop_val)) else: print("Deleted: " + prop_name) print(" - " + str(old_prop_val)) else: print("Added: " + prop_name) print(" + " + str(prop_val)) print("") def delete_entry(self, path, revision, parent_baton, pool): ### need more logic to detect 'replace' if not fs.is_dir(self.base_root, '/' + path): self._do_diff(path, None) def add_directory(self, path, parent_baton, copyfrom_path, copyfrom_revision, dir_pool): return [ 1, path ] def add_file(self, path, parent_baton, copyfrom_path, copyfrom_revision, file_pool): self._do_diff(None, path) return [ '_', ' ', None ] def open_root(self, base_revision, dir_pool): return [ 1, '' ] def open_directory(self, path, parent_baton, base_revision, dir_pool): return [ 1, path ] def open_file(self, path, parent_baton, base_revision, file_pool): return [ '_', ' ', path ] def apply_textdelta(self, file_baton, base_checksum): if file_baton[2] is not None: self._do_diff(file_baton[2], file_baton[2]) return None def change_file_prop(self, file_baton, name, value, pool): if file_baton[2] is not None: self._do_prop_diff(file_baton[2], name, value, pool) return None def change_dir_prop(self, dir_baton, name, value, pool): if dir_baton[1] is not None: self._do_prop_diff(dir_baton[1], name, value, pool) return None def set_target_revision(self, target_revision): self.target_revision = target_revision def _basename(path): "Return the basename for a '/'-separated path." idx = path.rfind('/') if idx == -1: return path return path[idx+1:] def usage(exit): if exit: output = sys.stderr else: output = sys.stdout output.write( "usage: %s REPOS_PATH rev REV [COMMAND] - inspect revision REV\n" " %s REPOS_PATH txn TXN [COMMAND] - inspect transaction TXN\n" " %s REPOS_PATH [COMMAND] - inspect the youngest revision\n" "\n" "REV is a revision number > 0.\n" "TXN is a transaction name.\n" "\n" "If no command is given, the default output (which is the same as\n" "running the subcommands `info' then `tree') will be printed.\n" "\n" "COMMAND can be one of: \n" "\n" " author: print author.\n" " changed: print full change summary: all dirs & files changed.\n" " date: print the timestamp (revisions only).\n" " diff: print GNU-style diffs of changed files and props.\n" " dirs-changed: print changed directories.\n" " ids: print the tree, with nodes ids.\n" " info: print the author, data, log_size, and log message.\n" " log: print log message.\n" " tree: print the tree.\n" "\n" % (sys.argv[0], sys.argv[0], sys.argv[0])) sys.exit(exit) def main(): if len(sys.argv) < 2: usage(1) rev = txn = None args = sys.argv[2:] if args: cmd = args[0] if cmd == 'rev': if len(args) == 1: usage(1) try: rev = int(args[1]) except ValueError: usage(1) del args[:2] elif cmd == 'txn': if len(args) == 1: usage(1) txn = args[1] del args[:2] if args: if len(args) > 1: usage(1) cmd = args[0].replace('-', '_') else: cmd = 'default' if not hasattr(SVNLook, 'cmd_' + cmd): usage(1) SVNLook(sys.argv[1], cmd, rev, txn) if __name__ == '__main__': main()
发表评论
-
Python的ASCII, GB2312, Unicode , UTF-8
2009-02-16 19:27 1189ASCII 是一种字符集,包括大小写的英文字母、数字、控制字符 ... -
django项目添加了fckeditor
2009-02-12 21:27 1728fckeditor默认的 connector.py 不能用于d ... -
dango + aparche + mod_python方式配置文件
2009-02-03 20:26 1015[size=medium]<VirtualHost *& ... -
读取lumaQQ的ip数据文件
2008-07-20 22:15 852根据网上搜索的资料,稍做改动。 from struct im ...
相关推荐
A drop-in replacement for UICollectionViewFlowLayout.zip,A drop-in replacement for UICollectionViewFlowLayout
5. 基于时间的替换(Time-based Replacement):根据数据的过期时间进行替换。 在VB6中实现高速缓存调度算法,需要考虑如何将这些理论应用到实际编程中。VB6提供了丰富的控件和API接口,可以方便地处理数据读写和...
在Python的Web开发领域,Flask是一个轻量级且灵活的框架,而Webpack则是一个流行的JavaScript模块打包工具,常用于前端资源的管理和优化。将两者结合可以创建一个高效的开发环境,便于构建现代化的Web应用程序。在这...
资源分类:Python库 所属语言:Python 资源全名:replacement-0.3.0.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
### PADRe:多项式注意力置换概述 #### 一、引言与背景 随着深度学习技术的发展,Transformer模型在自然语言处理、计算机视觉以及语音识别等多个领域取得了显著成果。特别是在计算机视觉领域,Vision Transformer ...
is designed to be a drop-in replacement for users used to building Zaptel 1.2 or 1.4 for their system without specifying any special build options, file locations, or anything else. If you need to ...
。 。 。 (进行检查:来自400多个测试用例的代码覆盖率达到93%)docker systemctl更换该脚本可用于覆盖“ / usr / bin / systemctl”。 它将在没有SystemD的情况下执行systemctl命令! 这用于测试以Docker容器为...
MariaDB is a drop-in replacement for MySQL. MariaDB strives to be the logical choice for database professionals looking for a robust, scalable, and reliable SQL server. To accomplish this, Monty ...
"Atom-atom-replacement-icon.zip"这个压缩包显然包含了针对Atom编辑器的自定义图标资源。在编程环境中,图标是一个重要的视觉元素,它们可以帮助用户快速识别和理解各种功能。"Atom文本编辑器的替换图标"可能是指...
SDAC, a high-performance and feature-rich SQL Server connectivity solution, is a complete replacement for standard SQL Server connectivity solutions and presents an efficient native alternative to the...
### 数字隔离器的演进推动光耦合器替换 #### 引言 自20世纪60年代末以来,光耦合器(Optocoupler)作为一种隔离技术,在多种应用领域内得到了广泛的应用。然而,由于其固有的技术限制与不足之处,设计师们常常需要...
资源分类:Python库 所属语言:Python 资源全名:oc_replacement-0.3.0-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
Swift 重新实现的 JSQMessagesViewController.zip,A community-driven replacement for JSQMessagesViewController
实现高斯模糊的工具包,github开源项目https://github.com/android/renderscript-intrinsics-replacement-toolkit打包生成。
这个“Google Tag Manager - Quote replacement-crx”插件是专为GTM设计的一个扩展,其主要功能是在发布新标签时显示随机的引言。这个插件的目标用户主要是那些经常使用GTM来优化网站分析和营销策略的专业人士。 ...
在实际编程实现中,可以使用Python等语言,利用内置的数据结构如`dict`和`collections.deque`来简化操作。`deque`可以方便地实现对链表头尾的操作,而`dict`则可以快速查找页面。 在LRU页面置换的压缩包文件中,...