hgext/amend.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sat, 10 Mar 2018 10:48:34 -0800
changeset 36854 290fc4c3d1e0
parent 34970 3e549546a6e9
child 40293 c303d65d2e34
permissions -rw-r--r--
hgweb: use a capped reader for WSGI input stream Per PEP 3333, the input stream from WSGI should respect EOF and prevent reads past the end of the request body. However, not all WSGI servers guarantee this. Notably, our BaseHTTPServer based built-in HTTP server doesn't. Instead, it exposes the raw socket and you can read() from it all you want, getting the connection in a bad state by doing so. We have a "cappedreader" utility class that proxies a file object and prevents reading past a limit. This commit converts the WSGI input stream into a capped reader when the input length is advertised via Content-Length headers. "cappedreader" only exposes a read() method. PEP 3333 states that the input stream MUST also support readline(), readlines(hint), and __iter__(). However, since our WSGI application code only calls read() and since we're not manipulating the stream exposed by the WSGI server, we're not violating the spec here. Differential Revision: https://phab.mercurial-scm.org/D2768

# amend.py - provide the amend command
#
# Copyright 2017 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.
"""provide the amend command (EXPERIMENTAL)

This extension provides an ``amend`` command that is similar to
``commit --amend`` but does not prompt an editor.
"""

from __future__ import absolute_import

from mercurial.i18n import _
from mercurial import (
    cmdutil,
    commands,
    error,
    pycompat,
    registrar,
)

# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
# leave the attribute unspecified.
testedwith = 'ships-with-hg-core'

cmdtable = {}
command = registrar.command(cmdtable)

@command('amend',
    [('A', 'addremove', None,
      _('mark new/missing files as added/removed before committing')),
     ('e', 'edit', None, _('invoke editor on commit messages')),
     ('i', 'interactive', None, _('use interactive mode')),
     ('n', 'note', '', _('store a note on the amend')),
    ] + cmdutil.walkopts + cmdutil.commitopts + cmdutil.commitopts2,
    _('[OPTION]... [FILE]...'),
    inferrepo=True)
def amend(ui, repo, *pats, **opts):
    """amend the working copy parent with all or specified outstanding changes

    Similar to :hg:`commit --amend`, but reuse the commit message without
    invoking editor, unless ``--edit`` was set.

    See :hg:`help commit` for more details.
    """
    opts = pycompat.byteskwargs(opts)
    if len(opts['note']) > 255:
        raise error.Abort(_("cannot store a note of more than 255 bytes"))
    with repo.wlock(), repo.lock():
        if not opts.get('logfile'):
            opts['message'] = opts.get('message') or repo['.'].description()
        opts['amend'] = True
        return commands._docommit(ui, repo, *pats, **pycompat.strkwargs(opts))