Python中如何实现在Web页面展示SVN diff的小程序
项目地址: https://github.com/owenliang/side-by-side-diff
在线体验: https://owenliang.github.io/side-by-side-diff/sample/side-by-side-view.html
测了一下,有些 svn 操作场景还是没有覆盖全,不过基本的 add/del/upd 文件都是可以的。
Python中如何实现在Web页面展示SVN diff的小程序
666 可以扩展到任意两种文本进行比对展示 diff 嘛
比如允许修改的论坛发帖 展示编辑版本
要做一个在网页上展示SVN diff的小工具,核心是调用svn diff命令获取差异内容,然后在前端用合适的格式展示。这里给你一个完整的Flask实现方案:
import subprocess
import os
from flask import Flask, render_template_string, request, jsonify
app = Flask(__name__)
def get_svn_diff(repo_path, revision1=None, revision2=None):
"""执行svn diff命令获取差异"""
cmd = ['svn', 'diff', repo_path]
if revision1 and revision2:
cmd.extend(['-r', f'{revision1}:{revision2}'])
elif revision1:
cmd.extend(['-r', revision1])
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
check=True
)
return result.stdout
except subprocess.CalledProcessError as e:
return f"Error executing svn diff: {e.stderr}"
def format_diff_for_html(diff_text):
"""将diff文本转换为HTML格式"""
if not diff_text:
return ""
lines = diff_text.split('\n')
html_lines = []
for line in lines:
if line.startswith('+'):
html_lines.append(f'<div class="added">{line}</div>')
elif line.startswith('-'):
html_lines.append(f'<div class="removed">{line}</div>')
elif line.startswith('@@'):
html_lines.append(f'<div class="chunk-header">{line}</div>')
else:
html_lines.append(f'<div>{line}</div>')
return '\n'.join(html_lines)
@app.route('/')
def index():
"""主页面"""
html_template = '''
<!DOCTYPE html>
<html>
<head>
<title>SVN Diff Viewer</title>
<style>
body { font-family: monospace; margin: 20px; }
.diff-container {
background: #f5f5f5;
padding: 15px;
border-radius: 5px;
white-space: pre-wrap;
font-size: 14px;
}
.added { background-color: #e6ffe6; color: #006600; }
.removed { background-color: #ffe6e6; color: #cc0000; }
.chunk-header { background-color: #e6f3ff; color: #0066cc; font-weight: bold; }
form { margin-bottom: 20px; }
input, button { padding: 8px; margin: 5px; }
</style>
</head>
<body>
<h1>SVN Diff Viewer</h1>
<form id="diffForm">
<input type="text" name="repo_path" placeholder="SVN仓库路径" required style="width: 300px;">
<input type="text" name="rev1" placeholder="起始版本号 (可选)">
<input type="text" name="rev2" placeholder="结束版本号 (可选)">
<button type="submit">查看差异</button>
</form>
<div id="result" class="diff-container"></div>
<script>
document.getElementById('diffForm').addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const params = new URLSearchParams(formData);
const response = await fetch('/get_diff?' + params.toString());
const data = await response.json();
document.getElementById('result').innerHTML = data.html_diff || data.error;
});
</script>
</body>
</html>
'''
return render_template_string(html_template)
@app.route('/get_diff')
def get_diff():
"""获取并格式化diff的API接口"""
repo_path = request.args.get('repo_path')
rev1 = request.args.get('rev1')
rev2 = request.args.get('rev2')
if not repo_path:
return jsonify({'error': '请提供SVN仓库路径'})
if not os.path.exists(repo_path):
return jsonify({'error': '指定的路径不存在'})
diff_text = get_svn_diff(repo_path, rev1, rev2)
html_diff = format_diff_for_html(diff_text)
return jsonify({'html_diff': html_diff})
if __name__ == '__main__':
app.run(debug=True)
这个方案的工作原理:
- 后端用Flask搭建,
get_svn_diff()函数调用系统命令获取原始diff format_diff_for_html()把diff文本转成带CSS样式的HTML- 前端用简单的表单提交路径和版本号,通过AJAX获取并展示差异
运行前需要安装Flask:pip install flask。使用时在浏览器打开http://localhost:5000,输入SVN仓库路径和版本号即可。
如果你需要更高级的功能,比如支持多个文件、语法高亮,可以考虑集成pygments库来美化代码显示。另外注意,这个例子假设SVN客户端已安装且可执行。
核心就是调用svn命令+前端格式化展示。
可以 命令行 diff -u 也可以,稍作适配就差不多。
功能不错~
页面调整了 css,横向拉伸可以实现自适应。
difflib 本来就有 HtmlDiff,make_table
思路来自于他,是为了得到一部分灵活性。
一般我们通过 svn diff 或者 git diff 就可以生成,或者通过 diff -u filename1 filename2 也可以生成。
diff 是什么明了了? cmd 上的 svn 命令?我刚用 cmd 试了一下 diff 不行,svn diff 可以
嗯嗯,当前是为了解析 svn diff 格式做的。
按道理说,git diff,svn diff,diff -u 生成的都是 unified diff 格式的 patch,只是说一些头部的识别标识有点差异,我还没有花时间去分别的做一下适配。

