[PATCH] Add script to rewrite manifest to workaround lack of parent deltas

Benoit Boissinot benoit.boissinot at ens-lyon.org
Mon Aug 24 11:26:01 CDT 2009


On Fri, Aug 21, 2009 at 06:18:02PM -0400, Greg Ward wrote:
> # HG changeset patch
> # User Greg Ward <greg-hg at gerg.ca>
> # Date 1233047576 0
> # Node ID 4b03b395c5923319c1d9986ab47e6e3d99bfc6f8
> # Parent  b47fa638bfc7d6e5185f49113a6c418fbe6cf0b3
> Add script to rewrite manifest to workaround lack of parent deltas.

Other comments (sorry I should have batched the review).
> +
> +# Originally written by Benoit Boissinot <benoit.boissinot at ens-lyon.org>
> +# as a patch to rewrite-log.  Cleaned up, refactored, documented, and
> +# renamed by Greg Ward <greg at gerg.ca>.
> +
> +# XXX would be nice to have a way to verify the repository after shrinking,
> +# e.g. by comparing "before" and "after" states of random changesets
> +# (maybe: export before, shrink, export after, diff).
> +
> +import sys, os, tempfile
> +from mercurial import ui as ui_, hg, revlog, transaction, node, util
> +
> +def toposort(rl):
> +

If you want to use .pop() (I'm not sure it's worth it):

> +    # XXX this is a reimplementation of the 'branchsort' topo sort
> +    # algorithm in hgext.convert.convcmd... would be nice not to duplicate
> +    # the algorithm
> +    write('sorting ...')
> +    visit = root
> +    ret = []
> +    while visit:
> +        i = visit.pop(0)

        i = visit.pop()

> +        ret.append(i)
> +        if i not in children:
> +            # This only happens if some node's p1 == p2, which can
> +            # happen in the manifest in certain circumstances.
> +            continue
> +        next = []
> +        for c in children.pop(i):
> +            parents_unseen = [p for p in rl.parentrevs(c)
> +                              if p != node.nullrev and p in children]
> +            if len(parents_unseen) == 0:
> +                next.append(c)

               next.insert(0, c)

> +        visit = next + visit

          visit += next

> +
> +def main():
> +
> +    # Unbuffer stdout for nice progress output.
> +    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
> +    write = sys.stdout.write
> +
> +    # Open the local repository.
> +    ui = ui_.ui()
> +    repo = hg.repository(ui)
> +
> +    indexfn = repo.join('store/00manifest.i')
> +    datafn = indexfn[:-2] + '.d'
> +    if not os.path.exists(datafn):
> +        sys.exit('error: %s does not exist: manifest not big enough '
> +                 'to be worth shrinking' % datafn)
> +

I've found the warning annoying so I changed it like this:

> +    oldindexfn = indexfn + '.old'
> +    olddatafn = datafn + '.old'

    oldindexfn = tempfile.mktemp(dir=repo.sjoin(''),
                                 prefix='00manifest.',
                                 suffix='.i.old')
    olddatafn = oldindexfn[:-6] + '.d.old'

> +    if os.path.exists(oldindexfn) or os.path.exists(olddatafn):
> +        sys.exit('error: one or both of %s or %s exists from a previous run; '
> +                 'please clean up before running again'
> +                 % (oldindexfn, olddatafn))
> +


Final note: If someone wants to do that, the script could accept
arbitrary revlogs as arguments, except the changelog (because it would
need fixing the linkrevs).


regards,

Benoit
-- 
:wq


More information about the Mercurial-devel mailing list