D8490: hooks: provide access to transaction changes for hooks

joerg.sonnenberger (Joerg Sonnenberger) phabricator at mercurial-scm.org
Fri May 1 01:32:21 UTC 2020


joerg.sonnenberger created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
joerg.sonnenberger added a comment.


  This is part of a change discussed on IRC to make hooks more useful, e.g. providing better access to which changesets have been obsoleted or making it possible to avoid per changeset hooks with *-phase with a follow-up option to always compute the phase markers. I have some small potential concerns about the environmental size this can have for external hooks, so I'm also open for the idea of providing this argument only for internal hooks.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D8490

AFFECTED FILES
  mercurial/localrepo.py
  tests/test-bundle.t
  tests/test-bundle2-exchange.t
  tests/test-bundle2-multiple-changegroups.t
  tests/test-hook.t
  tests/test-http-bundle1.t
  tests/test-http.t
  tests/test-https.t
  tests/test-push-http.t
  tests/test-ssh-bundle1.t
  tests/test-ssh.t
  tests/test-static-http.t

CHANGE DETAILS

diff --git a/tests/test-static-http.t b/tests/test-static-http.t
--- a/tests/test-static-http.t
+++ b/tests/test-static-http.t
@@ -67,7 +67,8 @@
   adding file changes
   added 1 changesets with 1 changes to 1 files
   new changesets 4ac2e3648604
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 2), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=4ac2e3648604439c580c69b09ec9d93a88d93432
   HG_NODE_LAST=4ac2e3648604439c580c69b09ec9d93a88d93432
diff --git a/tests/test-ssh.t b/tests/test-ssh.t
--- a/tests/test-ssh.t
+++ b/tests/test-ssh.t
@@ -564,6 +564,7 @@
   Got arguments 1:user at dummy 2:hg -R $TESTTMP/local serve --stdio
   Got arguments 1:user at dummy 2:hg -R remote serve --stdio
   changegroup-in-remote hook: HG_BUNDLE2=1
+  HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(0, 3), (1, 0)), (range(3, 4), (None, 0))]}
   HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60
@@ -583,6 +584,7 @@
   Got arguments 1:user at dummy 2:hg -R remote serve --stdio
   Got arguments 1:user at dummy 2:hg -R remote serve --stdio
   changegroup-in-remote hook: HG_BUNDLE2=1
+  HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': [(range(5, 6), (None, 0))]}
   HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6
@@ -611,6 +613,7 @@
   Got arguments 1:user at dummy 2:hg -R 'a repo' serve --stdio
   Got arguments 1:user at dummy 2:hg -R remote serve --stdio
   changegroup-in-remote hook: HG_BUNDLE2=1
+  HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 6, 'phases': [(range(4, 5), (1, 0)), (range(6, 7), (None, 0))]}
   HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8
diff --git a/tests/test-ssh-bundle1.t b/tests/test-ssh-bundle1.t
--- a/tests/test-ssh-bundle1.t
+++ b/tests/test-ssh-bundle1.t
@@ -514,7 +514,8 @@
   Got arguments 1:user at dummy 2:hg -R local serve --stdio
   Got arguments 1:user at dummy 2:hg -R $TESTTMP/local serve --stdio
   Got arguments 1:user at dummy 2:hg -R remote serve --stdio
-  changegroup-in-remote hook: HG_HOOKNAME=changegroup
+  changegroup-in-remote hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(0, 1), (1, 0)), (range(3, 4), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60
   HG_NODE_LAST=a28a9d1a809cab7d4e2fde4bee738a9ede948b60
@@ -533,7 +534,8 @@
   Got arguments 1:user at dummy 2:hg -R remote serve --stdio
   Got arguments 1:user at dummy 2:hg -R remote serve --stdio
   Got arguments 1:user at dummy 2:hg -R remote serve --stdio
-  changegroup-in-remote hook: HG_HOOKNAME=changegroup
+  changegroup-in-remote hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': [(range(5, 6), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6
   HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6
@@ -550,7 +552,8 @@
   Got arguments 1:user at dummy 2:hg -R 'a repo' serve --stdio
   Got arguments 1:user at dummy 2:hg -R 'a repo' serve --stdio
   Got arguments 1:user at dummy 2:hg -R remote serve --stdio
-  changegroup-in-remote hook: HG_HOOKNAME=changegroup
+  changegroup-in-remote hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 6, 'phases': [(range(6, 7), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8
   HG_NODE_LAST=65c38f4125f9602c8db4af56530cc221d93b8ef8
diff --git a/tests/test-push-http.t b/tests/test-push-http.t
--- a/tests/test-push-http.t
+++ b/tests/test-push-http.t
@@ -95,7 +95,8 @@
   remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh
   remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872:   -> public
   remote: running hook changegroup: sh -c "printenv.py --line changegroup 0"
-  remote: changegroup hook: HG_HOOKNAME=changegroup
+  remote: changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]}
+  remote: HG_HOOKNAME=changegroup
   remote: HG_HOOKTYPE=changegroup
   remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872
   remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872
@@ -124,7 +125,8 @@
   remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh
   remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872:   -> public
   remote: running hook changegroup: sh -c "printenv.py --line changegroup 0"
-  remote: changegroup hook: HG_HOOKNAME=changegroup
+  remote: changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]}
+  remote: HG_HOOKNAME=changegroup
   remote: HG_HOOKTYPE=changegroup
   remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872
   remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872
