hgext/commitextras.py
author Joerg Sonnenberger <joerg@bec.de>
Fri, 30 Apr 2021 02:11:58 +0200
changeset 47043 12450fbea288
parent 43506 9f70512ae2cf
child 48370 45a073af50a2
permissions -rw-r--r--
manifests: push down expected node length into the parser This strictly enforces the node length in the manifest lines according to what the repository expects. One test case moves large hash testing into the non-treemanifest part as treemanifests don't provide an interface for overriding just the node length for now. Differential Revision: https://phab.mercurial-scm.org/D10533

# commitextras.py
#
# Copyright 2013 Facebook, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

'''adds a new flag extras to commit (ADVANCED)'''

from __future__ import absolute_import

import re

from mercurial.i18n import _
from mercurial import (
    commands,
    error,
    extensions,
    registrar,
    util,
)

cmdtable = {}
command = registrar.command(cmdtable)
testedwith = b'ships-with-hg-core'

usedinternally = {
    b'amend_source',
    b'branch',
    b'close',
    b'histedit_source',
    b'topic',
    b'rebase_source',
    b'intermediate-source',
    b'__touch-noise__',
    b'source',
    b'transplant_source',
}


def extsetup(ui):
    entry = extensions.wrapcommand(commands.table, b'commit', _commit)
    options = entry[1]
    options.append(
        (
            b'',
            b'extra',
            [],
            _(b'set a changeset\'s extra values'),
            _(b"KEY=VALUE"),
        )
    )


def _commit(orig, ui, repo, *pats, **opts):
    if util.safehasattr(repo, 'unfiltered'):
        repo = repo.unfiltered()

    class repoextra(repo.__class__):
        def commit(self, *innerpats, **inneropts):
            extras = opts.get('extra')
            for raw in extras:
                if b'=' not in raw:
                    msg = _(
                        b"unable to parse '%s', should follow "
                        b"KEY=VALUE format"
                    )
                    raise error.Abort(msg % raw)
                k, v = raw.split(b'=', 1)
                if not k:
                    msg = _(b"unable to parse '%s', keys can't be empty")
                    raise error.Abort(msg % raw)
                if re.search(br'[^\w-]', k):
                    msg = _(
                        b"keys can only contain ascii letters, digits,"
                        b" '_' and '-'"
                    )
                    raise error.Abort(msg)
                if k in usedinternally:
                    msg = _(
                        b"key '%s' is used internally, can't be set "
                        b"manually"
                    )
                    raise error.Abort(msg % k)
                inneropts['extra'][k] = v
            return super(repoextra, self).commit(*innerpats, **inneropts)

    repo.__class__ = repoextra
    return orig(ui, repo, *pats, **opts)