diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -694,7 +694,7 @@ class revlog(object): df.write(d) fp.close() df.close() - fp = self.opener(self.indexfile, 'w', atomic=True) + fp = self.opener(self.indexfile, 'w', atomictemp=True) self.version &= ~(REVLOGNGINLINEDATA) if self.count(): x = self.index[0] @@ -708,7 +708,9 @@ class revlog(object): e = struct.pack(self.indexformat, *x) fp.write(e) - fp.close() + # if we don't call rename, the temp file will never replace the + # real index + fp.rename() self.chunkcache = None def addrevision(self, text, transaction, link, p1=None, p2=None, d=None): diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -431,20 +431,33 @@ def opener(base, audit=True): os.chmod(temp, st.st_mode) return temp - class atomicfile(file): - """the file will only be copied on close""" - def __init__(self, name, mode, atomic=False): + class atomictempfile(file): + """the file will only be copied when rename is called""" + def __init__(self, name, mode): self.__name = name self.temp = mktempcopy(name) file.__init__(self, self.temp, mode) - def close(self): + def rename(self): if not self.closed: file.close(self) rename(self.temp, self.__name) def __del__(self): - self.close() + if not self.closed: + try: + os.unlink(self.temp) + except: pass + file.close(self) - def o(path, mode="r", text=False, atomic=False): + class atomicfile(atomictempfile): + """the file will only be copied on close""" + def __init__(self, name, mode): + atomictempfile.__init__(self, name, mode) + def close(self): + self.rename() + def __del__(self): + self.rename() + + def o(path, mode="r", text=False, atomic=False, atomictemp=False): if audit_p: audit_path(path) f = os.path.join(p, path) @@ -462,6 +475,8 @@ def opener(base, audit=True): else: if atomic: return atomicfile(f, mode) + elif atomictemp: + return atomictempfile(f, mode) if nlink > 1: rename(mktempcopy(f), f) return file(f, mode)