merging debian changelog
Pierre Habouzit
madcoder at debian.org
Mon Jan 7 23:55:08 UTC 2008
On lun, jan 07, 2008 at 10:43:58 +0000, Pierre Habouzit wrote:
> 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 :)
Here is a better version, that I believe can be used as a git merge
driver using this configuration snipplet:
[merge "merge-debchangelog"]
name = Debian Changelog merge driver
driver = /path/to/merge-debchangelog.py %O %A %B %A
and then, if I'm correct, you can in the .gitattribute of your debian/
directory set:
----8<----
/changelog merge=merge-debchangelog
---->8----
I'm not 100% sure it will work, but I think so, and by the way, the
script is fully reusable for other SCM. Its usage is:
merge-debchangelog.py ANCESTOR YOURS OTHER [OUTPUT]
it's safe to reuse any of the three other argument as the output file,
else stdout is used.
I didn't put a copyright statement, but consider it be under the BSD
license.
--
·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+).*')
footer_re = re.compile('^ --(?: (.*) (\w\w\w, +(\d| \d|\d\d) \w\w\w \d\d\d\d ' +
'\d\d:\d\d:\d\d [-+]\d\d\d\d( \(.*\))?))?\s*$')
diff_strs = ["<<<<<<<\n", "=======\n", ">>>>>>>\n"]
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()
ver = match.group('version')
cur = ''
cur += line
if ver: chunks[ver] = cur.strip()
return chunks
def to_state(l, old, new):
while old != new:
l.append(diff_strs[old])
old = (old + 1) % 3
return new
def do_merge(orig, left, right):
o = parse_changelog(orig) # unused for now
l = parse_changelog(left)
r = parse_changelog(right)
state = 0
conflict = False
res = []
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]:
conflict = True
for line in difflib.ndiff(l[ver].split('\n'), r[ver].split('\n')):
state = to_state(res, state, diff_auto[line[0]])
res.append(line[2:] + "\n")
state = to_state(res, state, 0)
else:
res.append((l.get(ver) or r.get(ver)) + "\n")
res.append("\n")
return conflict, res
if len(sys.argv) not in (4, 5):
sys.stderr.write("""\
usage: merge-debchangelog.py ORIGIN YOURS OTHER [OUTPUT]
if OUTPUT isn't specified, standard out is assumed
""")
conflict, res = do_merge(sys.argv[1], sys.argv[2], sys.argv[3])
if len(sys.argv) is 4:
sys.stdout.writelines(res)
else:
open(sys.argv[4], "w+").writelines(res)
sys.exit(conflict)
-------------- 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/20080108/ee6d6cdf/attachment.pgp
More information about the vcs-pkg-discuss
mailing list