hgdiff
105 lines
| 3.1 KiB
| text/plain
|
TextLexer
/ contrib / hgdiff
|
r1636 | #!/usr/bin/env python | ||
import os, sys, struct, stat | ||||
import difflib | ||||
import re | ||||
from optparse import OptionParser | ||||
from mercurial.bdiff import bdiff, blocks | ||||
|
r3398 | from mercurial.mdiff import bunidiff, diffopts | ||
|
r1636 | |||
|
r3398 | VERSION="0.3" | ||
|
r1636 | usage = "usage: %prog [options] file1 file2" | ||
parser = OptionParser(usage=usage) | ||||
parser.add_option("-d", "--difflib", action="store_true", default=False) | ||||
parser.add_option('-x', '--count', default=1) | ||||
parser.add_option('-c', '--context', type="int", default=3) | ||||
parser.add_option('-p', '--show-c-function', action="store_true", default=False) | ||||
|
r5081 | parser.add_option('-w', '--ignore-all-space', action="store_true", | ||
|
r1636 | default=False) | ||
(options, args) = parser.parse_args() | ||||
if not args: | ||||
parser.print_help() | ||||
sys.exit(1) | ||||
# simple utility function to put all the | ||||
# files from a directory tree into a dict | ||||
def buildlist(names, top): | ||||
tlen = len(top) | ||||
for root, dirs, files in os.walk(top): | ||||
l = root[tlen + 1:] | ||||
for x in files: | ||||
p = os.path.join(root, x) | ||||
st = os.lstat(p) | ||||
if stat.S_ISREG(st.st_mode): | ||||
names[os.path.join(l, x)] = (st.st_dev, st.st_ino) | ||||
def diff_files(file1, file2): | ||||
|
r8527 | if file1 is None: | ||
|
r9136 | b = file(file2).read().splitlines(True) | ||
|
r1636 | l1 = "--- %s\n" % (file2) | ||
l2 = "+++ %s\n" % (file2) | ||||
l3 = "@@ -0,0 +1,%d @@\n" % len(b) | ||||
l = [l1, l2, l3] + ["+" + e for e in b] | ||||
|
r8527 | elif file2 is None: | ||
|
r9136 | a = file(file1).read().splitlines(True) | ||
|
r1636 | l1 = "--- %s\n" % (file1) | ||
l2 = "+++ %s\n" % (file1) | ||||
l3 = "@@ -1,%d +0,0 @@\n" % len(a) | ||||
l = [l1, l2, l3] + ["-" + e for e in a] | ||||
else: | ||||
t1 = file(file1).read() | ||||
t2 = file(file2).read() | ||||
|
r9136 | l1 = t1.splitlines(True) | ||
l2 = t2.splitlines(True) | ||||
|
r1636 | if options.difflib: | ||
l = difflib.unified_diff(l1, l2, file1, file2) | ||||
else: | ||||
|
r3398 | l = bunidiff(t1, t2, l1, l2, file1, file2, | ||
diffopts(context=options.context, | ||||
showfunc=options.show_c_function, | ||||
ignorews=options.ignore_all_space)) | ||||
|
r1636 | for x in l: | ||
if x[-1] != '\n': | ||||
x += "\n\ No newline at end of file\n" | ||||
print x, | ||||
file1 = args[0] | ||||
file2 = args[1] | ||||
if os.path.isfile(file1) and os.path.isfile(file2): | ||||
diff_files(file1, file2) | ||||
elif os.path.isdir(file1): | ||||
if not os.path.isdir(file2): | ||||
sys.stderr.write("file types don't match\n") | ||||
sys.exit(1) | ||||
d1 = {} | ||||
d2 = {} | ||||
buildlist(d1, file1) | ||||
buildlist(d2, file2) | ||||
keys = d1.keys() | ||||
keys.sort() | ||||
for x in keys: | ||||
if x not in d2: | ||||
f2 = None | ||||
else: | ||||
f2 = os.path.join(file2, x) | ||||
st1 = d1[x] | ||||
st2 = d2[x] | ||||
del d2[x] | ||||
if st1[0] == st2[0] and st1[1] == st2[1]: | ||||
sys.stderr.write("%s is a hard link\n" % x) | ||||
continue | ||||
x = os.path.join(file1, x) | ||||
diff_files(x, f2) | ||||
keys = d2.keys() | ||||
keys.sort() | ||||
for x in keys: | ||||
f1 = None | ||||
x = os.path.join(file2, x) | ||||
diff_files(f1, x) | ||||