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