mercurial/rewriteutil.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Wed, 07 Jul 2021 19:32:22 +0200
changeset 47590 c5190adc17d5
parent 47553 debc29900b97
child 47787 48da5c325750
permissions -rw-r--r--
dirstate: introduce an internal `_remove` method We want to split current user of `dirstate.remove` between `hg rm`-like cases and update of the dirstate coming from update/merge. To do this we will introduce new API. The first step is to introduces an internal function that these new API migh use (or not use) to distinct between the migrated users and the others. Differential Revision: https://phab.mercurial-scm.org/D11011
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
35242
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
     1
# rewriteutil.py - utility functions for rewriting changesets
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
     2
#
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
     3
# Copyright 2017 Octobus <contact@octobus.net>
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
     4
#
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
     7
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
     8
from __future__ import absolute_import
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
     9
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
    10
import re
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
    11
35243
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    12
from .i18n import _
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45853
diff changeset
    13
from .node import (
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45853
diff changeset
    14
    hex,
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45853
diff changeset
    15
    nullrev,
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45853
diff changeset
    16
)
35243
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    17
35242
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
    18
from . import (
35243
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    19
    error,
47069
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    20
    node,
35242
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
    21
    obsolete,
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
    22
    obsutil,
35242
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
    23
    revset,
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
    24
    scmutil,
47016
8ad2f43fe37b rewriteutil: add devel warning if precheck is called with contexts
Martin von Zweigbergk <martinvonz@google.com>
parents: 47015
diff changeset
    25
    util,
35242
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
    26
)
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
    27
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 40636
diff changeset
    28
45427
78861610ded8 rewriteutil: relax the sha1 hash references to handle future hash types
Matt Harbison <matt_harbison@yahoo.com>
parents: 45425
diff changeset
    29
NODE_RE = re.compile(br'\b[0-9a-f]{6,64}\b')
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
    30
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
    31
47069
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    32
def _formatrevs(repo, revs, maxrevs=4):
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    33
    """returns a string summarizing revisions in a decent size
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    34
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    35
    If there are few enough revisions, we list them all. Otherwise we display a
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    36
    summary of the form:
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    37
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    38
        1ea73414a91b and 5 others
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    39
    """
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    40
    tonode = repo.changelog.node
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    41
    numrevs = len(revs)
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    42
    if numrevs < maxrevs:
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    43
        shorts = [node.short(tonode(r)) for r in revs]
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    44
        summary = b', '.join(shorts)
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    45
    else:
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    46
        first = revs.first()
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    47
        summary = _(b'%s and %d others')
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    48
        summary %= (node.short(tonode(first)), numrevs - 1)
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    49
    return summary
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    50
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    51
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    52
def precheck(repo, revs, action=b'rewrite'):
35243
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    53
    """check if revs can be rewritten
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    54
    action is used to control the error message.
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    55
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    56
    Make sure this function is called after taking the lock.
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    57
    """
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45853
diff changeset
    58
    if nullrev in revs:
47015
7001f92e0ee9 rewriteutil: replace "null changeset" by "the null revision" in error message
Martin von Zweigbergk <martinvonz@google.com>
parents: 46113
diff changeset
    59
        msg = _(b"cannot %s the null revision") % action
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    60
        hint = _(b"no changeset checked out")
45853
b4694ef45db5 errors: raise more specific errors from rewriteutil
Martin von Zweigbergk <martinvonz@google.com>
parents: 45711
diff changeset
    61
        raise error.InputError(msg, hint=hint)
35243
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    62
47016
8ad2f43fe37b rewriteutil: add devel warning if precheck is called with contexts
Martin von Zweigbergk <martinvonz@google.com>
parents: 47015
diff changeset
    63
    if any(util.safehasattr(r, 'rev') for r in revs):
8ad2f43fe37b rewriteutil: add devel warning if precheck is called with contexts
Martin von Zweigbergk <martinvonz@google.com>
parents: 47015
diff changeset
    64
        repo.ui.develwarn(b"rewriteutil.precheck called with ctx not revs")
