# HG changeset patch # User Pierre-Yves David # Date 1529187318 -7200 # Node ID bbe635dfd75cf3ad3c26536f2ba003e24970132c # Parent fa184c5edfe88d9cb2ec0c980043dd77be1905e8 rewind: obsolete latest successors unless instructed otherwise To prevent the creations of divergence, we automatically mark the successors set of the rewinded changeset as obsoleted by the rewind result. A new flag `--as-divergence` is added to disable this behavior. diff -r fa184c5edfe8 -r bbe635dfd75c hgext3rd/evolve/rewind.py --- a/hgext3rd/evolve/rewind.py Sat Jun 16 23:32:22 2018 +0200 +++ b/hgext3rd/evolve/rewind.py Sun Jun 17 00:15:18 2018 +0200 @@ -1,10 +1,12 @@ from __future__ import absolute_import +import collections import hashlib from mercurial import ( error, obsolete, + obsutil, scmutil, ) @@ -24,10 +26,19 @@ @eh.command( '^rewind', [('', 'to', [], _("rewind to these revision")), + ('', 'as-divergence', None, _("preserve current latest successors")), ], _('')) def rewind(ui, repo, **opts): """rewind stacks of changeset to a previous content + + This command can be used to restore stacks of changesets to an obsolete + state, creating identical identical copies. + + The latest successors the obsolete changesets will be superseed by these + new copies. This behavior can be disabled using `--as-divergence`, the + current latest successors won't be affected and content-divergence will + appears between them and the restored version of the obsolete changesets. """ unfi = repo.unfiltered() @@ -36,11 +47,35 @@ rewinded = scmutil.revrange(repo, opts.get('to')) + successorsmap = collections.defaultdict(set) + rewindmap = {} + sscache = {} with repo.wlock(), repo.lock(): + if not opts['as_divergence']: + for rev in rewinded: + ctx = unfi[rev] + ssets = obsutil.successorssets(repo, ctx.node(), sscache) + if 1 < len(ssets): + msg = _('rewind confused by divergence on %s') % ctx + hint = _('solve divergence first or use "--as-divergence"') + raise error.Abort(msg, hint=hint) + if ssets and ssets[0]: + for succ in ssets[0]: + successorsmap[succ].add(ctx.node()) + # Check that we can rewind these changesets with repo.transaction('rewind'): for rev in rewinded: - _revive_revision(unfi, rev) + ctx = unfi[rev] + rewindmap[ctx.node()] = _revive_revision(unfi, rev) + + relationships = [] + cl = unfi.changelog + for (source, dest) in sorted(successorsmap.items()): + newdest = [rewindmap[d] for d in sorted(dest, key=cl.rev)] + rel = (unfi[source], tuple(unfi[d] for d in newdest)) + relationships.append(rel) + obsolete.createmarkers(unfi, relationships, operation='rewind') repo.ui.status(_('rewinded to %d changesets\n') % len(rewinded)) def _revive_revision(unfi, rev): diff -r fa184c5edfe8 -r bbe635dfd75c tests/test-rewind.t --- a/tests/test-rewind.t Sat Jun 16 23:32:22 2018 +0200 +++ b/tests/test-rewind.t Sun Jun 17 00:15:18 2018 +0200 @@ -260,7 +260,7 @@ Actual rewind ````````````` - $ hg rewind --hidden --to 'desc("c_B0")' + $ hg rewind --hidden --to 'desc("c_B0")' --as-divergence 2 new content-divergent changesets rewinded to 1 changesets $ hg debugobsolete @@ -355,3 +355,92 @@ date: Thu Jan 01 00:00:00 1970 +0000 summary: c_ROOT + $ echo 'default-date = 2 0' >> $HGRCPATH + +rewind a simple amend - obsoleting the current latest successors +---------------------------------------------------------------- + + $ hg rewind --hidden --to 'min(desc("c_B0"))' + rewinded to 1 changesets + $ hg debugobsolete + 7e594302a05d3769b27be88fc3cdfd39d7498498 25c8f5ab0c3bb569ec672570f1a901be4c6f032b 0 (Thu Jan 01 00:00:01 1970 +0000) {'ef1': '9', 'operation': 'amend', 'user': 'test'} + 7e594302a05d3769b27be88fc3cdfd39d7498498 48acf2c0d9c8961859ce9a913671eb2adc9b057b 4 (Thu Jan 01 00:00:01 1970 +0000) {'ef1': '34', 'operation': 'rewind', 'user': 'test'} + 48acf2c0d9c8961859ce9a913671eb2adc9b057b 0 {579f120ba91885449adc92eedf48ef3569742cee} (Thu Jan 01 00:00:01 1970 +0000) {'ef1': '0', 'operation': 'prune', 'user': 'test'} + 7e594302a05d3769b27be88fc3cdfd39d7498498 d8b4471cfb3caa290e0a78ae6bc57d78656c9075 4 (Thu Jan 01 00:00:02 1970 +0000) {'ef1': '34', 'operation': 'rewind', 'user': 'test'} + 25c8f5ab0c3bb569ec672570f1a901be4c6f032b d8b4471cfb3caa290e0a78ae6bc57d78656c9075 0 (Thu Jan 01 00:00:02 1970 +0000) {'ef1': '43', 'operation': 'rewind', 'user': 'test'} + $ hg obslog --rev 'desc("c_B0")' + o d8b4471cfb3c (5) c_B0 + |\ + @ | 25c8f5ab0c3b (3) c_B1 + |/ rewritten(description, meta, date, content) as d8b4471cfb3c using rewind by test (Thu Jan 01 00:00:02 1970 +0000) + | + x 7e594302a05d (2) c_B0 + rewritten(description, content) as 25c8f5ab0c3b using amend by test (Thu Jan 01 00:00:01 1970 +0000) + rewritten(meta, date) as 48acf2c0d9c8 using rewind by test (Thu Jan 01 00:00:01 1970 +0000) + rewritten(meta, date) as d8b4471cfb3c using rewind by test (Thu Jan 01 00:00:02 1970 +0000) + + $ hg log -G + o changeset: 5:d8b4471cfb3c + | tag: tip + | parent: 1:579f120ba918 + | user: test + | date: Thu Jan 01 00:00:02 1970 +0000 + | summary: c_B0 + | + | @ changeset: 3:25c8f5ab0c3b + |/ parent: 1:579f120ba918 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: rewritten using rewind as 5:d8b4471cfb3c + | summary: c_B1 + | + o changeset: 1:579f120ba918 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: c_A0 + | + o changeset: 0:eba9c2249fe7 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: c_ROOT + + $ hg log -G --hidden + o changeset: 5:d8b4471cfb3c + | tag: tip + | parent: 1:579f120ba918 + | user: test + | date: Thu Jan 01 00:00:02 1970 +0000 + | summary: c_B0 + | + | x changeset: 4:48acf2c0d9c8 + |/ parent: 1:579f120ba918 + | user: test + | date: Thu Jan 01 00:00:01 1970 +0000 + | obsolete: pruned using prune + | summary: c_B0 + | + | @ changeset: 3:25c8f5ab0c3b + |/ parent: 1:579f120ba918 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: rewritten using rewind as 5:d8b4471cfb3c + | summary: c_B1 + | + | x changeset: 2:7e594302a05d + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: rewritten using rewind as 5:d8b4471cfb3c + | obsolete: rewritten using rewind as 4:48acf2c0d9c8 + | obsolete: rewritten using amend as 3:25c8f5ab0c3b + | summary: c_B0 + | + o changeset: 1:579f120ba918 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: c_A0 + | + o changeset: 0:eba9c2249fe7 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: c_ROOT +