Patchwork [4,of,4,V2] phase: add a dedicated pretxnclose-phase hook

login
register
mail settings
Submitter Boris Feld
Date Oct. 14, 2017, 3:46 p.m.
Message ID <d1409d777e72f23fa1c7.1507995984@FB>
Download mbox | patch
Permalink /patch/24904/
State Accepted
Headers show

Comments

Boris Feld - Oct. 14, 2017, 3:46 p.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1507476198 -7200
#      Sun Oct 08 17:23:18 2017 +0200
# Node ID d1409d777e72f23fa1c776beefd26a046091ef41
# Parent  06eeae1828afe149886e18e6b4fc8180a3803fdb
# EXP-Topic b2.phases.hooks
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r d1409d777e72
phase: add a dedicated pretxnclose-phase hook

This new hook mirror the newly introduced 'txnclose-phase' but can abort the
transaction.
Augie Fackler - Oct. 15, 2017, 5:06 a.m.
On Sat, Oct 14, 2017 at 05:46:24PM +0200, Boris Feld wrote:
> # HG changeset patch
> # User Boris Feld <boris.feld@octobus.net>
> # Date 1507476198 -7200
> #      Sun Oct 08 17:23:18 2017 +0200
> # Node ID d1409d777e72f23fa1c776beefd26a046091ef41
> # Parent  06eeae1828afe149886e18e6b4fc8180a3803fdb
> # EXP-Topic b2.phases.hooks
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r d1409d777e72
> phase: add a dedicated pretxnclose-phase hook

queued, thanks
Gregory Szorc - Oct. 20, 2017, 11:10 a.m.
> On Oct 14, 2017, at 17:46, Boris Feld <boris.feld@octobus.net> wrote:
> 
> # HG changeset patch
> # User Boris Feld <boris.feld@octobus.net>
> # Date 1507476198 -7200
> #      Sun Oct 08 17:23:18 2017 +0200
> # Node ID d1409d777e72f23fa1c776beefd26a046091ef41
> # Parent  06eeae1828afe149886e18e6b4fc8180a3803fdb
> # EXP-Topic b2.phases.hooks
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r d1409d777e72
> phase: add a dedicated pretxnclose-phase hook

Could you please send a follow up to improve the help documentation. Specifically:

* Note that the hook can be fired multiple times
* Clarify whether each change revision has a hook fire or whether it is only phase root/head revisions. If the latter, explain what that means.

