diff -r f00573bc93f8 -r 48a382c23226 mercurial/transaction.py --- a/mercurial/transaction.py Mon May 04 13:47:12 2009 +0200 +++ b/mercurial/transaction.py Mon May 04 15:31:57 2009 +0200 @@ -23,6 +23,23 @@ return func(self, *args, **kwds) return _active +def _playback(journal, report, opener, entries, unlink=True): + for f, o, ignore in entries: + if o or not unlink: + try: + opener(f, 'a').truncate(o) + except: + report(_("failed to truncate %s\n") % f) + raise + else: + try: + fn = opener(f).name + os.unlink(fn) + except OSError, inst: + if inst.errno != errno.ENOENT: + raise + os.unlink(journal) + class transaction(object): def __init__(self, report, opener, journal, after=None, createmode=None): self.journal = None @@ -101,40 +118,21 @@ self.report(_("transaction abort!\n")) - failed = False - for f, o, ignore in self.entries: + try: try: - self.opener(f, "a").truncate(o) + _playback(self.journal, self.report, self.opener, self.entries, False) + self.report(_("rollback completed\n")) except: - failed = True - self.report(_("failed to truncate %s\n") % f) - - self.entries = [] - - if not failed: - os.unlink(self.journal) - self.report(_("rollback completed\n")) - else: - self.report(_("rollback failed - please run hg recover\n")) - - self.journal = None + self.report(_("rollback failed - please run hg recover\n")) + finally: + self.journal = None -def rollback(opener, file): - files = {} +def rollback(opener, file, report): + entries = [] + for l in open(file).readlines(): f, o = l.split('\0') - files[f] = int(o) - for f in files: - o = files[f] - if o: - opener(f, "a").truncate(int(o)) - else: - try: - fn = opener(f).name - os.unlink(fn) - except OSError, inst: - if inst.errno != errno.ENOENT: - raise - os.unlink(file) + entries.append((f, int(o), None)) + _playback(file, report, opener, entries)