select() is a notable example of syscalls which may fail with EINTR. If we
had a SIGWINCH handler installed, ssh would crash when the terminal window
was resized. This patch fixes the problem.
sys.platform returns unicode on python 3 world. Our code base has most of the
things bytes because of the transformer. So we have a bytes version of this as
pycompat.sysplatform. This series of 2 patches replaces occurences of
sys.platform with pycompat.sysplatform.
os.environ is a dictionary which has string elements on Python 3. We have
encoding.environ which take care of all these things. This is the first patch
of 5 patch series which tend to replace the occurences of os.environ with
encoding.environ as using os.environ will result in unusual behaviour.
os.pathsep returns unicode on Python 3. We already have pycompat.ospathsep
which return bytes on Python 3. This patch replaces all the occurrences of
os.pathsep in the codebase (excluding tests) to pycompat.ospathsep.
The NamedTemporaryFile file is cleared up so checklink ends up as a dangling
symlink, causing cp -r in tests to complain on both Solaris and OS X. Use
a permanent file instead when there is a .hg/cache directory.
util.checklink would create a symlink and remove it again. That would sometimes
happen multiple times. Write operations are relatively expensive and give disk
tear and noise for applications monitoring file system activity.
Instead of creating a symlink and deleting it again, just create it once and
leave it in .hg/cache/check-link . If the file exists, just verify that
os.islink reports true. We will assume that this check is as good as symlink
creation not failing.
Note: The symlink left in .hg/cache has to resolve to a file - otherwise 'make
dist' will fail ...
test-symlink-os-yes-fs-no.py does some monkey patching to simulate a platform
without symlink support. The slightly different testing method requires
additional monkeying.
This avoids unnecessary churn in the working directory.
It is not necessarily a fully valid assumption that .hg/cache is on the same
filesystem as the working directory, but I think it is an acceptable
approximation. It could also be the case that different parts of the working
directory is on different mount points so checking in the root folder could
also be wrong.
Before, Mercurial would create a new temporary file every time, stat it, change
its exec mode, stat it again, and delete it. Most of this dance was done to
handle the rare and not-so-essential case of VFAT mounts on unix. The cost of
that was paid by the much more common and important case of using normal file
systems.
Instead, try to create and preserve .hg/cache/checkisexec and
.hg/cache/checknoexec with and without exec flag set. If the files exist and
have correct exec flags set, we can conclude that that file system supports the
exec flag. Best case, the whole exec check can thus be done with two stat
calls. Worst case, we delete the wrong files and check as usual. That will be
because temporary loss of exec bit or on file systems without support for the
exec bit. In that case we check as we did before, with the additional overhead
of one extra stat call.
It is possible that this different test algorithm in some cases on odd file
systems will give different behaviour. Again, I think it will be rare and
special cases and I think it is worth the risk.
test-clone.t happens to show the situation where checkisexec is left behind
from the old style check, while checknoexec only will be created next time a
exec check will be performed.
Use a slightly simpler logic that in some cases can avoid an unnecessary chmod
and stat.
Instead of flipping the X bits, make it more clear that we rely on no X bits
being set on initial file creation, and that at least some of them stick after
they all have been set.
This avoids unnecessary churn in the working directory.
It is not necessarily a fully valid assumption that .hg/cache is on the same
filesystem as the working directory, but I think it is an acceptable
approximation. It could also be the case that different parts of the working
directory is on different mount points so checking in the root folder could
also be wrong.
I'm going to get rid of sys.stderr|out|in references from posix.termwidth().
In order to do that, termwidth() needs to take a ui, but functions in util.py
shouldn't depend on a ui object. So moves termwidth() to scmutil.py.
Some platforms (see bug, notably a terminal emulator on Android) ship
with os.link removed from Python to try and cater to other tools that
expect os.link to exist iff hardlinks are supported on that
platform. As a workaround for this madness, include a fallback path
for when we're on a "posix" platform but lack os.link.
Multiple threads might attempt to check links with the same temporary
name. This would cause one side to get an EEXIST error and wrongly
fail the support check. Here, we simply retry if our temporary name
exists.
Python 2.6 introduced the "except type as instance" syntax, replacing
the "except type, instance" syntax that came before. Python 3 dropped
support for the latter syntax. Since we no longer support Python 2.4 or
2.5, we have no need to continue supporting the "except type, instance".
This patch mass rewrites the exception syntax to be Python 2.6+ and
Python 3 compatible.
This patch was produced by running `2to3 -f except -w -n .`.
Python 2.6 introduced a new octal syntax: "0oXXX", replacing "0XXX". The
old syntax is not recognized in Python 3 and will result in a parse
error.
Mass rewrite all instances of the old octal syntax to the new syntax.
This patch was generated by `2to3 -f numliterals -w -n .` and the diff
was selectively recorded to exclude changes to "<N>l" syntax conversion,
which will be handled separately.
We'll use it to detect when a sshpeer have server output to be displayed.
The implementation is super basic because all case support is not the focus of
this series.
According to 6b1369445b7b introducing "windows._removedirs()":
If a hg repository including working directory is a reparse point
(directory symlinked or a junction point), then using
os.removedirs will remove the reparse point erroneously.
"windows._removedirs()" should be used instead of "os.removedirs()" on
Windows.
This patch adds "removedirs" as platform depending function to replace
"os.removedirs()" invocations for portability and safety
These will be used in upcoming patches to efficiently create a dirstate
foldmap.
The Cygwin normcase behavior is more complicated than just a simple lowercasing
or uppercasing. That's why we specify 'other'.
This patch makes "posix.shellquote" examine the specified string and
quote it only when it may have to be quoted for safety, like as the
previous patch for "windows.shellquote".
In fact, on POSIX environment, quoting itself doesn't cause issues
like issue4463. But (almost) equivalent quoting policy can avoid
examining test result differently on POSIX and Windows (even though
showing command line with "%r" causes such examination in
"test-extdiff.t").
The last hunk for "test-extdiff.t" in this patch isn't needed for the
previous patch for "windows.shellquote", because the code path of it
is executed only "#if execbit" (= avoided on Windows).
Constructing the foldmap is much faster on OS X now. For a large real-world
repo, hg perfdirstatefoldmap:
before: wall 0.805278 comb 0.800000 user 0.790000 sys 0.010000 (best of 13)
after: wall 0.399708 comb 0.410000 user 0.390000 sys 0.020000 (best of 25)
This is a nice boost to 'hg status', especially with the third-party hgwatchman
extension enabled (which eliminates stat calls). For the above repo, 'hg
status' goes from 1.17 seconds to 0.74.
On Linux, fstat().st_size of a pipe always returns 0, even if the
pipe has data available for reading. This meant that reading from
and subsequently printing the stderr pipe content after wireproto
commands over SSH meant that available data wasn't being printed.
We now implement pipe reading on POSIX by doing a non-blocking
read for all available data.
Reading all available data from a pipe has a platform-dependent
implementation.
This patch establishes platform.readpipe() by copying the
inline implementation in sshpeer.readerr(). The implementations
for POSIX and Windows are currently identical. The POSIX
implementation will be changed in a subsequent patch.
With the follow_symlinks option, sshfs will successfully create links
while claiming it encountered an I/O error. In addition, depending on
the type of link, it may subsequently be impossible to delete the link
via sshfs. Our existing link to '.' will cause sshfs to think the link
is a directory, and thus cause unlink to give EISDIR. Links to
non-existent names or circular links will cause the created link to not even
be visible.
Thus, we need to create a new temporary file and link to that. We'll
still get a failure, but we'll be able to remove the link.
The original code was a bit too clever and got confused by some cp949
Korean text. This rewrite bytes the bullet and manually decodes UTF-8
sequences. Adds some doctests.
This is similar to what is done in encoding.lower, introduced in e7a5733d533f.
This has been seen making 'hg up' and 'hg st' in a 50000+ files repo 13%
faster.
This might make Mercurial slightly slower for users who mainly use non-ASCII
filenames. That is a reasonable trade-off.
A file's atime might change even if the file itself doesn't change. This might
cause us to invalidate caches more often than necessary.
Before this change, hg add often resulted in the dirstate being parsed twice
on systems that track atime. After this change, it is only parsed once. For a
repository with over 180,000 files, this speeds up hg add from 1.2 seconds to
1.0.
posixpath.split() strips '/' from the dirname *unless it is the root*. This
patch reproduces this behavior in posix.split(). The old behavior causes a
crash when creating a file at the root of the repo with localrepo.wfile()
when the repo is at the root of the filesystem.
We also turn the unix domain socket into a class, so that we have a
sensible place to hang its logically related attributes and behaviour.
We'll shortly want to reuse this in other code.