3

我试图找出一种方法来创建统一的差异,其中行号仅显示N上下文行。我一直无法做到这一点difflib.unified_diff。我需要显示两个文件中的更改。

我能来的最接近的是diff在命令行上使用,如下所示:

/usr/bin/diff --unchanged-line-format=' %.2dn %L' --old-line-format="-%.2dn %L" --new-line-format="+%.2dn %L" file1.py file2.py

我只想显示N上下文行,/usr/bin/diff似乎不支持自定义行格式的上下文(例如,-U2 与 --line-format " conflicting output style options" 不兼容)。

下面是我想要完成的示例(与上述差异相同的输出,但仅显示围绕更改的 1 行上下文):

+01: def renamed_function() -01: def original_function(): 02: +03: """ Neat stuff here """ 04: 21: +22: # Here's a new comment 23: 85: # Output the value of foo() +86: print "Foo is %s"%(foo()) -86: print foo() 87:

4

1 回答 1

0

我能够弄清楚一些非常接近我想做的事情。不过,它比常规 diff 慢。这是来自我的项目GitGate的完整代码。

def unified_diff(to_file_path, from_file_path, context=1):

    """ Returns a list of differences between two files based
    on some context. This is probably over-complicated. """

    pat_diff = re.compile(r'@@ (.[0-9]+\,[0-9]+) (.[0-9]+,[0-9]+) @@')

    from_lines = []
    if os.path.exists(from_file_path):
        from_fh = open(from_file_path,'r')
        from_lines = from_fh.readlines()
        from_fh.close()

    to_lines = []
    if os.path.exists(to_file_path):
        to_fh = open(to_file_path,'r')
        to_lines = to_fh.readlines()
        to_fh.close()

    diff_lines = []

    lines = difflib.unified_diff(to_lines, from_lines, n=context)
    for line in lines:
        if line.startswith('--') or line.startswith('++'):
            continue

        m = pat_diff.match(line)
        if m:
            left = m.group(1)
            right = m.group(2)
            lstart = left.split(',')[0][1:]
            rstart = right.split(',')[0][1:]
            diff_lines.append("@@ %s %s @@\n"%(left, right))
            to_lnum = int(lstart)
            from_lnum = int(rstart)
            continue

        code = line[0]

        lnum = from_lnum
        if code == '-':
            lnum = to_lnum
        diff_lines.append("%s%.4d: %s"%(code, lnum, line[1:]))

        if code == '-':
            to_lnum += 1
        elif code == '+':
            from_lnum += 1
        else:
            to_lnum += 1
            from_lnum += 1

    return diff_lines
于 2014-04-28T14:36:28.717 回答