@@ -157,6 +159,7 @@
   remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b:  draft -> public
   remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872:   -> public
   remote: changegroup hook: HG_BUNDLE2=1
+  remote: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]}
   remote: HG_HOOKNAME=changegroup
   remote: HG_HOOKTYPE=changegroup
   remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872
@@ -184,9 +187,10 @@
   remote: added 1 changesets with 1 changes to 1 files
   remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b:  draft -> public
   remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872:   -> public
-  remote: changegroup hook: HG_HOOKNAME=changegroup (no-bundle2 !)
+  remote: changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]} (no-bundle2 !)
   remote: changegroup hook: HG_BUNDLE2=1 (bundle2 !)
-  remote: HG_HOOKNAME=changegroup (bundle2 !)
+  remote: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]} (bundle2 !)
+  remote: HG_HOOKNAME=changegroup
   remote: HG_HOOKTYPE=changegroup
   remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872
   remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872
@@ -213,9 +217,10 @@
   remote: added 1 changesets with 1 changes to 1 files
   remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b:  draft -> public
   remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872:   -> public
-  remote: changegroup hook: HG_HOOKNAME=changegroup (no-bundle2 !)
+  remote: changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]} (no-bundle2 !)
   remote: changegroup hook: HG_BUNDLE2=1 (bundle2 !)
-  remote: HG_HOOKNAME=changegroup (bundle2 !)
+  remote: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]} (bundle2 !)
+  remote: HG_HOOKNAME=changegroup
   remote: HG_HOOKTYPE=changegroup
   remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872
   remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872
@@ -255,8 +260,10 @@
   remote: added 1 changesets with 1 changes to 1 files
   remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b:  draft -> public
   remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872:   -> public
-  remote: changegroup hook: * (glob)
-  remote: HG_HOOKNAME=changegroup (bundle2 !)
+  remote: changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]} (no-bundle2 !)
+  remote: changegroup hook: HG_BUNDLE2=1 (bundle2 !)
+  remote: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]} (bundle2 !)
+  remote: HG_HOOKNAME=changegroup
   remote: HG_HOOKTYPE=changegroup
   remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872
   remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872
@@ -310,6 +317,7 @@
   remote: adding manifests
   remote: adding file changes
   remote: prepushkey hook: HG_BUNDLE2=1
+  remote: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]}
   remote: HG_HOOKNAME=prepushkey
   remote: HG_HOOKTYPE=prepushkey
   remote: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872
@@ -351,6 +359,7 @@
   remote: adding manifests
   remote: adding file changes
   remote: prepushkey hook: HG_BUNDLE2=1
+  remote: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(0, 1), (1, 0)), (range(1, 2), (None, 0))]}
   remote: HG_HOOKNAME=prepushkey
   remote: HG_HOOKTYPE=prepushkey
   remote: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872
@@ -410,6 +419,7 @@
   remote: adding manifests
   remote: adding file changes
   remote: prepushkey hook: HG_BUNDLE2=1
+  remote: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 2), (None, 1))]}
   remote: HG_HOOKNAME=prepushkey
   remote: HG_HOOKTYPE=prepushkey
   remote: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872
@@ -464,6 +474,7 @@
   remote: adding manifests
   remote: adding file changes
   remote: prepushkey hook: HG_BUNDLE2=1
+  remote: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 2), (None, 1))]}
   remote: HG_HOOKNAME=prepushkey
   remote: HG_HOOKTYPE=prepushkey
   remote: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872
diff --git a/tests/test-https.t b/tests/test-https.t
--- a/tests/test-https.t
+++ b/tests/test-https.t
@@ -232,7 +232,8 @@
   adding file changes
   added 1 changesets with 1 changes to 1 files
   new changesets 5fed3813f7f5
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 2), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
   HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
diff --git a/tests/test-http.t b/tests/test-http.t
--- a/tests/test-http.t
+++ b/tests/test-http.t
@@ -150,7 +150,8 @@
   adding file changes
   added 1 changesets with 1 changes to 1 files
   new changesets 5fed3813f7f5
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 2), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
   HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
diff --git a/tests/test-http-bundle1.t b/tests/test-http-bundle1.t
--- a/tests/test-http-bundle1.t
+++ b/tests/test-http-bundle1.t
@@ -161,7 +161,8 @@
   adding file changes
   added 1 changesets with 1 changes to 1 files
   new changesets 5fed3813f7f5
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 2), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
   HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -48,14 +48,16 @@
   HG_PENDING=$TESTTMP/a
   
   0:cb9a9f314b8b
-  pretxnclose hook: HG_HOOKNAME=pretxnclose
+  pretxnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 0, 'phases': [(range(0, 1), (None, 1))]}
+  HG_HOOKNAME=pretxnclose
   HG_HOOKTYPE=pretxnclose
   HG_PENDING=$TESTTMP/a
   HG_PHASES_MOVED=1
   HG_TXNID=TXN:$ID$
   HG_TXNNAME=commit
   
-  txnclose hook: HG_HOOKNAME=txnclose
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 0, 'phases': [(range(0, 1), (None, 1))]}
+  HG_HOOKNAME=txnclose
   HG_HOOKTYPE=txnclose
   HG_PHASES_MOVED=1
   HG_TXNID=TXN:$ID$
@@ -107,13 +109,15 @@
   HG_PENDING=$TESTTMP/a
   
   1:ab228980c14d
