view mercurial/rewriteutil.py @ 45755:8ed69bd42f10 stable

demandimport: don't raise AttributeError if `exec_module` is missing I assume this was meant to do the check gracefully. After shoveling a bunch of modules into the ignore list in order to get keyring to work out of the box on CentOS 8, I hit the following error accessing the password, which the change fixes. Now the SecretStorage backend works out of the box, without any edits to the ignore list. ** Unknown exception encountered with possibly-broken third-party extension mercurial_keyring ** which supports versions unknown of Mercurial. ** Please disable mercurial_keyring and try your action again. ** If that fixes the bug please report it to https://foss.heptapod.net/mercurial/mercurial_keyring/issues ** Python 3.6.8 (default, Apr 16 2020, 01:36:27) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)] ** Mercurial Distributed SCM (version 5.5.2) ** Extensions loaded: evolve, topic, rebase, absorb, mercurial_keyring Traceback (most recent call last): File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/mercurial_keyring.py", line 230, in _read_password_from_keyring password = keyring.get_password(KEYRING_SERVICE, pwdkey) File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/keyring/core.py", line 53, in get_password return _keyring_backend.get_password(service_name, username) File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/keyring/backends/chainer.py", line 51, in get_password password = keyring.get_password(service, username) File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/keyring/backends/SecretService.py", line 79, in get_password return item.get_secret().decode('utf-8') File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/secretstorage/item.py", line 105, in get_secret decryptor = Cipher(aes, modes.CBC(aes_iv), default_backend()).decryptor() File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/cryptography/hazmat/backends/__init__.py", line 15, in default_backend from cryptography.hazmat.backends.openssl.backend import backend File "<frozen importlib._bootstrap>", line 971, in _find_and_load File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 665, in _load_unlocked File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/hgdemandimport/demandimportpy3.py", line 53, in exec_module self.loader.exec_module(module) File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/__init__.py", line 7, in <module> from cryptography.hazmat.backends.openssl.backend import backend File "<frozen importlib._bootstrap>", line 971, in _find_and_load File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 665, in _load_unlocked File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/hgdemandimport/demandimportpy3.py", line 53, in exec_module self.loader.exec_module(module) File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 14, in <module> from six.moves import range File "<frozen importlib._bootstrap>", line 971, in _find_and_load File "<frozen importlib._bootstrap>", line 951, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 894, in _find_spec File "/home/mharbison/hg_py3.6.8_venv/lib64/python3.6/site-packages/hgdemandimport/demandimportpy3.py", line 117, in find_spec and getattr(spec.loader, "exec_module") AttributeError: '_SixMetaPathImporter' object has no attribute 'exec_module' Differential Revision: https://phab.mercurial-scm.org/D9243
author Matt Harbison <matt_harbison@yahoo.com>
date Thu, 22 Oct 2020 18:38:41 -0400
parents 3d68b47e461b
children b4694ef45db5
line wrap: on
line source

# rewriteutil.py - utility functions for rewriting changesets
#
# Copyright 2017 Octobus <contact@octobus.net>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

from __future__ import absolute_import

import re

from .i18n import _

from . import (
    error,
    node,
    obsolete,
    obsutil,
    revset,
    scmutil,
)


NODE_RE = re.compile(br'\b[0-9a-f]{6,64}\b')


def precheck(repo, revs, action=b'rewrite'):
    """check if revs can be rewritten
    action is used to control the error message.

    Make sure this function is called after taking the lock.
    """
    if node.nullrev in revs:
        msg = _(b"cannot %s null changeset") % action
        hint = _(b"no changeset checked out")
        raise error.Abort(msg, hint=hint)

    if len(repo[None].parents()) > 1:
        raise error.Abort(_(b"cannot %s while merging") % action)

    publicrevs = repo.revs(b'%ld and public()', revs)
    if publicrevs:
        msg = _(b"cannot %s public changesets") % action
        hint = _(b"see 'hg help phases' for details")
        raise error.Abort(msg, hint=hint)

    newunstable = disallowednewunstable(repo, revs)
    if newunstable:
        raise error.Abort(_(b"cannot %s changeset with children") % action)


def disallowednewunstable(repo, revs):
    """Checks whether editing the revs will create new unstable changesets and
    are we allowed to create them.

    To allow new unstable changesets, set the config:
        `experimental.evolution.allowunstable=True`
    """
    allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
    if allowunstable:
        return revset.baseset()
    return repo.revs(b"(%ld::) - %ld", revs, revs)


def skip_empty_successor(ui, command):
    empty_successor = ui.config(b'rewrite', b'empty-successor')
    if empty_successor == b'skip':
        return True
    elif empty_successor == b'keep':
        return False
    else:
        raise error.ConfigError(
            _(
                b"%s doesn't know how to handle config "
                b"rewrite.empty-successor=%s (only 'skip' and 'keep' are "
                b"supported)"
            )
            % (command, empty_successor)
        )


def update_hash_refs(repo, commitmsg, pending=None):
    """Replace all obsolete commit hashes in the message with the current hash.

    If the obsolete commit was split or is divergent, the hash is not replaced
    as there's no way to know which successor to choose.

    For commands that update a series of commits in the current transaction, the
    new obsolete markers can be considered by setting ``pending`` to a mapping
    of ``pending[oldnode] = [successor_node1, successor_node2,..]``.
    """
    if not pending:
        pending = {}
    cache = {}
    hashes = re.findall(NODE_RE, commitmsg)
    unfi = repo.unfiltered()
    for h in hashes:
        fullnode = scmutil.resolvehexnodeidprefix(unfi, h)
        if fullnode is None:
            continue
        ctx = unfi[fullnode]
        if not ctx.obsolete():
            successors = pending.get(fullnode)
            if successors is None:
                continue
            # obsutil.successorssets() returns a list of list of nodes
            successors = [successors]
        else:
            successors = obsutil.successorssets(repo, ctx.node(), cache=cache)

        # We can't make any assumptions about how to update the hash if the
        # cset in question was split or diverged.
        if len(successors) == 1 and len(successors[0]) == 1:
            successor = successors[0][0]
            if successor is not None:
                newhash = node.hex(successor)
                commitmsg = commitmsg.replace(h, newhash[: len(h)])
            else:
                repo.ui.note(
                    _(
                        b'The stale commit message reference to %s could '
                        b'not be updated\n(The referenced commit was dropped)\n'
                    )
                    % h
                )
        else:
            repo.ui.note(
                _(
                    b'The stale commit message reference to %s could '
                    b'not be updated\n'
                )
                % h
            )

    return commitmsg