質問

I'm trying to figure out a way to create unified diffs with line numbers only showing N lines of context. I have been unable to do this with difflib.unified_diff. I need to show changes in both files.

The closest I can come is using diff on the command line like so:

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

BUT I only want to show N lines of context, and /usr/bin/diff doesn't seem to support context with a custom line format (eg. -U2 is not compatible with --line-format "conflicting output style options").

Below is an example of what I'd like to accomplish (the same output as the above diff, but only showing 1 line of context surrounding changes):

+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:

役に立ちましたか?

解決

I was able to figure out something very close to what I wanted to do. It's slower than regular diff, though. Here's the entire code, from my project 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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top