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