8ad2f43fe37b rewriteutil: add devel warning if precheck is called with contexts
Martin von Zweigbergk <martinvonz@google.com>
parents: 47015
diff changeset
    65
        revs = (r.rev() for r in revs)
8ad2f43fe37b rewriteutil: add devel warning if precheck is called with contexts
Martin von Zweigbergk <martinvonz@google.com>
parents: 47015
diff changeset
    66
35243
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    67
    if len(repo[None].parents()) > 1:
47020
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    68
        raise error.StateError(
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    69
            _(b"cannot %s changesets while merging") % action
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    70
        )
35243
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    71
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    72
    publicrevs = repo.revs(b'%ld and public()', revs)
35243
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    73
    if publicrevs:
47069
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    74
        summary = _formatrevs(repo, publicrevs)
5b6dd0d9171b rewriteutil: give examples of public changesets that can't be rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47020
diff changeset
    75
        msg = _(b"cannot %s public changesets: %s") % (action, summary)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    76
        hint = _(b"see 'hg help phases' for details")
45853
b4694ef45db5 errors: raise more specific errors from rewriteutil
Martin von Zweigbergk <martinvonz@google.com>
parents: 45711
diff changeset
    77
        raise error.InputError(msg, hint=hint)
35243
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    78
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    79
    newunstable = disallowednewunstable(repo, revs)
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    80
    if newunstable:
47018
7a90fddb13b0 rewriteutil: point to help about instability when rewriting creates orphan
Martin von Zweigbergk <martinvonz@google.com>
parents: 47016
diff changeset
    81
        hint = _(b"see 'hg help evolution.instability'")
7a90fddb13b0 rewriteutil: point to help about instability when rewriting creates orphan
Martin von Zweigbergk <martinvonz@google.com>
parents: 47016
diff changeset
    82
        raise error.InputError(
47070
d90f6237b3aa rewriteutil: say how many commits would become orphan if commit is rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47069
diff changeset
    83
            _(b"cannot %s changeset, as that will orphan %d descendants")
d90f6237b3aa rewriteutil: say how many commits would become orphan if commit is rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47069
diff changeset
    84
            % (action, len(newunstable)),
d90f6237b3aa rewriteutil: say how many commits would become orphan if commit is rewritten
Martin von Zweigbergk <martinvonz@google.com>
parents: 47069
diff changeset
    85
            hint=hint,
47018
7a90fddb13b0 rewriteutil: point to help about instability when rewriting creates orphan
Martin von Zweigbergk <martinvonz@google.com>
parents: 47016
diff changeset
    86
        )
35243
490df753894d rewriteutil: add a precheck function to check if revs can be rewritten
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35242
diff changeset
    87
47020
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    88
    if not obsolete.isenabled(repo, obsolete.allowdivergenceopt):
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    89
        new_divergence = _find_new_divergence(repo, revs)
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    90
        if new_divergence:
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    91
            local_ctx, other_ctx, base_ctx = new_divergence
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    92
            msg = _(
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    93
                b'cannot %s %s, as that creates content-divergence with %s'
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    94
            ) % (
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    95
                action,
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    96
                local_ctx,
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    97
                other_ctx,
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    98
            )
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
    99
            if local_ctx.rev() != base_ctx.rev():
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   100
                msg += _(b', from %s') % base_ctx
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   101
            if repo.ui.verbose:
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   102
                if local_ctx.rev() != base_ctx.rev():
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   103
                    msg += _(
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   104
                        b'\n    changeset %s is a successor of ' b'changeset %s'
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   105
                    ) % (local_ctx, base_ctx)
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   106
                msg += _(
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   107
                    b'\n    changeset %s already has a successor in '
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   108
                    b'changeset %s\n'
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   109
                    b'    rewriting changeset %s would create '
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   110
                    b'"content-divergence"\n'
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   111
                    b'    set experimental.evolution.allowdivergence=True to '
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   112
                    b'skip this check'
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   113
                ) % (base_ctx, other_ctx, local_ctx)
