python实现web svn diff

栏目: Python · 发布时间: 6年前

内容简介:python实现web svn diff

最近想做一个在线codereivew的功能,需要在web页面上分两栏(side-by-side)展示新老代码的差异(diff)。

在github参考了一些项目,例如:coderev、cdiff;经过一定的尝试,最终选择了使用 Python 来实现这个功能,因为python内置的difflib标准库里有一个计算diff的函数是专门用来生成两栏(side-by-side)视图用的,而这个算法是挺复杂的,网上并没有资料讲解,所以拿来即用吧。

项目地址: https://github.com/owenliang/side-by-side-diff

项目效果: https://owenliang.github.io/side-by-side-diff/sample/side-by-side-view.html

思路

生成patch

首先,需要生成diff内容,也就是patch。这种patch文件的格式如下:

Index: bgm/application_zdm/views/mgc_detail.php
===================================================================
--- bgm/application_zdm/views/mgc_detail.php (revision 172736)
+++ bgm/application_zdm/views/mgc_detail.php (working copy)
@@ -189,7 +189,7 @@
         </div>
     </div>
     <div class="button-group pull-right">
-        <a class="btn btn-primary btn-lg btn-submit" name="publish"><?= $status != 2 ? '发布榜单' : '保存榜单' ?></a>
+        <a class="btn btn-primary btn-lg btn-submit" name="publish"><?= $status == 2 ? '保存榜单' : '发布榜单' ?></a>
         <a class="btn btn-success btn-lg btn-submit" name="draft"><?= $status != 2 ? '保存为草稿' : '榜单已发布,退回为草稿' ?></a>
     </div>
 </form>
@@ -236,27 +236,6 @@
                         var uiLi3=[{n:"请选择",k:0}];
                         $(this).find("ul:first").children().each(function(){
                             uiLi3.push({
-                                n:$(this).find("a:first").html(),
-                                k:$(this).find("input:first").val()
-                            });
-                        });
-                        uiLi2.push({
-                            s:$(this).find("a:first").html(),
-                            k:$(this).find("input:first").val(),
-                            r:uiLi3
-                        });
-                    });
-                    uiLi1.push({
-                        n:$(this).find("a:first").html(),
-                        k:$(this).find("input:first").val(),
-                        a:uiLi2
-                    });
-                });
-                cateList.push({
-                    p:$(this).find("a:first").html(),
-                    k:$(this).find("input:first").val(),
-                    c:uiLi1
-                });
             });
             cateJson = {dataList:cateList};
             return cateJson;
@@ -285,42 +264,19 @@
         }
     };
 
