#!/usr/bin/env python # # Adapter for using interdiff with mercurial's extdiff extension. # # Copyright 2006 Bryan O'Sullivan # # This software may be used and distributed according to the terms of # the GNU General Public License, incorporated herein by reference. import os import shutil import sys import tempfile if len(sys.argv) < 4: print >> sys.stderr, ('usage: %s srcrepo destrepo cset-to-omit [...]' % os.path.basename(sys.argv[0])) sys.exit(1) srcrepo, destrepo = sys.argv[1], sys.argv[2] omit = sys.argv[3:] changemap = {} revs = [] parent = None sys.stdout.write('gathering history...') sys.stdout.flush() for line in os.popen("hg --cwd %r log -r0:tip --template '{rev}:{node} {parents}\n'" % srcrepo): changes = line.split() cset = changes[0].split(':')[1] rev = len(revs) changemap[cset] = rev if len(changes) >= 2: p1 = int(changes[1].split(':', 1)[0]) if len(changes) == 3: p2 = int(changes[2].split(':', 1)[0]) else: p2 = None if len(changes) == 1: p1 = parent revs.append((cset, p1, p2)) parent = rev sys.stdout.write(' %d revs\n' % len(revs)) def findrev(r): try: i = int(r) if str(i) == r: rev = i if rev < 0: rev += len(revs) if rev < 0 or rev > len(revs): print >> sys.stderr, 'bad changeset: %r' % r sys.exit(1) cset = revs[rev][0] except ValueError: cset = r matches = [changemap[c] for c in changemap if c.startswith(cset)] if len(matches) != 1: print >> sys.stderr, 'bad changeset: %r' % r sys.exit(1) rev = matches[0] return rev def run(cmd): print cmd ret = os.system(cmd) if ret: print >> sys.stderr, 'failure:', cmd sys.exit(1) omit = map(findrev, omit) omit.sort() newrevs = revs[:omit[0]] tip = len(newrevs) - 1 run('hg clone -q -r%s %r %r' % (tip, srcrepo, destrepo)) os.environ['HGMERGE'] = 'true' patchdir = tempfile.mkdtemp(prefix='replay.') try: run('hg --cwd %r export --git -o %r%s%%R %d:tip' % (srcrepo, patchdir, os.sep, omit[0]+1)) for rev in xrange(omit[0], len(revs)): if rev in omit: print 'omit', rev newrevs.append((None, revs[rev][1], None)) continue _, p1, p2 = revs[rev] np1 = newrevs[p1][1] if tip != np1: run('hg --cwd %r update -q -C %s' % (destrepo, np1)) np2 = None if p2: np2 = newrevs[p2][1] run('hg --cwd %r merge -q %s' % (destrepo, np2)) print >> sys.stderr, 'XXX - cannot handle merges properly yet' run('hg --cwd %r import -q -f %r%s%d' % (destrepo, patchdir, os.sep, rev)) tip = len(newrevs) - 1 newrevs.append((None, tip, np2)) finally: print 'cleaning up ...' #shutil.rmtree(patchdir)