47375
8125bcd28a5c rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47271
diff changeset
   114
                raise error.InputError(
8125bcd28a5c rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47271
diff changeset
   115
                    msg,
8125bcd28a5c rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47271
diff changeset
   116
                    hint=_(
8125bcd28a5c rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47271
diff changeset
   117
                        b"see 'hg help evolution.instability' for details on content-divergence"
8125bcd28a5c rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47271
diff changeset
   118
                    ),
8125bcd28a5c rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47271
diff changeset
   119
                )
47020
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   120
            else:
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   121
                raise error.InputError(
47271
055f7b9f2307 rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47070
diff changeset
   122
                    msg,
055f7b9f2307 rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47070
diff changeset
   123
                    hint=_(
055f7b9f2307 rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47070
diff changeset
   124
                        b"add --verbose for details or see "
055f7b9f2307 rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47070
diff changeset
   125
                        b"'hg help evolution.instability'"
055f7b9f2307 rewriteutil: add pointer to help text when rewrite would cause divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47070
diff changeset
   126
                    ),
47020
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   127
                )
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   128
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 40636
diff changeset
   129
35242
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
   130
def disallowednewunstable(repo, revs):
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
   131
    """Checks whether editing the revs will create new unstable changesets and
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
   132
    are we allowed to create them.
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
   133
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
   134
    To allow new unstable changesets, set the config:
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
   135
        `experimental.evolution.allowunstable=True`
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
   136
    """
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
   137
    allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
   138
    if allowunstable:
27d5c2d2db2b rewriteutil: add utility function to check if we can create new unstable cset
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff changeset
   139
        return revset.baseset()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
   140
    return repo.revs(b"(%ld::) - %ld", revs, revs)
45122
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   141
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   142
47020
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   143
def _find_new_divergence(repo, revs):
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   144
    obsrevs = repo.revs(b'%ld and obsolete()', revs)
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   145
    for r in obsrevs:
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   146
        div = find_new_divergence_from(repo, repo[r])
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   147
        if div:
47553
debc29900b97 rewriteutil: look up common predecessor on unfiltered repo
Martin von Zweigbergk <martinvonz@google.com>
parents: 47375
diff changeset
   148
            return (repo[r], repo[div[0]], repo.unfiltered()[div[1]])
47020
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   149
    return None
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   150
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   151
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   152
def find_new_divergence_from(repo, ctx):
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   153
    """return divergent revision if rewriting an obsolete cset (ctx) will
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   154
    create divergence
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   155
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   156
    Returns (<other node>, <common ancestor node>) or None
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   157
    """
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   158
    if not ctx.obsolete():
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   159
        return None
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   160
    # We need to check two cases that can cause divergence:
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   161
    # case 1: the rev being rewritten has a non-obsolete successor (easily
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   162
    #     detected by successorssets)
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   163
    sset = obsutil.successorssets(repo, ctx.node())
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   164
    if sset:
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   165
        return (sset[0][0], ctx.node())
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   166
    else:
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   167
        # case 2: one of the precursors of the rev being revived has a
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   168
        #     non-obsolete successor (we need divergentsets for this)
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   169
        divsets = obsutil.divergentsets(repo, ctx)
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   170
        if divsets:
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   171
            nsuccset = divsets[0][b'divergentnodes']
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   172
            prec = divsets[0][b'commonpredecessor']
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   173
            return (nsuccset[0], prec)
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   174
        return None
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   175
ba6881c6a178 rewriteutil: check for divergence
Martin von Zweigbergk <martinvonz@google.com>
parents: 47019
diff changeset
   176
