Mercurial > hg-stable
changeset 24284:ff14b26fe5f4
hook: add a generic hook right before we commit a transaction
We are adding a 'txnclose' hook that will be run right before a transaction is
closed. Hooks running at that time will have access to the full transaction
content through both 'hookargs' content and on-disk reading. They will be able
to abort the transaction.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Mon, 09 Mar 2015 22:50:49 -0700 |
parents | ef22cfff7052 |
children | 8e13cc0825f1 |
files | mercurial/help/config.txt mercurial/localrepo.py tests/test-hook.t |
diffstat | 3 files changed, 32 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/help/config.txt Mon Mar 09 22:43:36 2015 -0700 +++ b/mercurial/help/config.txt Mon Mar 09 22:50:49 2015 -0700 @@ -813,15 +813,23 @@ transaction will be in ``$HG_TXNNAME``. A non-zero status will prevent the transaction from being opened. +``pretxnclose`` + Run right before the transaction is actually finalized. Any + repository change will be visible to the hook program. This lets you + validate the transaction content or change it. Exit status 0 allows + the commit to proceed. Non-zero status will cause the transaction to + be rolled back. The reason for the transaction opening will be in + ``$HG_TXNNAME``. The rest of the available data will vary according + the transaction type. New changesets will add + ``$HG_NODE`` (id of the first added changeset), ``$HG_URL`` and + ``$HG_SOURCE`` variables, bookmarks and phases changes will set + ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``, etc. + ``txnclose`` Run after any repository transaction has been commited. At this point, the transaction can no longer be rolled back. The hook will run - after the lock is released. The reason for the transaction will - be in ``$HG_TXNNAME``. The rest of the available data will vary - according the event that happened during the transaction. New changesets - will add ``$HG_NODE`` (id of the first added changeset), ``$HG_URL`` - and ``$HG_SOURCE`` variables, bookmarks and phases changes will set - ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``, etc. + after the lock is released. see ``pretxnclose`` docs for details about + available variables. ``pretxnchangegroup`` Run after a changegroup has been added via push, pull or unbundle,
--- a/mercurial/localrepo.py Mon Mar 09 22:43:36 2015 -0700 +++ b/mercurial/localrepo.py Mon Mar 09 22:50:49 2015 -0700 @@ -915,17 +915,24 @@ renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()] rp = report and report or self.ui.warn vfsmap = {'plain': self.vfs} # root of .hg/ - tr = transaction.transaction(rp, self.svfs, vfsmap, + # we must avoid cyclic reference between repo and transaction. + reporef = weakref.ref(self) + def validate(tr): + """will run pre-closing hooks""" + pending = lambda: tr.writepending() and self.root or "" + reporef().hook('pretxnclose', throw=True, pending=pending, + xnname=desc) + + tr = transaction.transaction(rp, self.sopener, vfsmap, "journal", "undo", aftertrans(renames), - self.store.createmode) + self.store.createmode, + validator=validate) # note: writing the fncache only during finalize mean that the file is # outdated when running hooks. As fncache is used for streaming clone, # this is not expected to break anything that happen during the hooks. tr.addfinalize('flush-fncache', self.store.write) - # we must avoid cyclic reference between repo and transaction. - reporef = weakref.ref(self) def txnclosehook(tr2): """To be run if transaction is successful, will schedule a hook run """
--- a/tests/test-hook.t Mon Mar 09 22:43:36 2015 -0700 +++ b/tests/test-hook.t Mon Mar 09 22:50:49 2015 -0700 @@ -13,6 +13,7 @@ > pre-cat = python "$TESTDIR/printenv.py" pre-cat > post-cat = python "$TESTDIR/printenv.py" post-cat > pretxnopen = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" pretxnopen" + > pretxnclose = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" pretxnclose" > txnclose = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" txnclose" > EOF $ echo a > a @@ -22,6 +23,7 @@ pretxnopen hook: HG_TXNNAME=commit pretxncommit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$TESTTMP/a 0:cb9a9f314b8b + pretxnclose hook: HG_PENDING=$TESTTMP/a HG_XNNAME=commit txnclose hook: HG_PHASES_MOVED=1 HG_TXNNAME=commit commit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 commit.b hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 @@ -49,6 +51,7 @@ pretxnopen hook: HG_TXNNAME=commit pretxncommit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a 1:ab228980c14d + pretxnclose hook: HG_PENDING=$TESTTMP/a HG_XNNAME=commit txnclose hook: HG_TXNNAME=commit commit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b commit.b hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b @@ -61,6 +64,7 @@ pretxnopen hook: HG_TXNNAME=commit pretxncommit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a 2:ee9deb46ab31 + pretxnclose hook: HG_PENDING=$TESTTMP/a HG_XNNAME=commit txnclose hook: HG_TXNNAME=commit commit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b commit.b hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b @@ -73,6 +77,7 @@ pretxnopen hook: HG_TXNNAME=commit pretxncommit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd HG_PENDING=$TESTTMP/a 3:07f3376c1e65 + pretxnclose hook: HG_PENDING=$TESTTMP/a HG_XNNAME=commit txnclose hook: HG_TXNNAME=commit commit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd commit.b hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd @@ -116,6 +121,7 @@ pretxnopen hook: HG_TXNNAME=commit pretxncommit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a 4:539e4b31b6dc + pretxnclose hook: HG_PENDING=$TESTTMP/a HG_XNNAME=commit tag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a txnclose hook: HG_TXNNAME=commit commit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 @@ -212,6 +218,7 @@ searching for changes no changes found pretxnopen hook: HG_TXNNAME=bookmarks + pretxnclose hook: HG_PENDING=$TESTTMP/a HG_XNNAME=bookmarks txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNNAME=bookmarks pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1 exporting bookmark foo