> 
> This new hook mirror the newly introduced 'txnclose-phase' but can abort the
> transaction.
> 
> diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
> --- a/mercurial/help/config.txt
> +++ b/mercurial/help/config.txt
> @@ -990,6 +990,17 @@
>   ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
>   ``HG_TXNID``.
> 
> +``pretxnclose-phase``
> +  Run right before a phase change 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.  A non-zero
> +  status will cause the transaction to be rolled back.
> +  The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
> +  while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
> +  will be empty.  In addition, the reason for the transaction opening will be in
> +  ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
> +  ``HG_TXNID``.
> +
> ``txnclose``
>   Run after any repository transaction has been committed. At this
>   point, the transaction can no longer be rolled back. The hook will run
> @@ -1005,12 +1016,8 @@
> ``txnclose-phase``
>   Run after any phase change has been committed. At this point, the
>   transaction can no longer be rolled back. The hook will run after the lock
> -  is released.
> -  The affected node is available in ``$HG_NODE``, the new phase will be
> -  available in ``$HG_PHASE`` while the previous phase will be available in
> -  ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE`` will be empty.  In
> -  addition, the reason for the transaction opening will be in ``$HG_TXNNAME``,
> -  and a unique identifier for the transaction will be in ``HG_TXNID``.
> +  is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
> +  available variables.
> 
> ``txnabort``
>   Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -1243,6 +1243,14 @@
>                     repo.hook('pretxnclose-bookmark', throw=True,
>                               txnname=desc,
>                               **pycompat.strkwargs(args))
> +            if hook.hashook(repo.ui, 'pretxnclose-phase'):
> +                cl = repo.unfiltered().changelog
> +                for rev, (old, new) in tr.changes['phases'].items():
> +                    args = tr.hookargs.copy()
> +                    node = hex(cl.node(rev))
> +                    args.update(phases.preparehookargs(node, old, new))
> +                    repo.hook('pretxnclose-phase', throw=True, txnname=desc,
> +                              **pycompat.strkwargs(args))
> 
>             repo.hook('pretxnclose', throw=True,
>                       txnname=desc, **pycompat.strkwargs(tr.hookargs))
> diff --git a/tests/test-phases.t b/tests/test-phases.t
> --- a/tests/test-phases.t
> +++ b/tests/test-phases.t
> @@ -732,3 +732,94 @@
>   rollback completed
>   abort: pretxnclose hook exited with status 1
>   [255]
> +
> +Check that pretxnclose-phase hook can control phase movement
> +
> +  $ hg phase --force b3325c91a4d9 --secret
> +  test-debug-phase: move rev 3: 0 -> 2
> +  test-debug-phase: move rev 4: 0 -> 2
> +  test-debug-phase: move rev 5: 1 -> 2
> +  test-debug-phase: move rev 7: 0 -> 2
> +  test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e:  0 -> 2
> +  test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde:  0 -> 2
> +  test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8:  1 -> 2
> +  test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af:  0 -> 2
> +  $ hg log -G -T phases
> +  @    changeset:   7:17a481b3bccb
> +  |\   tag:         tip
> +  | |  phase:       secret
> +  | |  parent:      6:cf9fe039dfd6
> +  | |  parent:      4:a603bfb5a83e
> +  | |  user:        test
> +  | |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  | |  summary:     merge B' and E
> +  | |
> +  | o  changeset:   6:cf9fe039dfd6
> +  | |  phase:       public
> +  | |  parent:      1:27547f69f254
> +  | |  user:        test
> +  | |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  | |  summary:     B'
> +  | |
> +  o |  changeset:   4:a603bfb5a83e
> +  | |  phase:       secret
> +  | |  user:        test
> +  | |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  | |  summary:     E
> +  | |
> +  o |  changeset:   3:b3325c91a4d9
> +  | |  phase:       secret
> +  | |  user:        test
> +  | |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  | |  summary:     D
> +  | |
> +  o |  changeset:   2:f838bfaca5c7
> +  |/   phase:       public
> +  |    user:        test
> +  |    date:        Thu Jan 01 00:00:00 1970 +0000
> +  |    summary:     C
> +  |
> +  o  changeset:   1:27547f69f254
> +  |  phase:       public
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     B
> +  |
> +  o  changeset:   0:4a2df7238c3b
> +     phase:       public
> +     user:        test
> +     date:        Thu Jan 01 00:00:00 1970 +0000
> +     summary:     A
> +  
> +
> +Install a hook that prevent b3325c91a4d9 to become public
> +
> +  $ cat >> .hg/hgrc << EOF
> +  > [hooks]
> +  > pretxnclose-phase.nopublish_D = (echo \$HG_NODE| grep -v b3325c91a4d9>/dev/null) || [ 0 -lt \$HG_PHASE ]
> +  > EOF
> +
> +Try various actions. only the draft move should succeed
> +
> +  $ hg phase --public b3325c91a4d9
> +  transaction abort!
> +  rollback completed
> +  abort: pretxnclose-phase.nopublish_D hook exited with status 1
> +  [255]
> +  $ hg phase --public a603bfb5a83e
> +  transaction abort!
> +  rollback completed
> +  abort: pretxnclose-phase.nopublish_D hook exited with status 1
> +  [255]
> +  $ hg phase --draft 17a481b3bccb
> +  test-debug-phase: move rev 3: 2 -> 1
> +  test-debug-phase: move rev 4: 2 -> 1
> +  test-debug-phase: move rev 7: 2 -> 1
> +  test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e:  2 -> 1
> +  test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde:  2 -> 1
> +  test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af:  2 -> 1
> +  $ hg phase --public 17a481b3bccb
> +  transaction abort!
> +  rollback completed
> +  abort: pretxnclose-phase.nopublish_D hook exited with status 1
> +  [255]
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -990,6 +990,17 @@ 
   ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
   ``HG_TXNID``.
 
+``pretxnclose-phase``
+  Run right before a phase change 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.  A non-zero
+  status will cause the transaction to be rolled back.
+  The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
+  while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
+  will be empty.  In addition, the reason for the transaction opening will be in
+  ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
+  ``HG_TXNID``.
+
 ``txnclose``
   Run after any repository transaction has been committed. At this
   point, the transaction can no longer be rolled back. The hook will run
