# HG changeset patch # User Vadim Gelfer # Date 1147284618 25200 # Node ID 45aef5ddcdbe2302ee2292c8d5ae83dd189acdf4 # Parent 3e5fbf001f9b064e5ddd8b4d4b707c2eb20482a6 windows: revlog.lazyparser not always safe to use. can not use on windows < nt or if win32 api not available. diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -87,6 +87,13 @@ class lazyparser(object): """ this class avoids the need to parse the entirety of large indices """ + + # lazyparser is not safe to use on windows if win32 extensions not + # available. it keeps file handle open, which make it not possible + # to break hardlinks on local cloned repos. + safe_to_use = os.name != 'nt' or (not util.is_win_9x() and + hasattr(util, 'win32api')) + def __init__(self, dataf, size, indexformat, shaoffset): self.dataf = dataf self.format = indexformat @@ -362,7 +369,8 @@ class revlog(object): shaoffset = ngshaoffset if i: - if not self.inlinedata() and st and st.st_size > 10000: + if (lazyparser.safe_to_use and not self.inlinedata() and + st and st.st_size > 10000): # big index, let's parse it on demand parser = lazyparser(f, st.st_size, self.indexformat, shaoffset) self.index = lazyindex(parser) diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -489,6 +489,13 @@ def fstat(fp): posixfile = file +def is_win_9x(): + '''return true if run on windows 95, 98 or me.''' + try: + return sys.getwindowsversion()[3] == 1 + except AttributeError: + return os.name == 'nt' and 'command' in os.environ.get('comspec', '') + # Platform specific variants if os.name == 'nt': demandload(globals(), "msvcrt") @@ -570,6 +577,8 @@ if os.name == 'nt': try: # override functions with win32 versions if possible from util_win32 import * + if not is_win_9x(): + posixfile = posixfile_nt except ImportError: pass diff --git a/mercurial/util_win32.py b/mercurial/util_win32.py --- a/mercurial/util_win32.py +++ b/mercurial/util_win32.py @@ -183,11 +183,11 @@ def system_rcpath_win32(): filename = win32process.GetModuleFileNameEx(proc, 0) return [os.path.join(os.path.dirname(filename), 'mercurial.ini')] -class posixfile(object): +class posixfile_nt(object): '''file object with posix-like semantics. on windows, normal files can not be deleted or renamed if they are open. must open with win32file.FILE_SHARE_DELETE. this flag does not exist on - windows <= nt.''' + windows < nt, so do not use this class there.''' # tried to use win32file._open_osfhandle to pass fd to os.fdopen, # but does not work at all. wrap win32 file api instead.