* Re: mtnpatch (updated)
[not found] ` <432beae0606101112s21729552odecce94034ad9d6@mail.gmail.com>
@ 2007-03-11 14:59 ` cyril Romain
0 siblings, 0 replies; only message in thread
From: cyril Romain @ 2007-03-11 14:59 UTC (permalink / raw)
To: papercrane; +Cc: oe, monotone, openembedded-devel
[-- Attachment #1: Type: text/plain, Size: 2051 bytes --]
Justin Patrin wrote:
> Just thought I'd let everyone know that I just cherrypicked my first
> revision with mtnpatch.py. I made some efl/e17 updates to .dev and
> edited one file, made a diff, and applied the diff to .oz354x with
> mtnpatch.py. It worked like a charm.
>
> For those that missed it, I have checked in mtnpatch.py into
> org.openembedded.dev in contrib/. I have also switch to using a regex
> instead of split() so that whitespace in filenames should be correctly
> taken care of.
>
> The script is used like this:
> mtn diff -r ParentRev -r RevToCherryPick > file.patch
> cd /branch/to/cherrypick/to
> contrib/mtnpatch.py file.patch
> Look at the output to make sure it's sane
> contrib/mtnpatch.py file.patch | sh
> mtn ci
Maybe I've just missed the right mtn command reading the documentation,
but as I'm submitting some patches/recipes for OE metadata, I'd like to:
1. test that my 'mtn diff' patches successfully apply on a up-to-date
metadata tree without any local modifications.
2. apply some patches to another development tree.
And this script is "almost" what I'm looking for :)
"Almost" because it does not takes file/directory drop order into
account, i.e. "mtnpatch.py the.patch | sh" can fail.
For example if mtnpatch dumps:
---
mtn drop -e packages/quilt/files/install.patch
mtn drop -e packages/quilt/files
---
And if you run these commands in that order, you get "mtn: misuse:
cannot remove packages/quilt/files/, it is not empty"
In attachment, an updated version of mtnpatch.py with the following
improvements:
1. output command are sorted, so that 'mtnpatch.py my_patch.patch | sh'
should now succeed in all cases, hopefully :)
2. help (-h, --help) option added, and usage message is printed on misuse
3. reverse mode (-R option) can be also set with --reverse
4. the reverse option is used to unapply the patch. The dropped files
are reverted (not added), but maybe it is not what you, Justin, wanted
to do with -R ?
Best regards,
cyril
[-- Attachment #2: mtnpatch.py --]
[-- Type: text/x-python, Size: 3457 bytes --]
#!/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())
^ permalink raw reply [flat|nested] only message in thread