-  pretxnclose hook: HG_HOOKNAME=pretxnclose
+  pretxnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 2), (None, 1))]}
+  HG_HOOKNAME=pretxnclose
   HG_HOOKTYPE=pretxnclose
   HG_PENDING=$TESTTMP/a
   HG_TXNID=TXN:$ID$
   HG_TXNNAME=commit
   
-  txnclose hook: HG_HOOKNAME=txnclose
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 2), (None, 1))]}
+  HG_HOOKNAME=txnclose
   HG_HOOKTYPE=txnclose
   HG_TXNID=TXN:$ID$
   HG_TXNNAME=commit
@@ -149,14 +153,16 @@
   HG_PENDING=$TESTTMP/a
   
   2:ee9deb46ab31
-  pretxnclose hook: HG_HOOKNAME=pretxnclose
+  pretxnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 2, 'phases': [(range(2, 3), (None, 1))]}
+  HG_HOOKNAME=pretxnclose
   HG_HOOKTYPE=pretxnclose
   HG_PENDING=$TESTTMP/a
   HG_TXNID=TXN:$ID$
   HG_TXNNAME=commit
   
   created new head
-  txnclose hook: HG_HOOKNAME=txnclose
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 2, 'phases': [(range(2, 3), (None, 1))]}
+  HG_HOOKNAME=txnclose
   HG_HOOKTYPE=txnclose
   HG_TXNID=TXN:$ID$
   HG_TXNNAME=commit
@@ -193,13 +199,15 @@
   HG_PENDING=$TESTTMP/a
   
   3:07f3376c1e65
-  pretxnclose hook: HG_HOOKNAME=pretxnclose
+  pretxnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(3, 4), (None, 1))]}
+  HG_HOOKNAME=pretxnclose
   HG_HOOKTYPE=pretxnclose
   HG_PENDING=$TESTTMP/a
   HG_TXNID=TXN:$ID$
   HG_TXNNAME=commit
   
-  txnclose hook: HG_HOOKNAME=txnclose
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(3, 4), (None, 1))]}
+  HG_HOOKNAME=txnclose
   HG_HOOKTYPE=txnclose
   HG_TXNID=TXN:$ID$
   HG_TXNNAME=commit
@@ -248,7 +256,8 @@
   $ hg pull ../a
   pulling from ../a
   searching for changes
-  prechangegroup hook: HG_HOOKNAME=prechangegroup
+  prechangegroup hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': []}
+  HG_HOOKNAME=prechangegroup
   HG_HOOKTYPE=prechangegroup
   HG_SOURCE=pull
   HG_TXNID=TXN:$ID$
@@ -261,7 +270,8 @@
   adding file changes
   added 3 changesets with 2 changes to 2 files
   new changesets ab228980c14d:07f3376c1e65
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 3, 'changegroup-count-files': 2, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 2, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 4), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
   HG_NODE_LAST=07f3376c1e655977439df2a814e3cc14b27abac2
@@ -271,7 +281,8 @@
   file:/*/$TESTTMP/a (glob)
   HG_URL=file:$TESTTMP/a
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 3, 'changegroup-count-files': 2, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 2, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 4), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
   HG_SOURCE=pull
@@ -280,7 +291,8 @@
   file:/*/$TESTTMP/a (glob)
   HG_URL=file:$TESTTMP/a
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 3, 'changegroup-count-files': 2, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 2, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 4), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
   HG_SOURCE=pull