@@ -1005,12 +1016,8 @@ 
 ``txnclose-phase``
   Run after any phase change has been committed. At this point, the
   transaction can no longer be rolled back. The hook will run after the lock
-  is released.
-  The affected node is available in ``$HG_NODE``, the new phase will be
-  available in ``$HG_PHASE`` while the previous phase will be available in
-  ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE`` will be empty.  In
-  addition, the reason for the transaction opening will be in ``$HG_TXNNAME``,
-  and a unique identifier for the transaction will be in ``HG_TXNID``.
+  is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
+  available variables.
 
 ``txnabort``
   Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1243,6 +1243,14 @@ 
                     repo.hook('pretxnclose-bookmark', throw=True,
                               txnname=desc,
                               **pycompat.strkwargs(args))
+            if hook.hashook(repo.ui, 'pretxnclose-phase'):
+                cl = repo.unfiltered().changelog
+                for rev, (old, new) in tr.changes['phases'].items():
+                    args = tr.hookargs.copy()
+                    node = hex(cl.node(rev))
+                    args.update(phases.preparehookargs(node, old, new))
+                    repo.hook('pretxnclose-phase', throw=True, txnname=desc,
+                              **pycompat.strkwargs(args))
 
             repo.hook('pretxnclose', throw=True,
                       txnname=desc, **pycompat.strkwargs(tr.hookargs))
diff --git a/tests/test-phases.t b/tests/test-phases.t
--- a/tests/test-phases.t
+++ b/tests/test-phases.t
@@ -732,3 +732,94 @@ 
   rollback completed
   abort: pretxnclose hook exited with status 1
   [255]
+
+Check that pretxnclose-phase hook can control phase movement
+
+  $ hg phase --force b3325c91a4d9 --secret
+  test-debug-phase: move rev 3: 0 -> 2
+  test-debug-phase: move rev 4: 0 -> 2
+  test-debug-phase: move rev 5: 1 -> 2
+  test-debug-phase: move rev 7: 0 -> 2
+  test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e:  0 -> 2
+  test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde:  0 -> 2
+  test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8:  1 -> 2
+  test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af:  0 -> 2
+  $ hg log -G -T phases
+  @    changeset:   7:17a481b3bccb
+  |\   tag:         tip
+  | |  phase:       secret
+  | |  parent:      6:cf9fe039dfd6
+  | |  parent:      4:a603bfb5a83e
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     merge B' and E
+  | |
+  | o  changeset:   6:cf9fe039dfd6
+  | |  phase:       public
+  | |  parent:      1:27547f69f254
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     B'
+  | |
+  o |  changeset:   4:a603bfb5a83e
+  | |  phase:       secret
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     E
+  | |
+  o |  changeset:   3:b3325c91a4d9
+  | |  phase:       secret
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     D
+  | |
+  o |  changeset:   2:f838bfaca5c7
+  |/   phase:       public
+  |    user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     C
+  |
+  o  changeset:   1:27547f69f254
+  |  phase:       public
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     B
+  |
+  o  changeset:   0:4a2df7238c3b
+     phase:       public
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     A
+  
+
+Install a hook that prevent b3325c91a4d9 to become public
+
+  $ cat >> .hg/hgrc << EOF
+  > [hooks]
+  > pretxnclose-phase.nopublish_D = (echo \$HG_NODE| grep -v b3325c91a4d9>/dev/null) || [ 0 -lt \$HG_PHASE ]
+  > EOF
+
+Try various actions. only the draft move should succeed
+
+  $ hg phase --public b3325c91a4d9
+  transaction abort!
+  rollback completed
+  abort: pretxnclose-phase.nopublish_D hook exited with status 1
+  [255]
+  $ hg phase --public a603bfb5a83e
+  transaction abort!
+  rollback completed
+  abort: pretxnclose-phase.nopublish_D hook exited with status 1
+  [255]
+  $ hg phase --draft 17a481b3bccb
+  test-debug-phase: move rev 3: 2 -> 1
+  test-debug-phase: move rev 4: 2 -> 1
+  test-debug-phase: move rev 7: 2 -> 1
+  test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e:  2 -> 1
+  test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde:  2 -> 1
+  test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af:  2 -> 1
+  $ hg phase --public 17a481b3bccb
+  transaction abort!
+  rollback completed
+  abort: pretxnclose-phase.nopublish_D hook exited with status 1
+  [255]