comparison mercurial/util.py @ 4328:1083ae4b5f0e

util.opener: if requested, use atomicfile even if the file doesn't exist Right now, surprisingly enough, if you request an atomic file but the file still doesn't exist, you get a regular file. AFAICS, the only time this happens is during the initial creation of the dirstate.
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Mon, 09 Apr 2007 04:24:17 -0300
parents aba90193f4e4
children ce52deed83bc
comparison
equal deleted inserted replaced
4327:aba90193f4e4 4328:1083ae4b5f0e
1007 1007
1008 def mktempcopy(name): 1008 def mktempcopy(name):
1009 d, fn = os.path.split(name) 1009 d, fn = os.path.split(name)
1010 fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d) 1010 fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d)
1011 os.close(fd) 1011 os.close(fd)
1012 ofp = posixfile(temp, "wb") 1012 # Temporary files are created with mode 0600, which is usually not
1013 # what we want. If the original file already exists, just copy
1014 # its mode. Otherwise, manually obey umask.
1015 try:
1016 st_mode = os.lstat(name).st_mode
1017 except OSError, inst:
1018 if inst.errno != errno.ENOENT:
1019 raise
1020 st_mode = 0666 & ~_umask
1021 os.chmod(temp, st_mode)
1013 try: 1022 try:
1014 try: 1023 try:
1015 ifp = posixfile(name, "rb") 1024 ifp = posixfile(name, "rb")
1016 except IOError, inst: 1025 except IOError, inst:
1026 if inst.errno == errno.ENOENT:
1027 return temp
1017 if not getattr(inst, 'filename', None): 1028 if not getattr(inst, 'filename', None):
1018 inst.filename = name 1029 inst.filename = name
1019 raise 1030 raise
1031 ofp = posixfile(temp, "wb")
1020 for chunk in filechunkiter(ifp): 1032 for chunk in filechunkiter(ifp):
1021 ofp.write(chunk) 1033 ofp.write(chunk)
1022 ifp.close() 1034 ifp.close()
1023 ofp.close() 1035 ofp.close()
1024 except: 1036 except:
1025 try: os.unlink(temp) 1037 try: os.unlink(temp)
1026 except: pass 1038 except: pass
1027 raise 1039 raise
1028 st = os.lstat(name)
1029 os.chmod(temp, st.st_mode)
1030 return temp 1040 return temp
1031 1041
1032 class atomictempfile(posixfile): 1042 class atomictempfile(posixfile):
1033 """the file will only be copied when rename is called""" 1043 """the file will only be copied when rename is called"""
1034 def __init__(self, name, mode): 1044 def __init__(self, name, mode):
1065 1075
1066 if mode[0] != "r": 1076 if mode[0] != "r":
1067 try: 1077 try:
1068 nlink = nlinks(f) 1078 nlink = nlinks(f)
1069 except OSError: 1079 except OSError:
1080 nlink = 0
1070 d = os.path.dirname(f) 1081 d = os.path.dirname(f)
1071 if not os.path.isdir(d): 1082 if not os.path.isdir(d):
1072 os.makedirs(d) 1083 os.makedirs(d)
1073 else: 1084 if atomic:
1074 if atomic: 1085 return atomicfile(f, mode)
1075 return atomicfile(f, mode) 1086 elif atomictemp:
1076 elif atomictemp: 1087 return atomictempfile(f, mode)
1077 return atomictempfile(f, mode) 1088 if nlink > 1:
1078 if nlink > 1: 1089 rename(mktempcopy(f), f)
1079 rename(mktempcopy(f), f)
1080 return posixfile(f, mode) 1090 return posixfile(f, mode)
1081 1091
1082 return o 1092 return o
1083 1093
1084 class chunkbuffer(object): 1094 class chunkbuffer(object):