I've accidentally commited some stuff into a darcs 2.0 repository, and
moving it to a darcs 1.0 one using regular darcs tools (push, send)
seems not to be possible (I know darcs warned me about this when
converting the repo, that's why I used the word "accidentally").

So I've resurrected an old script to export darcs' changes as regular
patches. Because it may be useful for other people, I've uploaded it to
http://blitiri.com.ar/p/other/darcs-export (and attached it, as a
special bonus).

For example, to export the last 4 patches you can (from inside a darcs
repository) use

  darcs changes --last=4 --xml-output | darcs-export list

to verify what you're going to export, and then

  darcs changes --last=4 --xml-output | darcs-export export /tmp

to export the four patches into four different nicely-named files inside
/tmp.

Thanks,
                Alberto

#!/usr/bin/python

# Simple script to export darcs' changes as regular patches
# Alberto Bertogli ([EMAIL PROTECTED]), 2008-08-03
#
# The latest version should be available at
# http://blitiri.com.ar/p/other/darcs-export

import sys
import os
from xml.sax import saxutils
from xml.sax import make_parser
from xml.sax.handler import feature_namespaces, ContentHandler

def run_darcs(*params):
        cmd = 'darcs ' + ' '.join(params)
        os.environ['DARCS_DONT_ESCAPE_8BIT'] = '1'
        inf, outf = os.popen4(cmd, 't')
        return outf

class Patch:
        "Represents a single patch/record"
        def __init__(self):
                self.hash = ''
                self.author = ''
                self.date = ''
                self.local_date = ''
                self.name = ''
                self.comment = ''

        def tostr(self):
                s = "%s\n\tAuthor: %s\n\tDate: %s\n\tHash: %s\n" % \
                        (self.name, self.author, self.date, self.hash)
                return s

        def export(self, order, path):
                # '/'s are not allowed in filenames
                name = self.name.replace('/', '-')

                # avoid 'name..patch'
                if name[-1] == '.':
                        name = name[:-1]

                fd = open("%s/%.2d - %s.patch" % (path, order, name), 'w')
                out = run_darcs("diff", "-u", '--match "hash %s"' % self.hash)

                buf = out.read()
                while buf:
                        fd.write(buf)
                        buf = out.read()


class BuildPatchList(ContentHandler):
        def __init__(self):
                self.db = {}
                self.list = []
                self.cur_hash = ''
                self.cur_elem = None
                self.cur_val = ''

        def startElement(self, name, attrs):
                if name == 'patch':
                        p = Patch()
                        p.author = attrs.get('author', None)
                        p.date = attrs.get('date', None)
                        p.local_date = attrs.get('local_date', None)
                        p.hash = attrs.get('hash')
                        self.db[p.hash] = p
                        self.current = p.hash
                        self.list.append(p.hash)
                elif name == 'name':
                        self.db[self.current].name = ''
                        self.cur_elem = 'name'
                elif name == 'comment':
                        self.db[self.current].comment = ''
                        self.cur_elem = 'name'
                else:
                        self.cur_elem = None

        def characters(self, s):
                if not self.cur_elem:
                        return
                self.cur_val += s

        def endElement(self, name):
                if name == 'name':
                        self.db[self.current].name = self.cur_val
                elif name == 'comment':
                        self.db[self.current].current = self.cur_val

                self.cur_elem = None
                self.cur_val = ''


# main

if len(sys.argv) < 3:
        print """\
Use: darcs-export [xmlfile|-] [list|export destdir]"

Examples:
 $ darcs changes --last=4 --xml-output | darcs-export list
 $ darcs changes --last=4 --xml-output | darcs-export export /tmp
        """
        sys.exit(1)

if sys.argv[1] == '-':
        file = sys.stdin
else:
        file = sys.argv[1]

parser = make_parser()
parser.setFeature(feature_namespaces, 0)

handler = BuildPatchList()
parser.setContentHandler(handler)
parser.parse(file)

# reverse the list so the oldest is the first, and the newest is the last
handler.list.reverse()

# we now have two main structures: handler.db is the hash table of Patches,
# indexed by their hash, and handler.list is the ordered list of hashes.

if sys.argv[2] == 'list':
        c = 1
        for h in handler.list:
                print "%.2d:" % c, handler.db[h].tostr()
                c += 1
elif sys.argv[2] == 'export':
        if len(sys.argv) < 4:
                print "Destination directory missing"
                sys.exit(1)
        c = 1
        for h in handler.list:
                p = handler.db[h]
                print "%.2d: %s" % (c, p.name)
                p.export(c, sys.argv[3])
                c += 1
else:
        print "Unknown parameter"

_______________________________________________
darcs-users mailing list
[email protected]
http://lists.osuosl.org/mailman/listinfo/darcs-users

Reply via email to