--- /dev/null
+#!/usr/bin/python
+
+import os, os.path
+import subprocess
+import re
+
+from optparse import OptionParser
+
+def report_stderr(stderrdata):
+ if stderrdata:
+ print "STDERR BEG (%d chars)",len(stderrdata)
+ print stderrdata
+ print "STDERR END (%d chars)",len(stderrdata)
+
+def git_update (dir):
+ os.chdir(dir)
+ print "git pull in %s"%dir
+ prog=subprocess.Popen(["git","pull"],stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ try:
+ (stdoutdata, stderrdata) = prog.communicate()
+ except KeyboardInterrupt:
+ raise Exception, "Interrupted by user"
+ prog.wait()
+ print stdoutdata,
+ report_stderr(stderrdata)
+
+
+excludes=[ "*.git*", "*~" ]
+excludes+= [ "*.pyc", "*.png", "*.pdf", "*.out" , "*.DS_Store", "*.lint" ]
+excludes+= [ "listfiles.sh", "python.*" ]
+def run_diff(options):
+ dir1=options.left_dir
+ dir2=options.right_dir
+ command=["diff","-r",]
+ for exclude in excludes:
+ command += [ "-x", "%s"%exclude]
+ command += [dir1,dir2]
+ prog=subprocess.Popen(command,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ print "diffing -r %s %s"%(dir1,dir2)
+ try:
+ (stdoutdata, stderrdata) = prog.communicate()
+ except KeyboardInterrupt:
+ raise Exception, "Interrupted by user"
+ prog.wait()
+ report_stderr(stderrdata)
+
+ re_only_left =re.compile("^Only in %s[:/]"%dir1)
+ re_only_right=re.compile("^Only in %s[:/]"%dir2)
+ re_binary =re.compile("^Binary files %s.* and %s.*"%(dir1,dir2))
+ re_start_diff=re.compile("diff -r.*%s/(?P<path>.*) %s/(?P=path)"%(dir1,dir2))
+
+ only_left=[]
+ only_right=[]
+ ignored=[]
+
+ class Context:
+ def __init__ (self,diffs):
+ self.current_path=''
+ self.current_diff=[]
+ self.diffs=diffs
+ def close_diff(self):
+ if self.current_path: self.diffs[self.current_path]=self.current_diff
+ elif self.current_diff: print """----------
+WARNING, diff with no path %s
+----------"""%self.current_diff
+ self.current_path=''
+ self.current_diff=[]
+ def set_path (self,path):
+ self.current_path=path
+ def insert_line(self,line):
+ self.current_diff.append(line)
+
+ ### parse
+ diffs={}
+ context=Context(diffs)
+ for line in stdoutdata.split("\n"):
+ m=re_only_left.match(line)
+ if m:
+ context.close_diff()
+ only_left.append(line)
+ continue
+ m=re_only_right.match(line)
+ if m:
+ context.close_diff()
+ only_right.append(line)
+ continue
+ m=re_binary.match(line)
+ if m:
+ context.close_diff()
+ ignored.append(line)
+ continue
+ m=re_start_diff.match(line)
+ if m:
+ context.close_diff()
+ context.set_path(m.group('path'))
+ continue
+ context.insert_line(line)
+
+ ### ignore some entries - maybe not needed if we're smart with diff
+
+ # print report
+ print "< < < < < %d old files/dirs"%len(only_left)
+ for l in only_left: print "< < < < < ",l
+ print "> > > > > %d new files/dirs"%len(only_right)
+ for l in only_right: print "> > > > > ",l
+ print "= = = = = %d files"%len(diffs)
+ for (path,contents) in diffs.iteritems():
+ if options.verbose:
+ print "= = = = = Diffs in path %s"%path
+ for line in contents: print line
+ else:
+ print "Diffs in path %s (%d lines)"%(path,len(contents))
+
+
+left_default=os.path.expanduser("~/git/sfa")
+right_default=os.path.expanduser("~/git/sfa-generic")
+
+def main ():
+ parser=OptionParser()
+ parser.add_option("-g","--git",action='store_true',dest='git',default=False,
+ help="run git pull before diffing")
+ parser.add_option("-l","--left",action='store',dest='left_dir',default=left_default,
+ help="left dir, default=%s"%left_default)
+ parser.add_option("-r","--right",action='store',dest='right_dir',default=right_default,
+ help="right dir, default=%s"%right_default)
+ parser.add_option("-v","--verbose",action='store_true',dest='verbose',default=False,
+ help="Show actual diff contents")
+ (options,args)=parser.parse_args()
+ if options.git:
+ git_update(options.left_dir)
+ git_update(options.right_dir)
+ run_diff(options)
+
+if __name__ == "__main__":
+ main()