Commits

Bryan O'Sullivan committed d179d63

New example script attempts to replay history, omitting selected changes.

Comments (0)

Files changed (1)

+#!/usr/bin/env python
+#
+# Adapter for using interdiff with mercurial's extdiff extension.
+#
+# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com>
+#
+# 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)