[PATCH 3 of 4 RFC] transaction: add a validation stage
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Tue Mar 10 03:07:15 CDT 2015
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1425966216 25200
# Mon Mar 09 22:43:36 2015 -0700
# Node ID d3bb13fe8ffe090f13b6f66cf437333c468c8b0a
# Parent b9b9d81a2ad56ca8951ed8c11c06bc965164120a
transaction: add a validation stage
The 'transaction' object can now be fed a 'validator' function. This function
will be run right before the transaction is closed to validate its content. The
target usage is hooks. The validation function is expected to raise an exception
when it wants to abort the transaction.
This only introduce the idea with a default no-op validator. Actual usage is in
the next changeset.
diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -810,15 +810,13 @@ variables it is passed are listed with n
``txnopen``
Run before any new repository transaction is open. Reason for the transaction
opening will be in ``$HG_TXNNAME``. This hook can abort transaction opening.
-``txnclosing``
- Run right before that transaction is actually commited for good. Any
- repository change will be visible to the hook program. This lets you validate
- the transaction content or changes it. Exit status 0 allows the commit to
- proceed. Non-zero status will cause the transaction to be rolled back. Reason
+``txnclosed``
+ Run after any transaction have been commited. The transaction cannot be
+ aborted at this point. The hook will run after the lock is released. Reason
for the transaction opening will be in ``$HG_TXNNAME``. The rest of the
available data will vary according the event who append during the
transaction. New changesets will add ``$HG_NODE`` (id of the first added
changesets, ``$HG_URL`` and ``$HG_SOURCE`` variables, bookmark and phases
changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``, etc
diff --git a/mercurial/transaction.py b/mercurial/transaction.py
--- a/mercurial/transaction.py
+++ b/mercurial/transaction.py
@@ -81,11 +81,11 @@ def _playback(journal, report, opener, v
# only pure backup file remains, it is sage to ignore any error
pass
class transaction(object):
def __init__(self, report, opener, vfsmap, journalname, undoname=None,
- after=None, createmode=None):
+ after=None, createmode=None, validator=None):
"""Begin a new transaction
Begins a new transaction that allows rolling back writes in the event of
an exception.
@@ -105,10 +105,16 @@ class transaction(object):
self.entries = []
self.map = {}
self.journal = journalname
self.undoname = undoname
self._queue = []
+ # A callback to validate transaction content before closing it.
+ # should raise exception is anything is wrong.
+ # target user is repository hooks.
+ if validator is None:
+ validator = lambda tr: None
+ self.validator = validator
# a dict of arguments to be passed to hooks
self.hookargs = {}
self.file = opener.open(self.journal, "w")
# a list of ('location', 'path', 'backuppath', cache) entries.
@@ -376,10 +382,11 @@ class transaction(object):
@active
def close(self):
'''commit the transaction'''
if self.count == 1:
+ self.validator(self) # will raise exception if needed
self._generatefiles()
categories = sorted(self._finalizecallback)
for cat in categories:
self._finalizecallback[cat](self)
More information about the Mercurial-devel
mailing list