Creating a patch as a zip
#diffdiff.py
# Create a zip file containing the difference between two directories.
# Usage: python dirdiff.py newdir olddir [outputfile]
# Files files in newdir that are different in olddir or are not present
# will be zipped. If the outputfile parameter is not provided the a
# file diff.zip will be created.
#
from os import walk, stat
from os.path import join, sep, split
from sys import argv
from itertools import izip
from zipfile import ZipFile, ZIP_DEFLATED
def chop(base, path):
if not base.endswith(sep):
base = base + sep
return path[len(base):]
def listfiles(path):
for base, dirs, files in walk(path):
for f in files:
yield join(base, f)
def dirdiff(new_path, old_path, diff_file):
zf = ZipFile(diff_file, "w")
def write(file_path):
zf.write(file_path, chop(new_path, file_path), ZIP_DEFLATED)
for old, new in izip(walk(old_path), walk(new_path)):
(old_base, old_dirs, old_files) = old
(new_base, new_dirs, new_files) = new
for d in set(new_dirs).difference(old_dirs):
for f in listfiles(join(new_base, d)):
write(f)
for f in set(new_files).difference(old_files):
write(join(new_base,f))
fs = set(old_files) & set(new_files)
ds = set(old_dirs) & set(new_dirs)
old_dirs[:] = ds
new_dirs[:] = ds
for f in fs:
file_old = join(old_base, f)
file_new = join(new_base, f)
if (stat(file_old).st_mtime != stat(file_new).st_mtime
and file(file_old).read()!=file(file_new).read()):
write(join(new_base, f))
zf.close()
if __name__ == "__main__":
new = argv[1]
old = argv[2]
if len(argv) == 4:
out=argv[3]
else:
out="diff.zip"
dirdiff(new, old, out)
1 Comments:
Reminds me of this feature in Trac:
http://trac.edgewall.org/ticket/303
Post a Comment
<< Home