mq: apply patch is any posative guard matches
this is like guards command from quilt package.
#!/usr/bin/env python
import os, sys, struct, stat
import difflib
import re
from optparse import OptionParser
from mercurial.bdiff import bdiff, blocks
from mercurial.mdiff import bunidiff
VERSION="0.2"
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)
parser.add_option('-w', '--ignore-all-space', action="store_true",
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):
if file1 == None:
b = file(file2).read().splitlines(1)
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]
elif file2 == None:
a = file(file1).read().splitlines(1)
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()
l1 = t1.splitlines(1)
l2 = t2.splitlines(1)
if options.difflib:
l = difflib.unified_diff(l1, l2, file1, file2)
else:
l = bunidiff(t1, t2, l1, l2, file1, file2, context=options.context,
showfunc=options.show_c_function,
ignorews=options.ignore_all_space)
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)