comparison mercurial/util.py @ 41289:593f6359681d

update: fix edge-case with update.atomic-file and read-only files We used to create the tempfile with the original file mode. That means creating a read-only tempfile when the original file is read-only, which crash if we need to write on the tempfile. The file in the working directory ends up being writable with and without the atomic update config, so the behavior is the same.
author Boris Feld <boris.feld@octobus.net>
date Thu, 10 Jan 2019 14:57:01 +0100
parents 7cda0cacbbf6
children b141b5243b37
comparison
equal deleted inserted replaced
41288:17941fc53ae9 41289:593f6359681d
2043 an alternative of simple "xxx.split(os.sep)". 2043 an alternative of simple "xxx.split(os.sep)".
2044 It is recommended to use os.path.normpath() before using this 2044 It is recommended to use os.path.normpath() before using this
2045 function if need.''' 2045 function if need.'''
2046 return path.split(pycompat.ossep) 2046 return path.split(pycompat.ossep)
2047 2047
2048 def mktempcopy(name, emptyok=False, createmode=None): 2048 def mktempcopy(name, emptyok=False, createmode=None, enforcewritable=False):
2049 """Create a temporary file with the same contents from name 2049 """Create a temporary file with the same contents from name
2050 2050
2051 The permission bits are copied from the original file. 2051 The permission bits are copied from the original file.
2052 2052
2053 If the temporary file is going to be truncated immediately, you 2053 If the temporary file is going to be truncated immediately, you
2059 fd, temp = pycompat.mkstemp(prefix='.%s-' % fn, suffix='~', dir=d) 2059 fd, temp = pycompat.mkstemp(prefix='.%s-' % fn, suffix='~', dir=d)
2060 os.close(fd) 2060 os.close(fd)
2061 # Temporary files are created with mode 0600, which is usually not 2061 # Temporary files are created with mode 0600, which is usually not
2062 # what we want. If the original file already exists, just copy 2062 # what we want. If the original file already exists, just copy
2063 # its mode. Otherwise, manually obey umask. 2063 # its mode. Otherwise, manually obey umask.
2064 copymode(name, temp, createmode) 2064 copymode(name, temp, createmode, enforcewritable)
2065
2065 if emptyok: 2066 if emptyok:
2066 return temp 2067 return temp
2067 try: 2068 try:
2068 try: 2069 try:
2069 ifp = posixfile(name, "rb") 2070 ifp = posixfile(name, "rb")
2202 or repo.wlock). 2203 or repo.wlock).
2203 ''' 2204 '''
2204 def __init__(self, name, mode='w+b', createmode=None, checkambig=False): 2205 def __init__(self, name, mode='w+b', createmode=None, checkambig=False):
2205 self.__name = name # permanent name 2206 self.__name = name # permanent name
2206 self._tempname = mktempcopy(name, emptyok=('w' in mode), 2207 self._tempname = mktempcopy(name, emptyok=('w' in mode),
2207 createmode=createmode) 2208 createmode=createmode,
2209 enforcewritable=('w' in mode))
2210
2208 self._fp = posixfile(self._tempname, mode) 2211 self._fp = posixfile(self._tempname, mode)
2209 self._checkambig = checkambig 2212 self._checkambig = checkambig
2210 2213
2211 # delegated methods 2214 # delegated methods
2212 self.read = self._fp.read 2215 self.read = self._fp.read