@@ -289,7 +301,8 @@
   file:/*/$TESTTMP/a (glob)
   HG_URL=file:$TESTTMP/a
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 3, 'changegroup-count-files': 2, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 2, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 4), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
   HG_SOURCE=pull
@@ -330,7 +343,8 @@
   HG_PENDING=$TESTTMP/a
   
   4:539e4b31b6dc
-  pretxnclose hook: HG_HOOKNAME=pretxnclose
+  pretxnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 4, 'phases': [(range(4, 5), (None, 1))]}
+  HG_HOOKNAME=pretxnclose
   HG_HOOKTYPE=pretxnclose
   HG_PENDING=$TESTTMP/a
   HG_TXNID=TXN:$ID$
@@ -342,7 +356,8 @@
   HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
   HG_TAG=a
   
-  txnclose hook: HG_HOOKNAME=txnclose
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 4, 'phases': [(range(4, 5), (None, 1))]}
+  HG_HOOKNAME=txnclose
   HG_HOOKTYPE=txnclose
   HG_TXNID=TXN:$ID$
   HG_TXNNAME=commit
@@ -443,8 +458,9 @@
   HG_PENDING=$TESTTMP/a
   
   transaction abort!
-  txnabort Python hook: txnid,txnname
-  txnabort hook: HG_HOOKNAME=txnabort.1
+  txnabort Python hook: changes,txnid,txnname
+  txnabort hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': []}
+  HG_HOOKNAME=txnabort.1
   HG_HOOKTYPE=txnabort
   HG_TXNID=TXN:$ID$
   HG_TXNNAME=commit
@@ -536,6 +552,7 @@
   
   pretxnclose hook: HG_BOOKMARK_MOVED=1
   HG_BUNDLE2=1
+  HG_CHANGES={'bookmarks': {'foo': (None, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')}, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': []}
   HG_HOOKNAME=pretxnclose
   HG_HOOKTYPE=pretxnclose
   HG_PENDING=$TESTTMP/a
@@ -545,6 +562,7 @@
   HG_URL=file:$TESTTMP/a
   
   pushkey hook: HG_BUNDLE2=1
+  HG_CHANGES={'bookmarks': {'foo': (None, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')}, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': []}
   HG_HOOKNAME=pushkey
   HG_HOOKTYPE=pushkey
   HG_KEY=foo
@@ -558,6 +576,7 @@
   
   txnclose hook: HG_BOOKMARK_MOVED=1
   HG_BUNDLE2=1
+  HG_CHANGES={'bookmarks': {'foo': (None, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')}, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': []}
   HG_HOOKNAME=txnclose
   HG_HOOKTYPE=txnclose
   HG_SOURCE=push
@@ -581,6 +600,7 @@
   HG_TXNNAME=bookmark
   
   pretxnclose hook: HG_BOOKMARK_MOVED=1
+  HG_CHANGES={'bookmarks': {'bar': (None, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')}, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': []}
   HG_HOOKNAME=pretxnclose
   HG_HOOKTYPE=pretxnclose
   HG_PENDING=$TESTTMP/a
@@ -588,6 +608,7 @@
   HG_TXNNAME=bookmark
   
   txnclose hook: HG_BOOKMARK_MOVED=1
+  HG_CHANGES={'bookmarks': {'bar': (None, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')}, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': []}
   HG_HOOKNAME=txnclose
   HG_HOOKTYPE=txnclose
   HG_TXNID=TXN:$ID$
@@ -632,6 +653,7 @@
   HG_TXNNAME=push
   
   prepushkey.forbid hook: HG_BUNDLE2=1
+  HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': []}
   HG_HOOKNAME=prepushkey
   HG_HOOKTYPE=prepushkey
   HG_KEY=baz
@@ -659,6 +681,7 @@
   HG_TXNNAME=bookmark
   
   pretxnclose hook: HG_BOOKMARK_MOVED=1
+  HG_CHANGES={'bookmarks': {'quux': (None, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')}, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': []}
   HG_HOOKNAME=pretxnclose
   HG_HOOKTYPE=pretxnclose
   HG_PENDING=$TESTTMP/a
@@ -666,6 +689,7 @@
   HG_TXNNAME=bookmark
   
   txnclose hook: HG_BOOKMARK_MOVED=1
+  HG_CHANGES={'bookmarks': {'quux': (None, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')}, 'obsmarkers': set([]), 'origrepolen': 5, 'phases': []}
   HG_HOOKNAME=txnclose
   HG_HOOKTYPE=txnclose
   HG_TXNID=TXN:$ID$
@@ -695,7 +719,8 @@
   $ hg pull ../a
   pulling from ../a
   searching for changes
-  prechangegroup.forbid hook: HG_HOOKNAME=prechangegroup.forbid
+  prechangegroup.forbid hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 4, 'phases': []}
+  HG_HOOKNAME=prechangegroup.forbid
   HG_HOOKTYPE=prechangegroup
   HG_SOURCE=pull
   HG_TXNID=TXN:$ID$
@@ -721,7 +746,8 @@
   adding manifests
   adding file changes
   4:539e4b31b6dc
-  pretxnchangegroup.forbid hook: HG_HOOKNAME=pretxnchangegroup.forbid1
+  pretxnchangegroup.forbid hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 4, 'phases': []}
+  HG_HOOKNAME=pretxnchangegroup.forbid1
   HG_HOOKTYPE=pretxnchangegroup
   HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
   HG_NODE_LAST=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
diff --git a/tests/test-bundle2-multiple-changegroups.t b/tests/test-bundle2-multiple-changegroups.t
--- a/tests/test-bundle2-multiple-changegroups.t
+++ b/tests/test-bundle2-multiple-changegroups.t
@@ -80,7 +80,8 @@
   adding changesets
   adding manifests
   adding file changes
-  pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
+  pretxnchangegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': []}
+  HG_HOOKNAME=pretxnchangegroup
   HG_HOOKTYPE=pretxnchangegroup
   HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56
   HG_NODE_LAST=27547f69f25460a52fff66ad004e58da7ad3fb56
@@ -95,7 +96,8 @@
   adding changesets
   adding manifests
   adding file changes
-  pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
+  pretxnchangegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 2, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 2, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 2), (None, 1))]}
+  HG_HOOKNAME=pretxnchangegroup
   HG_HOOKTYPE=pretxnchangegroup
   HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
   HG_NODE_LAST=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
@@ -109,7 +111,8 @@
   
   added 2 changesets with 2 changes to 2 files
   new changesets 27547f69f254:f838bfaca5c7
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 2, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 2, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 3), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56
   HG_NODE_LAST=27547f69f25460a52fff66ad004e58da7ad3fb56
@@ -119,7 +122,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 2, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 2, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 3), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56
   HG_SOURCE=pull
@@ -128,7 +132,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 2, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 2, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 3), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
   HG_NODE_LAST=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
@@ -139,7 +144,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 2, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 2, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 3), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
   HG_PHASES_MOVED=1
@@ -207,7 +213,8 @@
   adding changesets
   adding manifests
   adding file changes
-  pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
+  pretxnchangegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 2, 'changegroup-count-heads': 1, 'changegroup-count-revisions': 2, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': []}
+  HG_HOOKNAME=pretxnchangegroup
   HG_HOOKTYPE=pretxnchangegroup
   HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
   HG_NODE_LAST=8a5212ebc8527f9fb821601504794e3eb11a1ed3
@@ -222,7 +229,8 @@
   adding changesets
   adding manifests
   adding file changes
-  pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
+  pretxnchangegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 5, 'changegroup-count-files': 5, 'changegroup-count-heads': 2, 'changegroup-count-revisions': 5, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(3, 5), (None, 1))]}
+  HG_HOOKNAME=pretxnchangegroup
   HG_HOOKTYPE=pretxnchangegroup
   HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46
   HG_NODE_LAST=5cd59d311f6508b8e0ed28a266756c859419c9f1
@@ -236,7 +244,8 @@
   
   added 5 changesets with 5 changes to 5 files (+2 heads)
   new changesets b3325c91a4d9:5cd59d311f65
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 5, 'changegroup-count-files': 5, 'changegroup-count-heads': 2, 'changegroup-count-revisions': 5, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(3, 8), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
   HG_NODE_LAST=8a5212ebc8527f9fb821601504794e3eb11a1ed3
@@ -246,7 +255,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 5, 'changegroup-count-files': 5, 'changegroup-count-heads': 2, 'changegroup-count-revisions': 5, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(3, 8), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
   HG_SOURCE=pull
@@ -255,7 +265,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 5, 'changegroup-count-files': 5, 'changegroup-count-heads': 2, 'changegroup-count-revisions': 5, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(3, 8), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=8a5212ebc8527f9fb821601504794e3eb11a1ed3
   HG_SOURCE=pull
@@ -264,7 +275,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 5, 'changegroup-count-files': 5, 'changegroup-count-heads': 2, 'changegroup-count-revisions': 5, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(3, 8), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46
   HG_NODE_LAST=5cd59d311f6508b8e0ed28a266756c859419c9f1
@@ -275,7 +287,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 5, 'changegroup-count-files': 5, 'changegroup-count-heads': 2, 'changegroup-count-revisions': 5, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(3, 8), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46
   HG_PHASES_MOVED=1
@@ -285,7 +298,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 5, 'changegroup-count-files': 5, 'changegroup-count-heads': 2, 'changegroup-count-revisions': 5, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(3, 8), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=1d14c3ce6ac0582d2809220d33e8cd7a696e0156
   HG_PHASES_MOVED=1
@@ -295,7 +309,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 5, 'changegroup-count-files': 5, 'changegroup-count-heads': 2, 'changegroup-count-revisions': 5, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(3, 8), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=5cd59d311f6508b8e0ed28a266756c859419c9f1
   HG_PHASES_MOVED=1
@@ -363,7 +378,8 @@
   adding changesets
   adding manifests
   adding file changes
-  pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
+  pretxnchangegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 0, 'changegroup-count-heads': -1, 'changegroup-count-revisions': 0, 'obsmarkers': set([]), 'origrepolen': 8, 'phases': []}
+  HG_HOOKNAME=pretxnchangegroup
   HG_HOOKTYPE=pretxnchangegroup
   HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4
   HG_NODE_LAST=71bd7b46de72e69a32455bf88d04757d542e6cf4
@@ -378,7 +394,8 @@
   adding changesets
   adding manifests
   adding file changes
-  pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
+  pretxnchangegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 1, 'changegroup-count-heads': -1, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 8, 'phases': [(range(8, 9), (None, 1))]}
+  HG_HOOKNAME=pretxnchangegroup
   HG_HOOKTYPE=pretxnchangegroup
   HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84
   HG_NODE_LAST=9d18e5bd9ab09337802595d49f1dad0c98df4d84
@@ -392,7 +409,8 @@
   
   added 2 changesets with 1 changes to 1 files (-1 heads)
   new changesets 71bd7b46de72:9d18e5bd9ab0
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 1, 'changegroup-count-heads': -1, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 8, 'phases': [(range(8, 10), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4
   HG_NODE_LAST=71bd7b46de72e69a32455bf88d04757d542e6cf4
@@ -402,7 +420,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 1, 'changegroup-count-heads': -1, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 8, 'phases': [(range(8, 10), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4
   HG_SOURCE=pull
@@ -411,7 +430,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 1, 'changegroup-count-heads': -1, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 8, 'phases': [(range(8, 10), (None, 0))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84
   HG_NODE_LAST=9d18e5bd9ab09337802595d49f1dad0c98df4d84
@@ -422,7 +442,8 @@
   file:/*/$TESTTMP/repo (glob)
   HG_URL=file:$TESTTMP/repo
   
