All of lore.kernel.org
 help / color / mirror / Atom feed
* 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

only message in thread, other threads:[~2007-03-11 14:58 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <432beae0605272223y4eeb385eib0ea22eb136aeff8@mail.gmail.com>
     [not found] ` <432beae0606101112s21729552odecce94034ad9d6@mail.gmail.com>
2007-03-11 14:59   ` mtnpatch (updated) cyril Romain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.