##// END OF EJS Templates
atomictempfile: make close() consistent with other file-like objects....
Greg Ward -
r15057:774da712 default
parent child Browse files
Show More
@@ -1492,7 +1492,7 b' class queue(object):'
1492 n = repo.commit(message, user, ph.date, match=match,
1492 n = repo.commit(message, user, ph.date, match=match,
1493 force=True)
1493 force=True)
1494 # only write patch after a successful commit
1494 # only write patch after a successful commit
1495 patchf.rename()
1495 patchf.close()
1496 self.applied.append(statusentry(n, patchfn))
1496 self.applied.append(statusentry(n, patchfn))
1497 except:
1497 except:
1498 ctx = repo[cparents[0]]
1498 ctx = repo[cparents[0]]
@@ -195,7 +195,7 b' class fileit(object):'
195 return
195 return
196 f = self.opener(name, "w", atomictemp=True)
196 f = self.opener(name, "w", atomictemp=True)
197 f.write(data)
197 f.write(data)
198 f.rename()
198 f.close()
199 destfile = os.path.join(self.basedir, name)
199 destfile = os.path.join(self.basedir, name)
200 os.chmod(destfile, mode)
200 os.chmod(destfile, mode)
201
201
@@ -90,7 +90,7 b' def write(repo):'
90 file = repo.opener('bookmarks', 'w', atomictemp=True)
90 file = repo.opener('bookmarks', 'w', atomictemp=True)
91 for refspec, node in refs.iteritems():
91 for refspec, node in refs.iteritems():
92 file.write("%s %s\n" % (hex(node), encoding.fromlocal(refspec)))
92 file.write("%s %s\n" % (hex(node), encoding.fromlocal(refspec)))
93 file.rename()
93 file.close()
94
94
95 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
95 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
96 try:
96 try:
@@ -121,7 +121,7 b' def setcurrent(repo, mark):'
121 try:
121 try:
122 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
122 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
123 file.write(encoding.fromlocal(mark))
123 file.write(encoding.fromlocal(mark))
124 file.rename()
124 file.close()
125 finally:
125 finally:
126 wlock.release()
126 wlock.release()
127 repo._bookmarkcurrent = mark
127 repo._bookmarkcurrent = mark
@@ -453,7 +453,7 b' class dirstate(object):'
453 write(e)
453 write(e)
454 write(f)
454 write(f)
455 st.write(cs.getvalue())
455 st.write(cs.getvalue())
456 st.rename()
456 st.close()
457 self._lastnormaltime = None
457 self._lastnormaltime = None
458 self._dirty = self._dirtypl = False
458 self._dirty = self._dirtypl = False
459
459
@@ -150,7 +150,7 b' def save_state(repo, state):'
150 for kind in state:
150 for kind in state:
151 for node in state[kind]:
151 for node in state[kind]:
152 f.write("%s %s\n" % (kind, hex(node)))
152 f.write("%s %s\n" % (kind, hex(node)))
153 f.rename()
153 f.close()
154 finally:
154 finally:
155 wlock.release()
155 wlock.release()
156
156
@@ -521,7 +521,7 b' class localrepository(repo.repository):'
521 for label, nodes in branches.iteritems():
521 for label, nodes in branches.iteritems():
522 for node in nodes:
522 for node in nodes:
523 f.write("%s %s\n" % (hex(node), encoding.fromlocal(label)))
523 f.write("%s %s\n" % (hex(node), encoding.fromlocal(label)))
524 f.rename()
524 f.close()
525 except (IOError, OSError):
525 except (IOError, OSError):
526 pass
526 pass
527
527
@@ -946,9 +946,9 b' class revlog(object):'
946 e = self._io.packentry(self.index[i], self.node, self.version, i)
946 e = self._io.packentry(self.index[i], self.node, self.version, i)
947 fp.write(e)
947 fp.write(e)
948
948
949 # if we don't call rename, the temp file will never replace the
949 # if we don't call close, the temp file will never replace the
950 # real index
950 # real index
951 fp.rename()
951 fp.close()
952
952
953 tr.replace(self.indexfile, trindex * self._io.size)
953 tr.replace(self.indexfile, trindex * self._io.size)
954 self._chunkclear()
954 self._chunkclear()
@@ -445,7 +445,7 b' def simplemerge(ui, local, base, other, '
445 out.write(line)
445 out.write(line)
446
446
447 if not opts.get('print'):
447 if not opts.get('print'):
448 out.rename()
448 out.close()
449
449
450 if m3.conflicts:
450 if m3.conflicts:
451 if not opts.get('quiet'):
451 if not opts.get('quiet'):
@@ -345,7 +345,7 b' class fncache(object):'
345 fp = self.opener('fncache', mode='wb', atomictemp=True)
345 fp = self.opener('fncache', mode='wb', atomictemp=True)
346 for p in self.entries:
346 for p in self.entries:
347 fp.write(encodedir(p) + '\n')
347 fp.write(encodedir(p) + '\n')
348 fp.rename()
348 fp.close()
349 self._dirty = False
349 self._dirty = False
350
350
351 def add(self, fn):
351 def add(self, fn):
@@ -287,6 +287,6 b' def _writetagcache(ui, repo, heads, tagf'
287 cachefile.write("%s %s\n" % (hex(node), name))
287 cachefile.write("%s %s\n" % (hex(node), name))
288
288
289 try:
289 try:
290 cachefile.rename()
290 cachefile.close()
291 except (OSError, IOError):
291 except (OSError, IOError):
292 pass
292 pass
@@ -745,11 +745,10 b' class atomictempfile(object):'
745 '''writeable file object that atomically updates a file
745 '''writeable file object that atomically updates a file
746
746
747 All writes will go to a temporary copy of the original file. Call
747 All writes will go to a temporary copy of the original file. Call
748 rename() when you are done writing, and atomictempfile will rename
748 close() when you are done writing, and atomictempfile will rename
749 the temporary copy to the original name, making the changes visible.
749 the temporary copy to the original name, making the changes
750
750 visible. If the object is destroyed without being closed, all your
751 Unlike other file-like objects, close() discards your writes by
751 writes are discarded.
752 simply deleting the temporary file.
753 '''
752 '''
754 def __init__(self, name, mode='w+b', createmode=None):
753 def __init__(self, name, mode='w+b', createmode=None):
755 self.__name = name # permanent name
754 self.__name = name # permanent name
@@ -761,12 +760,12 b' class atomictempfile(object):'
761 self.write = self._fp.write
760 self.write = self._fp.write
762 self.fileno = self._fp.fileno
761 self.fileno = self._fp.fileno
763
762
764 def rename(self):
763 def close(self):
765 if not self._fp.closed:
764 if not self._fp.closed:
766 self._fp.close()
765 self._fp.close()
767 rename(self._tempname, localpath(self.__name))
766 rename(self._tempname, localpath(self.__name))
768
767
769 def close(self):
768 def discard(self):
770 if not self._fp.closed:
769 if not self._fp.closed:
771 try:
770 try:
772 os.unlink(self._tempname)
771 os.unlink(self._tempname)
@@ -776,7 +775,7 b' class atomictempfile(object):'
776
775
777 def __del__(self):
776 def __del__(self):
778 if safehasattr(self, '_fp'): # constructor actually did something
777 if safehasattr(self, '_fp'): # constructor actually did something
779 self.close()
778 self.discard()
780
779
781 def makedirs(name, mode=None):
780 def makedirs(name, mode=None):
782 """recursive directory creation with parent mode inheritance"""
781 """recursive directory creation with parent mode inheritance"""
@@ -12,22 +12,21 b' def test1_simple():'
12 assert basename in glob.glob('.foo-*')
12 assert basename in glob.glob('.foo-*')
13
13
14 file.write('argh\n')
14 file.write('argh\n')
15 file.rename()
15 file.close()
16
16
17 assert os.path.isfile('foo')
17 assert os.path.isfile('foo')
18 assert basename not in glob.glob('.foo-*')
18 assert basename not in glob.glob('.foo-*')
19 print 'OK'
19 print 'OK'
20
20
21 # close() removes the temp file but does not make the write
21 # discard() removes the temp file without making the write permanent
22 # permanent -- essentially discards your work (WTF?!)
22 def test2_discard():
23 def test2_close():
24 if os.path.exists('foo'):
23 if os.path.exists('foo'):
25 os.remove('foo')
24 os.remove('foo')
26 file = atomictempfile('foo')
25 file = atomictempfile('foo')
27 (dir, basename) = os.path.split(file._tempname)
26 (dir, basename) = os.path.split(file._tempname)
28
27
29 file.write('yo\n')
28 file.write('yo\n')
30 file.close()
29 file.discard()
31
30
32 assert not os.path.isfile('foo')
31 assert not os.path.isfile('foo')
33 assert basename not in os.listdir('.')
32 assert basename not in os.listdir('.')
@@ -45,5 +44,5 b' def test3_oops():'
45
44
46 if __name__ == '__main__':
45 if __name__ == '__main__':
47 test1_simple()
46 test1_simple()
48 test2_close()
47 test2_discard()
49 test3_oops()
48 test3_oops()
@@ -59,7 +59,7 b' def basic(repo):'
59 # because of inode change
59 # because of inode change
60 f = scmutil.opener('.')('x', 'w', atomictemp=True)
60 f = scmutil.opener('.')('x', 'w', atomictemp=True)
61 f.write('b')
61 f.write('b')
62 f.rename()
62 f.close()
63
63
64 repo.invalidate()
64 repo.invalidate()
65 repo.cached
65 repo.cached
General Comments 0
You need to be logged in to leave comments. Login now