reducing it to a NOP on Windows.
This eliminates a pointless stat call on Windows and reduces the risk of
interferring with other processes (e.g. AV-scanners, file change watchers).
See also http://mercurial.selenic.com/wiki/UnlinkingFilesOnWindows, item 2d
This class contains a stat result, and possibly other file info to reliably
determine between two points in time whether a file has changed.
Uniquely identifying a file gives us that reliability because we either
atomic rename or append. So one of two will happen: the file 'id' will change,
or the size of the file will change.
posix implements it simply by calling os.stat() and checking if the result
has st_ino.
For now on Windows we always assume the path is uncacheable. This can be
improved on NTFS due to file IDs: http://msdn.microsoft.com/en-us/library/aa363788(v=vs.85).aspx
So we need to find out if a file path is on an NTFS drive, for that we have:
- GetVolumeInformation, which unfortunately only works with a root path (but is available on XP)
- GetVolumeInformationByHandleW, works on a full file path but requires Vista or higher
On Windows sys.stdout was being replaced with winstdout, which caused
util.system() to redirect its output (due to 388eabdda556). That causes
interactive tools (such as vim) to stop working.
Python added support for Windows 6.0 (Vista) symbolic links in 3.2 [1], but
even these symbolic links aren't what we can expect from a canonical
symbolic link, since creation requires SeCreateSymbolicLinkPrivilege,
which typically only admins have.
So we can safely assume that we don't have symbolic links on Windows.
[1] http://docs.python.org/py3k/library/os.html#os.symlink
The pywin32 package is no longer needed.
ctypes is now required for running Mercurial on Windows.
ctypes is included in Python since version 2.5. For Python 2.4, ctypes is
available as an extra installer package for Windows.
Moved spawndetached() from windows.py to win32.py and fixed it, using
ctypes as well. spawndetached was defunct with Python 2.6.6 because Python
removed their undocumented subprocess.CreateProcess. This fixes
'hg serve -d' on Windows.
windows: factor it out of rename
posix: add alias 'unlink' for os.unlink
Note that this new unlink function now has different semantics than the
unlink() we had before changeset 5c424b3de62c ("rename util.unlink to
unlinkpath").
On Windows, os.rename reliably raises OSError with errno.EEXIST if the
destination already exists (even on shares served by Samba).
Windows does *not* silently overwrite the destination of a rename.
So there is no need to first call os.path.exists on the chosen temp path.
Trusting os.path.exists is actually harmful, since using it enables the
following racy sequence of actions:
1) os.path.exists(temp) returns False
2) some evil other process creates a file with name temp
3) os.rename(dst, temp) now fails because temp has been taken
Not using os.path.exists and directly trying os.rename(dst, temp)
eliminates this race.
sys.stdout.write('-'*80 + '\n')
or
sys.stdout.write('-'*80 + '\r')
do not work on Windows as they do on unix. On a 80 columns Windows console, the
extra CR or LF are interpreted as if belonging to the next line, so the first
command displays 2 lines (only one on unix) and the second one leave the line
visible and move back to the following line. To avoid this, we sacrifice one
column under Windows.
On Windows, Mercurial can be run from the python script of from a frozen
executable. In the first case, we have to call the python interpreter since the
script is not executable. Frozen executable can be called directly.
Fix 3/3 for issue421
The Windows-only wrapper around stdout is causing both of these tests to fail.
test-demandimport fails because it tries to print repr(sys.stdout). Use
stderr instead since that is not wrapped.
test-trusted fails because the wrapper doesn't handle softspace and an
unexpected extra space gets printed.
The function is implemented for Mac OS X using the F_GETPATH fcntl,
and a basic implementation for Windows is provided as well. On other
POSIX systems, vanilla os.path.realpath() is used.
This fixes the implied reliance on pywin32 and the win32 module. This
also fixes a regression in fe7c89838a64 that made Mercurial unusable
without pywin32.
The fstat function was undefined, but never used since a stat object
was always passed in the optional st argument. Passing st is now
mandatory.
This bug crept in when util was split up into posix and windows
modules. The fstat function is still defined in util, but importing it
into posix would create an import cycle which seems unnecessary.