hgext/commitextras.py
author Martin von Zweigbergk <martinvonz@google.com>
Fri, 05 Oct 2018 11:07:34 -0700
changeset 40344 2c5835b4246b
parent 39295 3a60416c4fd8
child 41532 bd3f03d8cc9f
permissions -rw-r--r--
narrow: when widening, don't include manifests the client already has When widening, we already don't include the changelog (since f1844a10ee19) and files that the client already has (since c73c7653dfb9). However, we still include all manifests needed for the new narrowspec. When using flat manifests, that means we resend all the manifests even though the client necessarily has all of them. For tree manifests, we unnecessarily resend the root manifests and any subdirectory manifests that the client already has. This patch makes it so we no longer resend manifests that the client already has. It does so by passing an extra matcher to the changegroup packer and it uses that for filtering out directories matching the old matcher's visitdir(). For consistency between directories and files, it also makes the filtering of files look at both old and new matcher rather than passing in a diff matcher as we did before. Differential Revision: https://phab.mercurial-scm.org/D4895

# 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 = 'ships-with-hg-core'

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

def extsetup(ui):
    entry = extensions.wrapcommand(commands.table, 'commit', _commit)
    options = entry[1]
    options.append(('', 'extra', [],
        _('set a changeset\'s extra values'), _("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(r'extra')
            for raw in extras:
                if '=' not in raw:
                    msg = _("unable to parse '%s', should follow "
                            "KEY=VALUE format")
                    raise error.Abort(msg % raw)
                k, v = raw.split('=', 1)
                if not k:
                    msg = _("unable to parse '%s', keys can't be empty")
                    raise error.Abort(msg % raw)
                if re.search('[^\w-]', k):
                    msg = _("keys can only contain ascii letters, digits,"
                            " '_' and '-'")
                    raise error.Abort(msg)
                if k in usedinternally:
                    msg = _("key '%s' is used internally, can't be set "
                            "manually")
                    raise error.Abort(msg % k)
                inneropts[r'extra'][k] = v
            return super(repoextra, self).commit(*innerpats, **inneropts)
    repo.__class__ = repoextra
    return orig(ui, repo, *pats, **opts)