hgext3rd/evolve/rewind.py
author Anton Shestakov <av6@dwimlabs.net>
Thu, 07 May 2020 01:29:24 +0200
changeset 5348 a9f9edb168a1
parent 5262 678a9223aad3
permissions -rw-r--r--
obslog: add a --origin flag to show predecessors instead of successors This flag will be turned on by default in the next changeset.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     1
from __future__ import absolute_import
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     2
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
     3
import collections
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     4
import hashlib
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     5
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     6
from mercurial import (
3873
b81fd1487e04 rewing: prevent rewind in case of uncommitted changes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3872
diff changeset
     7
    cmdutil,
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     8
    error,
3863
c31be22d1d90 rewind: update the working copy if it gets obsoleted
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3862
diff changeset
     9
    hg,
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    10
    obsolete,
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    11
    obsutil,
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    12
    scmutil,
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    13
)
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    14
5178
61e49d2654cc compat: directly use function from dateutil
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5111
diff changeset
    15
from mercurial.utils import dateutil
61e49d2654cc compat: directly use function from dateutil
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5111
diff changeset
    16
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    17
from mercurial.i18n import _
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    18
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    19
from . import (
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    20
    exthelper,
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    21
    rewriteutil,
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    22
    compat,
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    23
)
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    24
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    25
eh = exthelper.exthelper()
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    26
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    27
# flag in obsolescence markers to link to identical version
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    28
identicalflag = 4
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    29
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    30
@eh.command(
4715
12c8b24757f4 py3: use byte strings for @command registrations
Martin von Zweigbergk <martinvonz@google.com>
parents: 4624
diff changeset
    31
    b'rewind|undo',
12c8b24757f4 py3: use byte strings for @command registrations
Martin von Zweigbergk <martinvonz@google.com>
parents: 4624
diff changeset
    32
    [(b'', b'to', [], _(b"rewind to these revisions"), _(b'REV')),
12c8b24757f4 py3: use byte strings for @command registrations
Martin von Zweigbergk <martinvonz@google.com>
parents: 4624
diff changeset
    33
     (b'', b'as-divergence', None, _(b"preserve current latest successors")),
12c8b24757f4 py3: use byte strings for @command registrations
Martin von Zweigbergk <martinvonz@google.com>
parents: 4624
diff changeset
    34
     (b'', b'exact', None, _(b"only rewind explicitly selected revisions")),
12c8b24757f4 py3: use byte strings for @command registrations
Martin von Zweigbergk <martinvonz@google.com>
parents: 4624
diff changeset
    35
     (b'', b'from', [],
12c8b24757f4 py3: use byte strings for @command registrations
Martin von Zweigbergk <martinvonz@google.com>
parents: 4624
diff changeset
    36
      _(b"rewind these revisions to their predecessors"), _(b'REV')),
4821
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
    37
     (b'k', b'keep', None,
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
    38
      _(b"do not modify working directory during rewind")),
4715
12c8b24757f4 py3: use byte strings for @command registrations
Martin von Zweigbergk <martinvonz@google.com>
parents: 4624
diff changeset
    39
     ],
4821
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
    40
    _(b'[--as-divergence] [--exact] [--keep] [--to REV]... [--from REV]...'),
4894
f9743b13de6d help: categorizing evolve and topic commands
Rodrigo Damazio <rdamazio@google.com>
parents: 4821
diff changeset
    41
    helpbasic=True,
f9743b13de6d help: categorizing evolve and topic commands
Rodrigo Damazio <rdamazio@google.com>
parents: 4821
diff changeset
    42
    **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    43
def rewind(ui, repo, **opts):
4091
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    44
    """rewind a stack of changesets to a previous state
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    45
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    46
    This command can be used to restore stacks of changesets to an obsolete
4091
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    47
    state, creating identical copies.
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    48
4091
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    49
    There are two main ways to select the rewind target. Rewinding "from"
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    50
    changesets will restore the direct predecessors of these changesets (and
3871
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
    51
    obsolete the changeset you rewind from). Rewinding "to" will restore the
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
    52
    changeset you have selected (and obsolete their latest successors).
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
    53
4794
7b5d08e84c4d rewind: working directory is the preferred term
Anton Shestakov <av6@dwimlabs.net>
parents: 4793
diff changeset
    54
    By default, we rewind from the working directory parents, restoring its
4091
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    55
    predecessor.
3872
bbc3cfdfe42b rewind: default to rewinding the current stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3871
diff changeset
    56
3868
1742254d1190 rewind: automatically rewind entire stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3866
diff changeset
    57
    When we rewind to an obsolete version, we also rewind to all its obsolete
4091
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    58
    ancestors. To only rewind to the explicitly selected changesets use the
3868
1742254d1190 rewind: automatically rewind entire stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3866
diff changeset
    59
    `--exact` flag. Using the `--exact` flag can restore some changesets as
1742254d1190 rewind: automatically rewind entire stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3866
diff changeset
    60
    orphan.
1742254d1190 rewind: automatically rewind entire stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3866
diff changeset
    61
4091
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    62
    The latest successors of the obsolete changesets will be superseded by
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    63
    these new copies. This behavior can be disabled using `--as-divergence`,
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    64
    the current latest successors won't be affected and content-divergence will
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    65
    appear between them and the restored version of the obsolete changesets.
3865
b945f2dae587 rewind: add a test for rewinding a fold
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3863
diff changeset
    66
4091
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    67
    Current rough edges:
3865
b945f2dae587 rewind: add a test for rewinding a fold
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3863
diff changeset
    68
b945f2dae587 rewind: add a test for rewinding a fold
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3863
diff changeset
    69
      * fold: rewinding to only some of the initially folded changesets will be
b945f2dae587 rewind: add a test for rewinding a fold
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3863
diff changeset
    70
              problematic. The fold result is marked obsolete and the part not
4091
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    71
              rewinded to are "lost".  Please use --as-divergence when you
3865
b945f2dae587 rewind: add a test for rewinding a fold
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3863
diff changeset
    72
              need to perform such operation.
3871
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
    73
4091
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    74
      * :hg:`rewind` might affect changesets outside the current stack. Without
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    75
              --exact, we also restore ancestors of the rewind target,
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    76
              obsoleting their latest successors (unless --as-divergent is
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    77
              provided). In some case, these latest successors will be on
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    78
              branches unrelated to the changeset you rewind from.
2c60ad0d54a9 rewind: fix help text (mostly grammar, but also s/precursor/predecessor)
Martin von Zweigbergk <martinvonz@google.com>
parents: 3873
diff changeset
    79
              (We plan to automatically detect this case in the future)
3871
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
    80
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    81
    """
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    82
    unfi = repo.unfiltered()
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    83
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    84
    successorsmap = collections.defaultdict(set)
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    85
    rewindmap = {}
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    86
    sscache = {}
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    87
    with repo.wlock(), repo.lock():
3873
b81fd1487e04 rewing: prevent rewind in case of uncommitted changes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3872
diff changeset
    88
        # stay on the safe side: prevent local case in case we need to upgrade
b81fd1487e04 rewing: prevent rewind in case of uncommitted changes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3872
diff changeset
    89
        cmdutil.bailifchanged(repo)
3868
1742254d1190 rewind: automatically rewind entire stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3866
diff changeset
    90
3869
bbfbaf46f7b0 rewind: move revision selection into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3868
diff changeset
    91
        rewinded = _select_rewinded(repo, opts)
3868
1742254d1190 rewind: automatically rewind entire stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3866
diff changeset
    92
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    93
        if not opts['as_divergence']:
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    94
            for rev in rewinded:
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    95
                ctx = unfi[rev]
5048
3947964a4ce7 evolve: provide cache argument to obsutil.successorssets() correctly
Anton Shestakov <av6@dwimlabs.net>
parents: 4899
diff changeset
    96
                ssets = obsutil.successorssets(repo, ctx.node(), cache=sscache)
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
    97
                if 1 < len(ssets):
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
    98
                    msg = _(b'rewind confused by divergence on %s') % ctx
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
    99
                    hint = _(b'solve divergence first or use "--as-divergence"')
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   100
                    raise error.Abort(msg, hint=hint)
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   101
                if ssets and ssets[0]:
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   102
                    for succ in ssets[0]:
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   103
                        successorsmap[succ].add(ctx.node())
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   104
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   105
        # Check that we can rewind these changesets
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   106
        with repo.transaction(b'rewind'):
4821
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   107
            oldctx = repo[b'.']
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   108
3866
de42d00d6ee2 rewind: use rewinded parent when creating multiple changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3865
diff changeset
   109
            for rev in sorted(rewinded):
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   110
                ctx = unfi[rev]
3866
de42d00d6ee2 rewind: use rewinded parent when creating multiple changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3865
diff changeset
   111
                rewindmap[ctx.node()] = _revive_revision(unfi, rev, rewindmap)
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   112
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   113
            relationships = []
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   114
            cl = unfi.changelog
3863
c31be22d1d90 rewind: update the working copy if it gets obsoleted
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3862
diff changeset
   115
            wctxp = repo[None].p1()
c31be22d1d90 rewind: update the working copy if it gets obsoleted
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3862
diff changeset
   116
            update_target = None
3861
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   117
            for (source, dest) in sorted(successorsmap.items()):
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   118
                newdest = [rewindmap[d] for d in sorted(dest, key=cl.rev)]
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   119
                rel = (unfi[source], tuple(unfi[d] for d in newdest))
bbe635dfd75c rewind: obsolete latest successors unless instructed otherwise
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3859
diff changeset
   120
                relationships.append(rel)
3863
c31be22d1d90 rewind: update the working copy if it gets obsoleted
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3862
diff changeset
   121
                if wctxp.node() == source:
c31be22d1d90 rewind: update the working copy if it gets obsoleted
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3862
diff changeset
   122
                    update_target = newdest[-1]
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   123
            obsolete.createmarkers(unfi, relationships, operation=b'rewind')
3863
c31be22d1d90 rewind: update the working copy if it gets obsoleted
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3862
diff changeset
   124
            if update_target is not None:
4821
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   125
                if opts.get('keep'):
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   126
                    hg.updaterepo(repo, oldctx, True)
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   127
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   128
                    # This is largely the same as the implementation in
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   129
                    # strip.stripcmd() and cmdrewrite.cmdprune().
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   130
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   131
                    # only reset the dirstate for files that would actually
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   132
                    # change between the working context and the revived cset
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   133
                    newctx = repo[update_target]
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   134
                    changedfiles = []
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   135
                    for ctx in [oldctx, newctx]:
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   136
                        # blindly reset the files, regardless of what actually
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   137
                        # changed
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   138
                        changedfiles.extend(ctx.files())
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   139
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   140
                    # reset files that only changed in the dirstate too
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   141
                    dirstate = repo.dirstate
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   142
                    dirchanges = [f for f in dirstate if dirstate[f] != 'n']
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   143
                    changedfiles.extend(dirchanges)
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   144
                    repo.dirstate.rebuild(newctx.node(), newctx.manifest(),
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   145
                                          changedfiles)
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   146
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   147
                    # TODO: implement restoration of copies/renames
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   148
                    # Ideally this step should be handled by dirstate.rebuild
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   149
                    # or scmutil.movedirstate, but right now there's no copy
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   150
                    # tracing across obsolescence relation (oldctx <-> newctx).
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   151
                    revertopts = {'no_backup': True, 'all': True,
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   152
                                  'rev': oldctx.node()}
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   153
                    with ui.configoverride({(b'ui', b'quiet'): True}):
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   154
                        cmdutil.revert(repo.ui, repo, oldctx,
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   155
                                       repo.dirstate.parents(), **revertopts)
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   156
                else:
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   157
                    hg.updaterepo(repo, update_target, False)
3863
c31be22d1d90 rewind: update the working copy if it gets obsoleted
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3862
diff changeset
   158
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   159
    repo.ui.status(_(b'rewinded to %d changesets\n') % len(rewinded))
3862
8d3eed113b77 rewind: add a message about obsolete changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3861
diff changeset
   160
    if relationships:
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   161
        repo.ui.status(_(b'(%d changesets obsoleted)\n') % len(relationships))
4821
d8e36e60aea0 rewind: add --keep flag that "doesn't modify working directory"
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   162
    if update_target is not None and not opts.get('keep'):
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   163
        ui.status(_(b'working directory is now at %s\n') % repo[b'.'])
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   164
3869
bbfbaf46f7b0 rewind: move revision selection into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3868
diff changeset
   165
def _select_rewinded(repo, opts):
bbfbaf46f7b0 rewind: move revision selection into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3868
diff changeset
   166
    """select the revision we shoudl rewind to
bbfbaf46f7b0 rewind: move revision selection into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3868
diff changeset
   167
    """
3871
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
   168
    unfi = repo.unfiltered()
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
   169
    rewinded = set()
3872
bbc3cfdfe42b rewind: default to rewinding the current stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3871
diff changeset
   170
    revsto = opts.get('to')
bbc3cfdfe42b rewind: default to rewinding the current stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3871
diff changeset
   171
    revsfrom = opts.get('from')
bbc3cfdfe42b rewind: default to rewinding the current stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3871
diff changeset
   172
    if not (revsto or revsfrom):
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   173
        revsfrom.append(b'.')
3872
bbc3cfdfe42b rewind: default to rewinding the current stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3871
diff changeset
   174
    if revsto:
bbc3cfdfe42b rewind: default to rewinding the current stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3871
diff changeset
   175
        rewinded.update(scmutil.revrange(repo, revsto))
bbc3cfdfe42b rewind: default to rewinding the current stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3871
diff changeset
   176
    if revsfrom:
bbc3cfdfe42b rewind: default to rewinding the current stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3871
diff changeset
   177
        succs = scmutil.revrange(repo, revsfrom)
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   178
        rewinded.update(unfi.revs(b'predecessors(%ld)', succs))
3871
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
   179
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
   180
    if not rewinded:
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   181
        raise error.Abort(b'no revision to rewind to')
3869
bbfbaf46f7b0 rewind: move revision selection into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3868
diff changeset
   182
3871
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
   183
    if not opts['exact']:
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   184
        rewinded = unfi.revs(b'obsolete() and ::%ld', rewinded)
3869
bbfbaf46f7b0 rewind: move revision selection into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3868
diff changeset
   185
3871
2e32a1ef0c60 rewing: add the ability to rewind "from" revisions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3869
diff changeset
   186
    return sorted(rewinded)
3869
bbfbaf46f7b0 rewind: move revision selection into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3868
diff changeset
   187
3866
de42d00d6ee2 rewind: use rewinded parent when creating multiple changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3865
diff changeset
   188
def _revive_revision(unfi, rev, rewindmap):
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   189
    """rewind a single revision rev.
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   190
    """
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   191
    ctx = unfi[rev]
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   192
    extra = ctx.extra().copy()
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   193
    # rewind hash should be unique over multiple rewind.
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   194
    user = unfi.ui.config(b'devel', b'user.obsmarker')
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   195
    if not user:
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   196
        user = unfi.ui.username()
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   197
    date = unfi.ui.configdate(b'devel', b'default-date')
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   198
    if date is None:
5178
61e49d2654cc compat: directly use function from dateutil
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5111
diff changeset
   199
        date = dateutil.makedate()
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   200
    noise = b"%s\0%s\0%d\0%d" % (ctx.node(), user, date[0], date[1])
5214
d7aed9675db6 rewind: make __rewind-hash__ extra field be bytes
Anton Shestakov <av6@dwimlabs.net>
parents: 5111
diff changeset
   201
    extra[b'__rewind-hash__'] = hashlib.sha256(noise).hexdigest().encode('ascii')
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   202
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   203
    p1 = ctx.p1().node()
3866
de42d00d6ee2 rewind: use rewinded parent when creating multiple changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3865
diff changeset
   204
    p1 = rewindmap.get(p1, p1)
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   205
    p2 = ctx.p2().node()
3866
de42d00d6ee2 rewind: use rewinded parent when creating multiple changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3865
diff changeset
   206
    p2 = rewindmap.get(p2, p2)
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   207
4722
7839720c7c75 rewind: make sure merge commits include files from p1 and p2
Anton Shestakov <av6@dwimlabs.net>
parents: 4715
diff changeset
   208
    updates = []
7839720c7c75 rewind: make sure merge commits include files from p1 and p2
Anton Shestakov <av6@dwimlabs.net>
parents: 4715
diff changeset
   209
    if len(ctx.parents()) > 1:
7839720c7c75 rewind: make sure merge commits include files from p1 and p2
Anton Shestakov <av6@dwimlabs.net>
parents: 4715
diff changeset
   210
        updates = ctx.parents()
4899
c982e7fb5e7a rewind: preserve date
Manuel Jacob <me@manueljacob.de>
parents: 4821
diff changeset
   211
    commitopts = {b'extra': extra, b'date': ctx.date()}
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   212
4722
7839720c7c75 rewind: make sure merge commits include files from p1 and p2
Anton Shestakov <av6@dwimlabs.net>
parents: 4715
diff changeset
   213
    new, unusedvariable = rewriteutil.rewrite(unfi, ctx, updates, ctx,
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   214
                                              [p1, p2],
4899
c982e7fb5e7a rewind: preserve date
Manuel Jacob <me@manueljacob.de>
parents: 4821
diff changeset
   215
                                              commitopts=commitopts)
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   216
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   217
    obsolete.createmarkers(unfi, [(ctx, (unfi[new],))],
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4794
diff changeset
   218
                           flag=identicalflag, operation=b'rewind')
3858
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   219
bb4f5ad63877 rewind: add a proto version of the command
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   220
    return new