Below is the file 'mkpristine.py' from this revision. You can also download the file.

#!/usr/bin/env python2.4
# vim:et:ts=4:

from sys import argv, exit, stdin, stdout, stderr
import random
from random import choice, randint
from itertools import izip, tee
from shutil import copyfile
from os import environ, WEXITSTATUS
from popen2 import Popen3

def usage():
    print>>stderr, "Usage: %s <database> <number of dbs to end up with> [optional seed]"
    print>>stderr
    print>>stderr, "Respects the MONOTONE environment variable"

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    try:
        b.next()
    except StopIteration:
        pass
    return izip(a, b)

def set_random():
    if len(argv) == 4:
        seed = int(argv[3])
    else:
        seed = randint(10000, 1000000)

    print "Random seed is %d" % seed

    random.seed(seed)

def monotone(db, args):
    try:
        MONOTONE = environ['MONOTONE']
    except KeyError:
        MONOTONE = 'monotone'

    cmd = [MONOTONE, '-d', db, '--dump=mkpristine.dump'] + args
    p = Popen3(cmd)
    stdout = p.fromchild
    lines = stdout.readlines()
    w = p.wait()
    exitcode = WEXITSTATUS(w)
    if exitcode != 0:
        print>>stderr
        print>>stderr, "monotone process exited with status %d" % exitcode
        print>>stderr, "cmd: %s" % ' '.join(cmd)
        exit(3)

    return lines


def vacuum(db):
    monotone(db, ['db', 'execute', 'vacuum'])

def get_num_revs(db):
    m = monotone(db, ['auto', 'select', ''])
    return len( m )

def remove_one_rev(db):

    m = monotone(db, ['auto', 'leaves'])
    leaves = map(lambda l: l.strip(), m)

    if len(leaves) < 1:
        print>>stderr, "Ran out of revs to remove"
        exit(2)

    to_kill = choice(leaves)
    monotone(db, ['db', 'kill_rev_locally', to_kill])

def main():
    if len(argv) != 3 and len(argv) != 4:
        usage()
        exit(1)

    db = argv[1]

    num_dbs = int(argv[2])

    set_random()

    copyfile(db, 'pristine-0.db')

    num_revs = get_num_revs('pristine-0.db')

    num_removed_per_db = num_revs / num_dbs
    print "Removing %d revs per db" % num_removed_per_db

    pristine_dbs = map(lambda i: "pristine-%s.db" % i, range(num_dbs) )

    for a, b in pairwise(pristine_dbs):
        copyfile(a, b)

        print b

        for i in range(num_removed_per_db):
            remove_one_rev(b)
            stdout.write('.')
        print



if __name__ == '__main__':
    main()