view hgext/amend.py @ 42456:87a34c767384

merge: fix race that could cause wrong size in dirstate The problem is that hg merge/update/etc work the following way: 1. figure out what files to update 2. apply the update to disk 3. apply the update to in-memory dirstate 4. write dirstate where step3 looks at the filesystem and assumes it sees the result of step2. If a file is changed between step2 and step3, step3 will record incorrect information in the dirstate. I avoid this by passing the size step3 needs directly from step2, for the common path (not implemented for change/delete conflicts for instance). I didn't fix the same race for the exec bit for now, because it's less likely to be problematic and I had trouble due to the fact that the dirstate stores the permissions differently from the manifest (st_mode vs '' 'l' 'x'), in combination with tests that pretend that symlinks are not supported. However, I moved the lstat from step3 to step2, which should tighten the race window markedly, both for the exec bit and for the mtime. Differential Revision: https://phab.mercurial-scm.org/D6475
author Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
date Mon, 27 May 2019 16:55:46 -0400
parents 4145fd3569c3
children e4803231f538
line wrap: on
line source

# 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')),
     ('D', 'currentdate', None,
      _('record the current date as commit date')),
    ] + cmdutil.walkopts + cmdutil.commitopts + cmdutil.commitopts2,
    _('[OPTION]... [FILE]...'),
    helpcategory=command.CATEGORY_COMMITTING,
    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))