45122
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   177
def skip_empty_successor(ui, command):
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   178
    empty_successor = ui.config(b'rewrite', b'empty-successor')
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   179
    if empty_successor == b'skip':
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   180
        return True
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   181
    elif empty_successor == b'keep':
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   182
        return False
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   183
    else:
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   184
        raise error.ConfigError(
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   185
            _(
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   186
                b"%s doesn't know how to handle config "
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   187
                b"rewrite.empty-successor=%s (only 'skip' and 'keep' are "
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   188
                b"supported)"
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   189
            )
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   190
            % (command, empty_successor)
a391d0710f22 rewriteutil: add utility to check whether empty successors should be skipped
Manuel Jacob <me@manueljacob.de>
parents: 43077
diff changeset
   191
        )
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   192
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   193
45425
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   194
def update_hash_refs(repo, commitmsg, pending=None):
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   195
    """Replace all obsolete commit hashes in the message with the current hash.
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   196
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   197
    If the obsolete commit was split or is divergent, the hash is not replaced
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   198
    as there's no way to know which successor to choose.
45425
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   199
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   200
    For commands that update a series of commits in the current transaction, the
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   201
    new obsolete markers can be considered by setting ``pending`` to a mapping
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   202
    of ``pending[oldnode] = [successor_node1, successor_node2,..]``.
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   203
    """
45425
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   204
    if not pending:
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   205
        pending = {}
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   206
    cache = {}
45427
78861610ded8 rewriteutil: relax the sha1 hash references to handle future hash types
Matt Harbison <matt_harbison@yahoo.com>
parents: 45425
diff changeset
   207
    hashes = re.findall(NODE_RE, commitmsg)
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   208
    unfi = repo.unfiltered()
45427
78861610ded8 rewriteutil: relax the sha1 hash references to handle future hash types
Matt Harbison <matt_harbison@yahoo.com>
parents: 45425
diff changeset
   209
    for h in hashes:
78861610ded8 rewriteutil: relax the sha1 hash references to handle future hash types
Matt Harbison <matt_harbison@yahoo.com>
parents: 45425
diff changeset
   210
        fullnode = scmutil.resolvehexnodeidprefix(unfi, h)
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   211
        if fullnode is None:
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   212
            continue
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   213
        ctx = unfi[fullnode]
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   214
        if not ctx.obsolete():
45425
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   215
            successors = pending.get(fullnode)
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   216
            if successors is None:
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   217
                continue
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   218
            # obsutil.successorssets() returns a list of list of nodes
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   219
            successors = [successors]
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   220
        else:
f7e293e0475f rewriteutil: also consider pending obsoletes when updating hashes in messages
Matt Harbison <matt_harbison@yahoo.com>
parents: 45424
diff changeset
   221
            successors = obsutil.successorssets(repo, ctx.node(), cache=cache)
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   222
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   223
        # We can't make any assumptions about how to update the hash if the
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   224
        # cset in question was split or diverged.
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   225
        if len(successors) == 1 and len(successors[0]) == 1:
45711
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   226
            successor = successors[0][0]
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   227
            if successor is not None:
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45853
diff changeset
   228
                newhash = hex(successor)
45711
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   229
                commitmsg = commitmsg.replace(h, newhash[: len(h)])
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   230
            else:
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   231
                repo.ui.note(
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   232
                    _(
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   233
                        b'The stale commit message reference to %s could '
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   234
                        b'not be updated\n(The referenced commit was dropped)\n'
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   235
                    )
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   236
                    % h
3d68b47e461b rewriteutil: handle dropped commits when updating description hashes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45427
diff changeset
   237
                )
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   238
        else:
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   239
            repo.ui.note(
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   240
                _(
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   241
                    b'The stale commit message reference to %s could '
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   242
                    b'not be updated\n'
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   243
                )
45427
78861610ded8 rewriteutil: relax the sha1 hash references to handle future hash types
Matt Harbison <matt_harbison@yahoo.com>
parents: 45425
diff changeset
   244
                % h
45424
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   245
            )
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   246
0a57ef4b3bdb rewriteutil: extract evolve code used to replace obsolete hashes in commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45122
diff changeset
   247
    return commitmsg