-    var toolBox={
-        cateSelected: function (curSelected) {
-            //初始化商品分类json数据
-            handleCategory.getCateJson(function(data){
-                var curSelectedArr=[];
-                var catSelectConf={
-                    jsonData:data,
-                    first:0,//电脑数码
-                    second:0,//手机通讯
-                    third:0,//非智能手机
-                    four:0,
-                    nodata:"none"
+    var toolBox={vwregergweartvwertgreqgewr
                 };
                 if(curSelected){//商品分类id匹配成功
                     curSelectedArr=curSelected.split(",");
                     if(curSelectedArr.length>0){
                         $.each(curSelectedArr,function(index,cid){
-                            if(index==0){
-                                catSelectConf.first=cid;
-                            }else if(index==1){
-                                catSelectConf.second=cid;
-                            }else if(index==2){
-                                catSelectConf.third=cid;
-                            }else if(index==3){
-                                catSelectConf.four=cid;
-                            }else{
+                            if(index=sfawdv
+                                fdd
+                            fvweq
+                            fa
+                            wefawre
+                            fgvwref
 
-                            }
-                        })
-                    }
-                }
-                handleCategory.cateInit(catSelectConf);//选中的商品分类填充到select
-            });
-        },
-    };
-
     toolBox.cateSelected("<?= implode(',', $categories) ?>");
 </script>
 
@@ -341,38 +297,7 @@
 
         $('#tag-selector').select2({
             ajax: {
-                url: '/tool/tag_search_by_title',
-                dataType: 'json',
-                data: function (params) {
-                    return {
-                        term: params.term,
-                        page: params.page
-                    };
-                },
-                processResults: function (data) {
-                    return {
-                        results: data.data,
-                        pagination: {
-                            more: data.data.length > 0
-                        }
-                    };
-                }
-            },
-            placeholder: '键入关键词开始搜索...',
-            minimumInputLength: 1
-        });
-
-        $('.btn-submit').click(function (event) {
-            event.preventDefault();
-
-            var formData = $(this).closest('form').serializeArray();
-
-            switch (this.name) {
-                case 'draft':
-                    formData.push({name: 'status', value: 1});
-                    formData.push({name: 'is_deleted', value: 0});
-                    break;
-                case 'publish':
+           
                     formData.push({name: 'status', value: 2});
                     formData.push({name: 'is_deleted', value: 0});
                     break;

一般我们通过svn diff或者git diff就可以生成,或者通过diff -u filename1 filename2也可以生成。

解析patch

我们需要解析patch文件,这个过程并不复杂。

类似于这种段落,表示是某个文件发生了变更:

Index: bgm/application_zdm/views/mgc_detail.php
===================================================================
--- bgm/application_zdm/views/mgc_detail.php (revision 172736)
+++ bgm/application_zdm/views/mgc_detail.php (working copy)

类似于这种段落,表示文件内的某一段发生了变化:

@@ -189,7 +189,7 @@
         </div>
     </div>
     <div class="button-group pull-right">
-        <a class="btn btn-primary btn-lg btn-submit" name="publish"><?= $status != 2 ? '发布榜单' : '保存榜单' ?></a>
+        <a class="btn btn-primary btn-lg btn-submit" name="publish"><?= $status == 2 ? '保存榜单' : '发布榜单' ?></a>
         <a class="btn btn-success btn-lg btn-submit" name="draft"><?= $status != 2 ? '保存为草稿' : '榜单已发布,退回为草稿' ?></a>
     </div>
 </form>

可见,上述段落删掉了一行,又增加了一行,相当于替换了原先的行。

而没有-号与+号的行,称为上下文(context)行,表示新老文件都拥有且没有变化过的行。

还原老与新段落

对于上述每个段落,我们需要还原出老文件和新文件。

context和-的行是老文件拥有的,而context和+的行是新文件拥有的,通过这样划分就可以得到每个差异段落的老内容和新内容。

调用python重算diff

现在可以将每个段落的老内容和新内容,作为一个pair传递给python的difflib._mdiff函数,这个函数会计算返回一个数组,每一个元素代表了双栏(side-by-side)视图中的一行。

我们需要根据_mdiff的返回值,对新老的行号进行重新标记。

在我的diff.py程序中,最终输出的结果在这里查看: https://raw.githubusercontent.com/owenliang/side-by-side-diff/master/sample/diff.json

可以观察到,最外层数组是若干的index,即发生变化的文件。

而index.segments里的每一个元素则是一个发生差异的段落。

段落内的rows记录了差异的行,我们只需要顺序的展示为两栏即可;左侧是老文件的行内容,右侧是新文件的行内容,红色标识变化前的行,绿色标识变化后的行。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP程序设计

PHP程序设计

Kevin Tatroe、Rasmus Lerdorf / 邓云佳 / 中国电力出版社 / 2003-7-1 / 68.00

本书涵盖了创建一个高效PHP Web应用程序所需要的所有技术,其内容包括:PHP语言基础的详细信息,包括数据类型、变量、操作符和流控制语句。用专门章节讨论关于函数、字符串、数组和对象的基本内容。涵盖通用的PHP Web应用程序设计技术,如表单处理和验证、会话跟踪以及cookie。用和数据库无关的PEAR DB库与关系数据库(如MySQL和Oracle)进行交互的内容。介绍用PHP生成动态图像、创建一起来看看 《PHP程序设计》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具