-  incoming hook: HG_HOOKNAME=incoming
+  incoming hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 1, 'changegroup-count-heads': -1, 'changegroup-count-revisions': 1, 'obsmarkers': set([]), 'origrepolen': 8, 'phases': [(range(8, 10), (None, 0))]}
+  HG_HOOKNAME=incoming
   HG_HOOKTYPE=incoming
   HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84
   HG_PHASES_MOVED=1
diff --git a/tests/test-bundle2-exchange.t b/tests/test-bundle2-exchange.t
--- a/tests/test-bundle2-exchange.t
+++ b/tests/test-bundle2-exchange.t
@@ -52,7 +52,7 @@
   $ hg commit -m 'a'
   pre-close-tip:3903775176ed draft 
   postclose-tip:3903775176ed draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 0, 'phases': [(range(0, 1), (None, 1))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
 
   $ hg unbundle $TESTDIR/bundles/rebase.hg
   adding changesets
@@ -62,7 +62,7 @@
   added 8 changesets with 7 changes to 7 files (+3 heads)
   new changesets cd010b8cd998:02de42196ebe (8 drafts)
   postclose-tip:02de42196ebe draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=unbundle HG_TXNID=TXN:$ID$ HG_TXNNAME=unbundle
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 8, 'changegroup-count-files': 7, 'changegroup-count-heads': 3, 'changegroup-count-revisions': 7, 'obsmarkers': set([]), 'origrepolen': 1, 'phases': [(range(1, 9), (None, 1))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=unbundle HG_TXNID=TXN:$ID$ HG_TXNNAME=unbundle
   bundle:*/tests/bundles/rebase.hg HG_URL=bundle:*/tests/bundles/rebase.hg (glob)
   (run 'hg heads' to see heads, 'hg merge' to merge)
 
@@ -77,19 +77,19 @@
   pre-close-tip:02de42196ebe draft 
   1 new obsolescence markers
   postclose-tip:02de42196ebe draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([('\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11', ('\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba'), 0, (('user', 'test')), (0, 0), None)]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
   $ hg -R main debugobsolete -d '0 0' 2222222222222222222222222222222222222222 `getmainid 24b6387c8c8c`
   pre-close-tip:02de42196ebe draft 
   1 new obsolescence markers
   postclose-tip:02de42196ebe draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([('""""""""""""""""""""', ('$\xb68|\x8c\x8c\xae7\x17\x88\x80\xf3\xfa\x95\xde\xd3\xcb\x1c\xf7\x85'), 0, (('user', 'test')), (0, 0), None)]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
 
 clone --pull
 
   $ hg -R main phase --public cd010b8cd998
   pre-close-tip:02de42196ebe draft 
   postclose-tip:02de42196ebe draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': [(range(1, 2), (1, 0))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
   $ hg clone main other --pull --rev 9520eea781bc
   adding changesets
   adding manifests
@@ -99,7 +99,7 @@
   1 new obsolescence markers
   new changesets cd010b8cd998:9520eea781bc (1 drafts)
   postclose-tip:9520eea781bc draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=9520eea781bcca16c1e15acc0ba14335a0e8e5ba HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 2, 'changegroup-count-files': 2, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 2, 'obsmarkers': set([('\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11', ('\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba'), 0, (('user', 'test')), (0.0, 0), None)]), 'origrepolen': 0, 'phases': [(range(0, 1), (None, 0)), (range(1, 2), (None, 1))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=9520eea781bcca16c1e15acc0ba14335a0e8e5ba HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
   file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
   updating to branch default
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -116,7 +116,7 @@
   $ hg -R main phase --public 9520eea781bc
   pre-close-tip:02de42196ebe draft 
   postclose-tip:02de42196ebe draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': [(range(5, 6), (1, 0))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
   $ hg -R other pull -r 24b6387c8c8c
   pulling from $TESTTMP/main
   searching for changes
@@ -128,7 +128,7 @@
   1 new obsolescence markers
   new changesets 24b6387c8c8c (1 drafts)
   postclose-tip:24b6387c8c8c draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_NODE_LAST=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 1, 'changegroup-count-revisions': 1, 'obsmarkers': set([('""""""""""""""""""""', ('$\xb68|\x8c\x8c\xae7\x17\x88\x80\xf3\xfa\x95\xde\xd3\xcb\x1c\xf7\x85'), 0, (('user', 'test')), (0.0, 0), None)]), 'origrepolen': 2, 'phases': [(range(2, 3), (None, 1))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_NODE_LAST=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
   file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg -R other log -G
@@ -147,14 +147,14 @@
   $ hg -R main phase --public 24b6387c8c8c
   pre-close-tip:02de42196ebe draft 
   postclose-tip:02de42196ebe draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': [(range(6, 7), (1, 0))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
   $ hg -R other pull -r 24b6387c8c8c
   pulling from $TESTTMP/main
   no changes found
   pre-close-tip:24b6387c8c8c public 
   1 local changesets published
   postclose-tip:24b6387c8c8c public 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=0 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': [(range(2, 3), (1, 0))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=0 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
   file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
   $ hg -R other log -G
   o  2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits at gmail.com>  F
@@ -174,7 +174,7 @@
   no changes found
   pre-close-tip:24b6387c8c8c public 
   postclose-tip:24b6387c8c8c public 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=0 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=0 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
   file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
   $ hg -R other log -G
   o  2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits at gmail.com>  F
@@ -192,74 +192,74 @@
   $ hg -R main bookmark --rev eea13746799a book_eea1
   pre-close-tip:02de42196ebe draft 
   postclose-tip:02de42196ebe draft 
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_eea1': (None, '\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO')}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
   $ hg -R main debugobsolete -d '0 0' 3333333333333333333333333333333333333333 `getmainid eea13746799a`
   pre-close-tip:02de42196ebe draft 
   1 new obsolescence markers
   postclose-tip:02de42196ebe draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([('33333333333333333333', ('\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO'), 0, (('user', 'test')), (0, 0), None)]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
   $ hg -R main bookmark --rev 02de42196ebe book_02de
   pre-close-tip:02de42196ebe draft book_02de
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_02de': (None, '\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x\n\x87\xcd\xc9n\x8e\xaa\xb6')}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
   $ hg -R main debugobsolete -d '0 0' 4444444444444444444444444444444444444444 `getmainid 02de42196ebe`
   pre-close-tip:02de42196ebe draft book_02de
   1 new obsolescence markers
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([('DDDDDDDDDDDDDDDDDDDD', ('\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x\n\x87\xcd\xc9n\x8e\xaa\xb6'), 0, (('user', 'test')), (0, 0), None)]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
   $ hg -R main bookmark --rev 42ccdea3bb16 book_42cc
   pre-close-tip:02de42196ebe draft book_02de
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_42cc': (None, 'B\xcc\xde\xa3\xbb\x16\xd2\x8e\x18H\xc9_\xe2\xe4L\x00\x0f?!\xb1')}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
   $ hg -R main debugobsolete -d '0 0' 5555555555555555555555555555555555555555 `getmainid 42ccdea3bb16`
   pre-close-tip:02de42196ebe draft book_02de
   1 new obsolescence markers
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([('UUUUUUUUUUUUUUUUUUUU', ('B\xcc\xde\xa3\xbb\x16\xd2\x8e\x18H\xc9_\xe2\xe4L\x00\x0f?!\xb1'), 0, (('user', 'test')), (0, 0), None)]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
   $ hg -R main bookmark --rev 5fddd98957c8 book_5fdd
   pre-close-tip:02de42196ebe draft book_02de
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_5fdd': (None, '_\xdd\xd9\x89W\xc8\xa5JMCm\xfe\x1d\xa9\xd8\x7f!\xa1\xb9{')}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
   $ hg -R main debugobsolete -d '0 0' 6666666666666666666666666666666666666666 `getmainid 5fddd98957c8`
   pre-close-tip:02de42196ebe draft book_02de
   1 new obsolescence markers
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([('ffffffffffffffffffff', ('_\xdd\xd9\x89W\xc8\xa5JMCm\xfe\x1d\xa9\xd8\x7f!\xa1\xb9{'), 0, (('user', 'test')), (0, 0), None)]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
   $ hg -R main bookmark --rev 32af7686d403 book_32af
   pre-close-tip:02de42196ebe draft book_02de
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_32af': (None, '2\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j')}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
   $ hg -R main debugobsolete -d '0 0' 7777777777777777777777777777777777777777 `getmainid 32af7686d403`
   pre-close-tip:02de42196ebe draft book_02de
   1 new obsolescence markers
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([('wwwwwwwwwwwwwwwwwwww', ('2\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j'), 0, (('user', 'test')), (0, 0), None)]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
 
   $ hg -R other bookmark --rev cd010b8cd998 book_eea1
   pre-close-tip:24b6387c8c8c public 
   postclose-tip:24b6387c8c8c public 
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_eea1': (None, '\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89')}, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
   $ hg -R other bookmark --rev cd010b8cd998 book_02de
   pre-close-tip:24b6387c8c8c public 
   postclose-tip:24b6387c8c8c public 
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_02de': (None, '\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89')}, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
   $ hg -R other bookmark --rev cd010b8cd998 book_42cc
   pre-close-tip:24b6387c8c8c public 
   postclose-tip:24b6387c8c8c public 
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_42cc': (None, '\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89')}, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
   $ hg -R other bookmark --rev cd010b8cd998 book_5fdd
   pre-close-tip:24b6387c8c8c public 
   postclose-tip:24b6387c8c8c public 
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_5fdd': (None, '\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89')}, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
   $ hg -R other bookmark --rev cd010b8cd998 book_32af
   pre-close-tip:24b6387c8c8c public 
   postclose-tip:24b6387c8c8c public 
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_32af': (None, '\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89')}, 'obsmarkers': set([]), 'origrepolen': 3, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
 
   $ hg -R main phase --public eea13746799a
   pre-close-tip:02de42196ebe draft book_02de
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': [(range(7, 8), (1, 0))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
 
 push
   $ hg -R main push other --rev eea13746799a --bookmark book_eea1
@@ -275,11 +275,11 @@
   remote: lock:  free
   remote: wlock: free
   remote: postclose-tip:eea13746799a public book_eea1
-  remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_NODE_LAST=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_PHASES_MOVED=1 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/other
+  remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_CHANGES={'bookmarks': {'book_eea1': ('\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89', '\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO')}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 0, 'changegroup-count-heads': -1, 'changegroup-count-revisions': 0, 'obsmarkers': set([('33333333333333333333', ('\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO'), 0, (('user', 'test')), (0.0, 0), None)]), 'origrepolen': 3, 'phases': [(range(1, 2), (1, 0)), (range(3, 4), (None, 0))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_NODE_LAST=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_PHASES_MOVED=1 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/other
   updating bookmark book_eea1
   pre-close-tip:02de42196ebe draft book_02de
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
   file:/*/$TESTTMP/other HG_URL=file:$TESTTMP/other (glob)
   $ hg -R other log -G
   o    3:eea13746799a public Nicolas Dumazet <nicdumz.commits at gmail.com> book_eea1 G
@@ -309,7 +309,7 @@
   1 new obsolescence markers
   new changesets 02de42196ebe (1 drafts)
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_02de': ('\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89', '\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x\n\x87\xcd\xc9n\x8e\xaa\xb6')}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 1, 'changegroup-count-revisions': 1, 'obsmarkers': set([('DDDDDDDDDDDDDDDDDDDD', ('\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x\n\x87\xcd\xc9n\x8e\xaa\xb6'), 0, (('user', 'test')), (0.0, 0), None)]), 'origrepolen': 4, 'phases': [(range(4, 5), (None, 1))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
   ssh://user@dummy/main HG_URL=ssh://user@dummy/main
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg -R other debugobsolete
@@ -335,7 +335,7 @@
   1 new obsolescence markers
   new changesets 42ccdea3bb16 (1 drafts)
   postclose-tip:42ccdea3bb16 draft book_42cc
-  txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_NODE_LAST=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
+  txnclose hook: HG_BOOKMARK_MOVED=1 HG_CHANGES={'bookmarks': {'book_42cc': ('\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89', 'B\xcc\xde\xa3\xbb\x16\xd2\x8e\x18H\xc9_\xe2\xe4L\x00\x0f?!\xb1')}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 1, 'changegroup-count-revisions': 1, 'obsmarkers': set([('UUUUUUUUUUUUUUUUUUUU', ('B\xcc\xde\xa3\xbb\x16\xd2\x8e\x18H\xc9_\xe2\xe4L\x00\x0f?!\xb1'), 0, (('user', 'test')), (0.0, 0), None)]), 'origrepolen': 5, 'phases': [(range(5, 6), (None, 1))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_NODE_LAST=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
   http://localhost:$HGPORT/ HG_URL=http://localhost:$HGPORT/
   (run 'hg heads .' to see heads, 'hg merge' to merge)
   $ cat main-error.log
@@ -361,11 +361,11 @@
   remote: lock:  free
   remote: wlock: free
   remote: postclose-tip:5fddd98957c8 draft book_5fdd
-  remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_NODE_LAST=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:ssh:$LOCALIP
+  remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_CHANGES={'bookmarks': {'book_5fdd': ('\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89', '_\xdd\xd9\x89W\xc8\xa5JMCm\xfe\x1d\xa9\xd8\x7f!\xa1\xb9{')}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([('ffffffffffffffffffff', ('_\xdd\xd9\x89W\xc8\xa5JMCm\xfe\x1d\xa9\xd8\x7f!\xa1\xb9{'), 0, (('user', 'test')), (0.0, 0), None)]), 'origrepolen': 6, 'phases': [(range(6, 7), (None, 1))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_NODE_LAST=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:ssh:$LOCALIP (glob)
   updating bookmark book_5fdd
   pre-close-tip:02de42196ebe draft book_02de
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
   ssh://user@dummy/other HG_URL=ssh://user@dummy/other
   $ hg -R other log -G
   o  6:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits at gmail.com> book_5fdd C
@@ -398,7 +398,7 @@
   $ hg -R main phase --public 32af7686d403
   pre-close-tip:02de42196ebe draft book_02de
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': [(range(2, 5), (1, 0))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
   $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403 --bookmark book_32af
   pushing to http://localhost:$HGPORT2/
   searching for changes
@@ -412,11 +412,11 @@
   remote: lock:  free
   remote: wlock: free
   remote: postclose-tip:32af7686d403 public book_32af
-  remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=32af7686d403cf45b5d95f2d70cebea587ac806a HG_NODE_LAST=32af7686d403cf45b5d95f2d70cebea587ac806a HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:http:$LOCALIP: (glob)
+  remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_CHANGES={'bookmarks': {'book_32af': ('\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89', '2\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j')}, 'changegroup-count-changesets': 1, 'changegroup-count-files': 1, 'changegroup-count-heads': 0, 'changegroup-count-revisions': 1, 'obsmarkers': set([('wwwwwwwwwwwwwwwwwwww', ('2\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j'), 0, (('user', 'test')), (0.0, 0), None)]), 'origrepolen': 7, 'phases': [(range(5, 7), (1, 0)), (range(7, 8), (None, 0))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=32af7686d403cf45b5d95f2d70cebea587ac806a HG_NODE_LAST=32af7686d403cf45b5d95f2d70cebea587ac806a HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:http:$LOCALIP: (glob)
   updating bookmark book_32af
   pre-close-tip:02de42196ebe draft book_02de
   postclose-tip:02de42196ebe draft book_02de
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': []} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
   http://localhost:$HGPORT2/ HG_URL=http://localhost:$HGPORT2/
   $ cat other-error.log
 
@@ -513,7 +513,7 @@
   $ hg ci -m 'I'
   pre-close-tip:e7ec4e813ba6 draft 
   postclose-tip:e7ec4e813ba6 draft 
-  txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
+  txnclose hook: HG_CHANGES={'bookmarks': {}, 'obsmarkers': set([]), 'origrepolen': 9, 'phases': [(range(9, 10), (None, 1))]} HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
   $ hg id
   e7ec4e813ba6 tip
   $ cd ..
diff --git a/tests/test-bundle.t b/tests/test-bundle.t
--- a/tests/test-bundle.t
+++ b/tests/test-bundle.t
@@ -234,7 +234,8 @@
   adding file changes
   added 9 changesets with 7 changes to 4 files (+1 heads)
   new changesets f9ee2f85a263:aa35859c02ea (9 drafts)
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 9, 'changegroup-count-files': 4, 'changegroup-count-heads': 1, 'changegroup-count-revisions': 7, 'obsmarkers': set([]), 'origrepolen': 0, 'phases': [(range(0, 9), (None, 1))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735
   HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf
@@ -269,7 +270,8 @@
   adding file changes
   added 9 changesets with 7 changes to 4 files (+1 heads)
   new changesets f9ee2f85a263:aa35859c02ea (9 drafts)
-  changegroup hook: HG_HOOKNAME=changegroup
+  changegroup hook: HG_CHANGES={'bookmarks': {}, 'changegroup-count-changesets': 9, 'changegroup-count-files': 4, 'changegroup-count-heads': 1, 'changegroup-count-revisions': 7, 'obsmarkers': set([]), 'origrepolen': 0, 'phases': [(range(0, 9), (None, 1))]}
+  HG_HOOKNAME=changegroup
   HG_HOOKTYPE=changegroup
   HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735
   HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -2237,6 +2237,7 @@
 
         tr.hookargs[b'txnid'] = txnid
         tr.hookargs[b'txnname'] = desc
+        tr.hookargs[b'changes'] = tr.changes
         # 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.



To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-patches, mercurial-devel


More information about the Mercurial-devel mailing list