hgext3rd/evolve/rewind.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Sun, 17 Jun 2018 00:57:09 +0200
changeset 3859 6e3d844b56f2
parent 3858 bb4f5ad63877
child 3861 bbe635dfd75c
permissions -rw-r--r--
rewind: add a message about the rewinded changesets This helps to understand what happened.

from __future__ import absolute_import

import hashlib

from mercurial import (
    error,
    obsolete,
    scmutil,
)

from mercurial.i18n import _

from . import (
    exthelper,
    rewriteutil,
    compat,
)

eh = exthelper.exthelper()

# flag in obsolescence markers to link to identical version
identicalflag = 4

@eh.command(
    '^rewind',
    [('', 'to', [], _("rewind to these revision")),
    ],
    _(''))
def rewind(ui, repo, **opts):
    """rewind stacks of changeset to a previous content
    """
    unfi = repo.unfiltered()

    if not opts.get('to'):
        raise error.Abort('no revision to rewind to')

    rewinded = scmutil.revrange(repo, opts.get('to'))

    with repo.wlock(), repo.lock():
        # Check that we can rewind these changesets
        with repo.transaction('rewind'):
            for rev in rewinded:
                _revive_revision(unfi, rev)
    repo.ui.status(_('rewinded to %d changesets\n') % len(rewinded))

def _revive_revision(unfi, rev):
    """rewind a single revision rev.
    """
    ctx = unfi[rev]
    extra = ctx.extra().copy()
    # rewind hash should be unique over multiple rewind.
    user = unfi.ui.config('devel', 'user.obsmarker')
    if not user:
        user = unfi.ui.username()
    date = unfi.ui.configdate('devel', 'default-date')
    if date is None:
        date = compat.makedate()
    noise = "%s\0%s\0%d\0%d" % (ctx.node(), user, date[0], date[1])
    extra['__rewind-hash__'] = hashlib.sha256(noise).hexdigest()

    p1 = ctx.p1().node()
    p2 = ctx.p2().node()

    extradict = {'extra': extra}

    new, unusedvariable = rewriteutil.rewrite(unfi, ctx, [], ctx,
                                              [p1, p2],
                                              commitopts=extradict)

    obsolete.createmarkers(unfi, [(ctx, (unfi[new],))],
                           flag=identicalflag, operation='rewind')

    return new