Beginning of new command parsing interface
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Beginning of new command parsing interface
This adds commands.py, with a primary interface dispatch(args)
Dispatch searches a table of known commands, handles switches, sets up
a repo object if appropriate, and dispatches the command.
It also handles KeyboardInterrupt and can handle similar exceptions in
the future.
If the command is unknown, it falls through to the current command handler.
Commands currently handled by the new scheme: help, init, and annotate
manifest hash: 134cd032c880985e3f92f82efb8b629dd862ba4c
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCnXEGywK+sNU5EO8RAuDAAJ9q7K4w7qGVWv1NWjCPFGO/UJc6VQCdEhMQ
sBBlSRzah9QPy8K94catZyg=
=wuRf
-----END PGP SIGNATURE-----
# 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.journal = None
# abort here if the journal already exists
if os.path.exists(journal):
raise "journal already exists - run hg recover"
self.opener = opener
self.after = after
self.entries = []
self.map = {}
self.journal = journal
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 rollback(opener, file):
for l in open(file).readlines():
f, o = l.split('\0')
opener(f, "a").truncate(int(o))
os.unlink(file)