#!/usr/bin/env python """ mtnpatch is a patch tool intended to apply 'mtn diff' patch, including the additional cset operations (e.g. add, drop and rename) listed in mtn diff comments. mtnpatch does not actually apply the patch. It only dumps the list of commands to enter to actually apply the patch. To apply the patch, use 'mtnpatch.py file.patch | sh' """ import sys, os, string, getopt, re mtncmd = "mtn" def usage(): print "Usage: mtnpatch.py [options] file.patch" print "Options:" print " -h --help display help message" print " -R --reverse apply patch in reverse" print "\nTo actually apply the patch, use 'mtnpatch.py file.patch | sh'" def main(argv = None): if argv is None: argv = sys.argv try: opts, list = getopt.getopt(sys.argv[1:], 'h:R', ["--help", "--reverse"]) except: usage() sys.exit(2) reverse = False for o, a in opts: if o in ("-h", "--help"): usage() sys.exit(1) if o in ("-R", "--reverse"): reverse = True if len(list) != 1: usage() sys.exit(1) if os.path.exists(list[0]): input = open(list[0], 'r') renameFrom = "" cmd = "" addedFiles = [] addedDirs = [] droppedFiles = [] droppedDirs = [] renamedFiles = [] for line in input: if len(line) > 0: if line[0] == '#': matches = re.search("#\s+(\w+)\s+\"(.*)\"", line) if matches is not None: cmd = matches.group(1) fileName = matches.group(2) isDir = os.path.isdir(fileName) if cmd == "delete": if isDir: droppedDirs.append(fileName) else: droppedFiles.append(fileName) elif cmd == "add" or cmd == "add_file" or cmd == "add_dir": if isDir: addedDirs.append(fileName) else: addedFiles.append(fileName) elif cmd == "rename": renameFrom = fileName elif cmd == "to" and renameFrom != "": renamedFiles.append((renameFrom, fileName)) renameFrom = "" else: cmd = "" if reverse: print "patch -R -p0 < %s" % list[0] for f in addedFiles: print "%s drop -e %s" % (mtncmd, f) for f in addedDirs: print "%s drop -e %s" % (mtncmd, f) for fold,fnew in renamedFiles: print "%s rename -e %s %s" % (mtncmd, fnew, fold) for f in droppedDirs: print "%s revert %s" % (mtncmd, f) for f in droppedFiles: print "%s revert %s" % (mtncmd, f) else: print "patch -p0 < %s" % list[0] for f in droppedFiles: print "%s drop -e %s" % (mtncmd, f) for f in droppedDirs: print "%s drop -e %s" % (mtncmd, f) for fold,fnew in renamedFiles: print "%s rename -e %s %s" % (mtncmd, fold, fnew) for f in addedDirs: print "%s add %s" % (mtncmd, f) for f in addedFiles: print "%s add %s" % (mtncmd, f) if __name__ == "__main__": sys.exit(main())