Question

Here's the beginning part of my diff.

#!/usr/bin/env python
import fileinput
import difflib
import subprocess
import sys

# for debugging
def info(type, value, info):
    import traceback
    traceback.print_exception(type, value, info)
    print
    pdb.pm()

sys.excepthook = info
import pdb
#end debugging

if len(sys.argv) == 8:
    # assume this was passed to git; we can of course do
    # some parsing to check if we got valid git style args
    args = [sys.argv[2], sys.argv[5]]
elif len(sys.argv) == 3:
    args = sys.argv[1:]
else:
    exit("Not a valid number of args (2 or 7) to this diff program")
print "Files: " + ' '.join(args)
for filename in args:
    filetype = subprocess.check_output(['file', filename])
    if filetype.find('text') == -1:
        args.insert(0, 'diff')
        print "A binary file was found: " + filename + ", deferring to diff"
        exit(subprocess.call(args))

When a binary (or otherwise non text) file is encountered, it attempts to fork diff to obtain whether the binary files differ or not. The goal is for this python diff program to be used as an external differ for git.

But I get this ghastly "external diff died, stopping at <file>" message once it hits the binary file.

How is git evaluating my program? How does it know it died? Isn't return value supposed to indicate the differing condition?

Was it helpful?

Solution

There's no exit function in your code. How about replace exit to sys.exit?

#!/usr/bin/env python

import subprocess
import sys

if len(sys.argv) == 8:
    # assume this was passed to git; we can of course do
    # some parsing to check if we got valid git style args
    args = [sys.argv[2], sys.argv[5]]
elif len(sys.argv) == 3:
    args = sys.argv[1:]
else:
    print "Not a valid number of args (2 or 7) to this diff program"
    sys.exit(1)
print "Files: ", args
for filename in args:
    filetype = subprocess.check_output(['file', filename])
    if filetype.find('text') == -1:
        args.insert(0, 'diff')
        print "A binary file was found: " + filename + ", deferring to diff"
        #sys.stdout.flush()
        subprocess.call(args)
        sys.exit(0)

EDIT: git depend on external diff's exit status. diff exit with 0 only if there is no differce. So changed the code not to use diff's exit status.

PS: Without sys.stdout.flush(), diff output come before print output.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top