[PATCH] util: refactor opener
Adrian Buehlmann
adrian at cadifra.com
Thu Nov 4 08:45:45 CDT 2010
# HG changeset patch
# User Adrian Buehlmann <adrian at cadifra.com>
# Date 1288857877 -3600
# Node ID 1fe20f15a22b08aedfdc2b6d21a2d441706f314e
# Parent a419cb2395d5d8167d58f9466d2bee34e87d6b3a
util: refactor opener
- Don't call atomictempfile or nlinks() if the path is malformed
(no basename). Let posixfile() raise IOError directly.
- atomictempfile already breaks up hardlinks, no need to poke
at the file with nlinks() if atomictemp.
- No need to copy the file contents to break hardlinks for 'w'rite
modes (w, wb, w+, w+b). Unlinking and recreating the file is faster.
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -858,23 +858,34 @@ class opener(object):
mode += "b" # for that other OS
nlink = -1
- if mode not in ("r", "rb"):
+ st_mode = None
+ dirname, basename = os.path.split(f)
+ # If basename is empty, then the path is malformed because it points
+ # to a directory. Let the posixfile() call below raise IOError.
+ if basename and mode not in ('r', 'rb'):
+ if atomictemp:
+ if not os.path.isdir(dirname):
+ makedirs(dirname, self.createmode)
+ return atomictempfile(f, mode, self.createmode)
try:
- nlink = nlinks(f)
+ if 'w' in mode:
+ st_mode = os.lstat(f).st_mode & 0777
+ os.unlink(f)
+ nlink = 0
+ else:
+ nlink = nlinks(f)
except OSError:
nlink = 0
- dirname, basename = os.path.split(f)
- # Avoid calling makedirs when the path points to a
- # directory -- the open will raise IOError below.
- if basename and not os.path.isdir(dirname):
+ if not os.path.isdir(dirname):
makedirs(dirname, self.createmode)
- if atomictemp:
- return atomictempfile(f, mode, self.createmode)
if nlink > 1:
rename(mktempcopy(f), f)
fp = posixfile(f, mode)
if nlink == 0:
- self._fixfilemode(f)
+ if st_mode is None:
+ self._fixfilemode(f)
+ else:
+ os.chmod(f, st_mode)
return fp
def symlink(self, src, dst):
More information about the Mercurial-devel
mailing list