Mercurial > hg > mercurial-crew-with-dirclash
view mercurial/transaction.py @ 147:b6d8ed7aeba0
A new ancestor algorithm
The old ancestor algorithm could get fooled into returning ancestors
closer to root than it ought to. Hopefully this one, which strictly
orders its search by distance from room, will be foolproof.
author | mpm@selenic.com |
---|---|
date | Tue, 24 May 2005 23:11:44 -0800 |
parents | 8d55c2d72c7c |
children | 5dcbe4d9a30c |
line wrap: on
line source
# transaction.py - simple journalling scheme for mercurial # # This transaction scheme is intended to gracefully handle program # errors and interruptions. More serious failures like system crashes # can be recovered with an fsck-like tool. As the whole repository is # effectively log-structured, this should amount to simply truncating # anything that isn't referenced in the changelog. # # Copyright 2005 Matt Mackall <mpm@selenic.com> # # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. import os class transaction: def __init__(self, opener, journal, after = None): self.opener = opener self.after = after self.entries = [] self.map = {} self.journal = journal # abort here if the journal already exists if os.path.exists(self.journal): raise "journal already exists!" self.file = open(self.journal, "w") def __del__(self): if self.entries: self.abort() try: os.unlink(self.journal) except: pass def add(self, file, offset): if file in self.map: return self.entries.append((file, offset)) self.map[file] = 1 # add enough data to the journal to do the truncate self.file.write("%s\0%d\n" % (file, offset)) self.file.flush() def close(self): self.file.close() self.entries = [] if self.after: os.rename(self.journal, self.after) else: os.unlink(self.journal) def abort(self): if not self.entries: return print "transaction abort!" for f, o in self.entries: try: self.opener(f, "a").truncate(o) except: print "failed to truncate", f self.entries = [] print "rollback completed" def recover(self): for l in open(self.journal).readlines(): f, o = l.split('\0') self.opener(f, "a").truncate(int(o)) os.unlink(self.journal)