##// END OF EJS Templates
procutil: make stream detection in make_line_buffered more correct and strict...
procutil: make stream detection in make_line_buffered more correct and strict In make_line_buffered(), we don’t want to wrap the stream if we know that lines get flushed to the underlying raw stream already. Previously, the heuristic was too optimistic. It assumed that any stream which is not an instance of io.BufferedIOBase doesn’t need wrapping. However, there are buffered streams that aren’t instances of io.BufferedIOBase, like Mercurial’s own winstdout. The new logic is different in two ways: First, only for the check, if unwraps any combination of WriteAllWrapper and winstdout. Second, it skips wrapping the stream only if it is an instance of io.RawIOBase (or already wrapped). If it is an instance of io.BufferedIOBase, it gets wrapped. In any other case, the function raises an exception. This ensures that, if an unknown stream is passed or we add another wrapper in the future, we don’t wrap the stream if it’s already line buffered or not wrap the stream if it’s not line buffered. In fact, this was already helpful during development of this change. Without it, I possibly would have forgot that WriteAllWrapper needs to be ignored for the check, leading to unnecessary wrapping if stdout is unbuffered. The alternative would have been to always wrap unknown streams. However, I don’t think that anyone would benefit from being less strict. We can expect streams from the standard library to be subclassing either io.RawIOBase or io.BufferedIOBase, so running Mercurial in the standard way should not regress by this change. Py2exe might replace sys.stdout and sys.stderr, but that currently breaks Mercurial anyway and also these streams don’t claim to be interactive, so this function is not called for them.

File last commit:

r49730:6000f5b2 default
r50273:094a5fa3 6.2 stable
Show More
closehead.py
94 lines | 2.7 KiB | text/x-python | PythonLexer
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029 # closehead.py - Close arbitrary heads without checking them out first
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
'''close arbitrary heads without checking them out first'''
from mercurial.i18n import _
from mercurial import (
bookmarks,
cmdutil,
context,
error,
Martin von Zweigbergk
errors: raise InputError from revsingle() iff revset provided by the user...
r48930 logcmdutil,
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029 pycompat,
registrar,
)
cmdtable = {}
command = registrar.command(cmdtable)
# 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.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 testedwith = b'ships-with-hg-core'
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029
commitopts = cmdutil.commitopts
commitopts2 = cmdutil.commitopts2
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 commitopts3 = [(b'r', b'rev', [], _(b'revision to check'), _(b'REV'))]
Augie Fackler
formatting: blacken the codebase...
r43346
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029
Augie Fackler
formatting: blacken the codebase...
r43346 @command(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'close-head|close-heads',
Augie Fackler
formatting: blacken the codebase...
r43346 commitopts + commitopts2 + commitopts3,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'[OPTION]... [REV]...'),
rdamazio@google.com
help: assigning categories to existing commands...
r40329 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
Augie Fackler
formatting: blacken the codebase...
r43346 inferrepo=True,
)
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029 def close_branch(ui, repo, *revs, **opts):
"""close the given head revisions
This is equivalent to checking out each revision in a clean tree and running
``hg commit --close-branch``, except that it doesn't change the working
directory.
The commit message must be specified with -l or -m.
"""
Augie Fackler
formatting: blacken the codebase...
r43346
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029 def docommit(rev):
Augie Fackler
formatting: blacken the codebase...
r43346 cctx = context.memctx(
repo,
parents=[rev, None],
text=message,
files=[],
filectxfn=None,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 user=opts.get(b'user'),
date=opts.get(b'date'),
Augie Fackler
formatting: blacken the codebase...
r43346 extra=extra,
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tr = repo.transaction(b'commit')
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029 ret = repo.commitctx(cctx, True)
bookmarks.update(repo, [rev, None], ret)
cctx.markcommitted(ret)
tr.close()
opts = pycompat.byteskwargs(opts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 revs += tuple(opts.get(b'rev', []))
Martin von Zweigbergk
errors: raise InputError on bad revset to revrange() iff provided by the user...
r48928 revs = logcmdutil.revrange(repo, revs)
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029
if not revs:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'no revisions specified'))
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029
heads = []
for branch in repo.branchmap():
heads.extend(repo.branchheads(branch))
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 heads = {repo[h].rev() for h in heads}
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029 for rev in revs:
if rev not in heads:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'revision is not an open head: %d') % rev)
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029
message = cmdutil.logmessage(ui, opts)
if not message:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"no commit message specified with -l or -m"))
extra = {b'close': b'1'}
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029
with repo.wlock(), repo.lock():
for rev in revs:
r = repo[rev]
branch = r.branch()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extra[b'branch'] = branch
Joerg Sonnenberger
extensions: new closehead module for closing arbitrary heads...
r40029 docommit(r)
return 0