Search code examples
gitdiff

Highlighting added/deleted lines, ignoring moves, in a patch file


I'm reviewing a patch that moved a lot of things around, added a few things, and removed a few things. I'm wondering if anyone's written a utility for picking out the unique adds/removes in a universal diff?

That is, an add and a remove of the same line should cancel themselves out.

Obviously this isn't useful all the time, but sometimes it's exactly what I want :)


Solution

  • This is what I ended up using.

    Example usage:

    git diff -w | /path/to/ignore_moves.py | less -R

    ignore_moves.py

    #!/usr/bin/python                                                                                                             
    
    import sys
    from itertools import *
    
    RED = 31
    GREEN = 32
    
    RESET_SEQ = "\033[0m"
    COLOR_SEQ = "\033[0;%dm"
    
    stack = []
    
    def inverse(line):
        return ('-' if line[0] == '+' else '+') + line[1:].strip()
    
    def reverse_enumerate(l):
        for i, x in enumerate(reversed(l)):
            yield len(l)-1-i, x
    
    def dumpchanges():
        for line in stack:
            SEQ = COLOR_SEQ % (GREEN if line.startswith('+') else RED)
            print SEQ + line.strip() + RESET_SEQ
        stack[:] = []
    
    for line in sys.stdin.readlines():
        if not line[1:].strip():
            continue # ignore empty lines                                                                                         
        if line.startswith(('---', '+++')):
            dumpchanges()
            print line.strip()
        elif line.startswith(('+', '-')):
            inverted = inverse(line)
            line = line[0] + line[1:].strip()
            for i, match in reverse_enumerate(stack):
                if inverted == match:
                    stack.pop(i)
                    break
            else:
                stack.append(line)
    
    # finished reading, still have state to be dumped                                                                             
    dumpchanges()