[PATCH STABLE V2] windows: implement nlinks() using Python's ctypes (issue1922)

Matt Mackall mpm at selenic.com
Tue Jan 25 16:45:45 CST 2011


On Sun, 2011-01-23 at 16:12 +0100, Adrian Buehlmann wrote:
> On 2011-01-23 15:17, Adrian Buehlmann wrote:
> > # HG changeset patch
> > # User Adrian Buehlmann <adrian at cadifra.com>
> > # Date 1295790385 -3600
> > # Branch stable
> > # Node ID 99f2b980756d1c22775cf6ec6e93c646bc910a55
> > # Parent  d0e0d3d43e1439d63564ab4dddfe0daa69ae2d86
> > windows: implement nlinks() using Python's ctypes (issue1922)
> > 
> > If the pywin32 package was not installed, the import of win32 in
> > windows.py silently failed and (before this patch) util.nlinks was then
> > used as a fallback when running on Windows.
> > 
> > util.nlinks() returned 0 for all files when called on Windows, because
> > Python's
> > 
> >     os.lstat(name).st_nlink
> > 
> > is 0 on Windows for all files.
> > 
> > If nlinks() returns 0, util.opener failed to break up hardlinks, which
> > could lead to repository corruption when committing or pushing to a
> > hardlinked clone (hg verify detects it).
> > 
> > We now provide our own nlinks() in windows.py by using Python's ctypes
> > library, so we don't depend on the pywin32 package being installed for
> > nlinks().
> > 
> >   ** Since Python's ctypes were introduced in Python 2.5, we now
> >   ** require Python 2.5 or later for Mercurial on Windows
> > 
> > Using ctypes also has the benefit that nlinks() also works correctly
> > for the pure Python Mercurial.
> > 
> > And we force breaking up hardlinks on every append file access in the
> > opener if nlinks() returns < 1, thus making sure that we can't cause
> > any hardlink repository corruption.
> > 
> > It would have been possible to simply require the pywin32 package on
> > Windows and abort with an import error if it's not installed, but such
> > a policy change should be avoided on the stable branch. Previous packages
> > like for example
> > 
> >     mercurial-1.7.3-1.win32-py2.6.exe
> > 
> > didn't make it obvious that pywin32 was needed as a dependency. It just
> > silently caused repository corruption in hardlinked clones if pywin32
> > was not installed.

Alright, now I've lost the plot. Let me see if I can recover it:

require pywin32
 - adds a new dependency
 - solves problem for native
 - pure may or may not be able to use it (ie jython)
extend osutils
 - no new dependency
 - solves problem for native
 - pure still broken
use ctypes
 - requires py2.5 or separate ctypes
 - solves problem for native
 - pure may or may not be able to use it

It's worth noting that pure has pretty substantial problems on Windows
due to the use of "native" open() and the like.

So in this analysis, osutils looks like the winner. Is your osutils
patch good for 1.7.4?

Another way to look at it is "what else breaks without pywin32"?
The answer looks like:

- finding stale locks
- finding rc paths
- finding usernames
- signal handling
- terminal width
- window hiding??

Looks like pretty minor stuff. 

A related question is "can we replace pywin32 with ctypes"? If the
answer is yes, it might make sense to do that so we'll have no
dependencies when we move to Py2.5 a few years from now. Switching to
ctypes might make sense for 1.8 or 1.9.

-- 
Mathematics is the supreme nostalgia of our time.




More information about the Mercurial-devel mailing list