merging debian changelog

Pierre Habouzit madcoder at debian.org
Mon Jan 7 22:43:59 UTC 2008


  I know this is a painful thing to do (if you consider the inherent
triviality of it), hence I ended up writing a custom merger. This is all
very sketchy, but I'm sure people will enhance it :)

  For now, it's primarily intended as a merger between two full
changelog, when for example you merge your etch-backports branch into
your sid one, or the experimental one into the sid one or any similar
setup. It generates painful merges, which are trivial to solve once you
know what a debian changelog is.

  The script is attached, and you can usually run it this way:

  merge-debchangelog.py <(git show debian-sid:debian/changelog) <(git show debian-experimental:debian/changelog) > debian/changelog

It'll leave conflicts marks for the entries for a _same_ debian
version but with different content.

  This needs python-apt.

-- 
·O·  Pierre Habouzit
··O                                                madcoder at debian.org
OOO                                                http://www.madism.org
-------------- next part --------------
#!/usr/bin/python
import re, sys, apt_pkg, difflib

apt_pkg.InitSystem()

header_re = re.compile('^\S+ \((?P<version>.*)\) .*;.*urgency=(?P<urgency>\w+).*')
diff_strs = ["<<<<<<<", "=======", ">>>>>>>"]
diff_auto = {' ': 0, '-': 1, '+': 2}

def parse_changelog(file):
    chunks = {}
    cur = ""
    ver = None
    for line in open(file).readlines():
        match = header_re.match(line)
        if match:
            if ver: chunks[ver] = cur.strip() + "\n"
            ver = match.group('version')
            cur = ''
        cur += line
    if ver: chunks[ver] = cur.strip()
    return chunks

def to_state(old, new):
    while old != new:
        print diff_strs[old]
        old = (old + 1) % 3
    return new

def do_merge(left, right):
    l = parse_changelog(left)
    r = parse_changelog(right)
    state = 0
    versions = list(set(l.keys() + r.keys()))
    versions.sort(lambda x, y: -apt_pkg.VersionCompare(x, y))
    for ver in versions:
        if ver in l and ver in r and l[ver] != r[ver]:
            for line in difflib.ndiff(l[ver].split('\n'), r[ver].split('\n')):
                state = to_state(state, diff_auto[line[0]])
                print line[2:]
            state = to_state(state, 0)
        else:
            print l.get(ver) or r.get(ver)
    print ""

do_merge(sys.argv[1], sys.argv[2])
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.alioth.debian.org/pipermail/vcs-pkg-discuss/attachments/20080107/8b062289/attachment.pgp 


More information about the vcs-pkg-discuss mailing list