Mercurial > public > mercurial-scm > hg
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 |