@@ -846,3 +846,12 @@
bmarks[bmark] = (n, prefix, label)
_printbookmarks(ui, repo, bmarks, **opts)
+
+def preparehookargs(name, old, new):
+ if new is None:
+ new = ''
+ if old is None:
+ old = ''
+ return {'bookmark': name,
+ 'node': hex(new),
+ 'oldnode': hex(old)}
@@ -982,6 +982,18 @@
after the lock is released. See :hg:`help config.hooks.pretxnclose` for
details about available variables.
+``txnclose-bookmark``
+ Run after any bookmark 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 name of the bookmark will be available in ``$HG_BOOKMARK``, the new
+ bookmark location will be available in ``$HG_NODE`` while the previous
+ location will be available in ``$HG_OLDNODE``. In case of a bookmark
+ creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
+ 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``.
+
``txnabort``
Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
for details about available variables.
@@ -1280,10 +1280,19 @@
# fixes the function accumulation.
hookargs = tr2.hookargs
- def hook():
- reporef().hook('txnclose', throw=False, txnname=desc,
- **pycompat.strkwargs(hookargs))
- reporef()._afterlock(hook)
+ def hookfunc():
+ repo = reporef()
+ if hook.hashook(repo.ui, 'txnclose-bookmark'):
+ bmchanges = sorted(tr.changes['bookmarks'].items())
+ for name, (old, new) in bmchanges:
+ args = tr.hookargs.copy()
+ args.update(bookmarks.preparehookargs(name, old, new))
+ repo.hook('txnclose-bookmark', throw=False,
+ txnname=desc, **pycompat.strkwargs(args))
+
+ repo.hook('txnclose', throw=False, txnname=desc,
+ **pycompat.strkwargs(hookargs))
+ reporef()._afterlock(hookfunc)
tr.addfinalize('txnclose-hook', txnclosehook)
tr.addpostclose('warms-cache', self._buildcacheupdater(tr))
def txnaborthook(tr2):
@@ -9,6 +9,8 @@
> stabilization=createmarkers,exchange
> EOF
+ $ TESTHOOK='hooks.txnclose-bookmark.test=echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"'
+
initialize
$ hg init a
@@ -30,7 +32,7 @@
$ hg book Y
$ hg book
* Y -1:000000000000
- $ hg pull ../a
+ $ hg pull ../a --config "$TESTHOOK"
pulling from ../a
requesting all changes
adding changesets
@@ -41,6 +43,9 @@
updating bookmark Y
adding remote bookmark Z
new changesets 4e3505fd9583
+ test-hook-bookmark: X: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
+ test-hook-bookmark: Y: 0000000000000000000000000000000000000000 -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
+ test-hook-bookmark: Z: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
(run 'hg update' to get a working copy)
$ hg bookmarks
X 0:4e3505fd9583
@@ -94,10 +99,11 @@
delete a remote bookmark
$ hg book -d W
- $ hg push -B W ../a
+ $ hg push -B W ../a --config "$TESTHOOK"
pushing to ../a
searching for changes
no changes found
+ test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
deleting remote bookmark W
[1]
@@ -165,7 +171,7 @@
Z 1:0d2164f0ce0d
$ cd ../b
- $ hg up
+ $ hg up --config
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
updating bookmark foobar
$ echo c2 > f2
@@ -181,7 +187,7 @@
foo -1:000000000000
* foobar 1:9b140be10808
- $ hg pull --config paths.foo=../a foo
+ $ hg pull --config paths.foo=../a foo --config "$TESTHOOK"
pulling from $TESTTMP/a (glob)
searching for changes
adding changesets
@@ -192,6 +198,9 @@
divergent bookmark X stored as X@foo
updating bookmark Z
new changesets 0d2164f0ce0d
+ test-hook-bookmark: @foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
+ test-hook-bookmark: X@foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
+ test-hook-bookmark: Z: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg book
@ 1:9b140be10808
@@ -254,11 +263,13 @@
$ hg update -r X
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
(activating bookmark X)
- $ hg pull --config paths.foo=../a foo -B .
+ $ hg pull --config paths.foo=../a foo -B . --config "$TESTHOOK"
pulling from $TESTTMP/a (glob)
no changes found
divergent bookmark @ stored as @foo
importing bookmark X
+ test-hook-bookmark: @foo: 0d2164f0ce0d8f1d6f94351eba04b794909be66c -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
+ test-hook-bookmark: X: 9b140be1080824d768c5a4691a564088eede71f9 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
reinstall state for further testing:
@@ -283,13 +294,14 @@
$ hg ci -Am3
adding f2
created new head
- $ hg push ../a
+ $ hg push ../a --config "$TESTHOOK"
pushing to ../a
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
+ test-hook-bookmark: Y: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
updating bookmark Y
$ hg -R ../a book
@ 1:0d2164f0ce0d
@@ -314,7 +326,11 @@
> echo committed in pull-race
> EOF
- $ hg clone -q http://localhost:$HGPORT/ pull-race2
+ $ hg clone -q http://localhost:$HGPORT/ pull-race2 --config "$TESTHOOK"
+ test-hook-bookmark: @: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
+ test-hook-bookmark: X: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
+ test-hook-bookmark: Y: -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
+ test-hook-bookmark: Z: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
$ cd pull-race
$ hg up -q Y
$ echo c4 > f2
@@ -1,6 +1,9 @@
+
$ hg init repo
$ cd repo
+ $ TESTHOOK='hooks.txnclose-bookmark.test=echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"'
+
no bookmarks
$ hg bookmarks
@@ -12,7 +15,8 @@
bookmark rev -1
- $ hg bookmark X
+ $ hg bookmark X --config "$TESTHOOK"
+ test-hook-bookmark: X: -> 0000000000000000000000000000000000000000
list bookmarks
@@ -27,7 +31,8 @@
$ echo a > a
$ hg add a
- $ hg commit -m 0
+ $ hg commit -m 0 --config "$TESTHOOK"
+ test-hook-bookmark: X: 0000000000000000000000000000000000000000 -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
bookmark X moved to rev 0
@@ -47,7 +52,8 @@
second bookmark for rev 0, command should work even with ui.strict on
- $ hg --config ui.strict=1 bookmark X2
+ $ hg --config ui.strict=1 bookmark X2 --config "$TESTHOOK"
+ test-hook-bookmark: X2: -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
bookmark rev -1 again
@@ -62,7 +68,8 @@
$ echo b > b
$ hg add b
- $ hg commit -m 1
+ $ hg commit -m 1 --config "$TESTHOOK"
+ test-hook-bookmark: X2: f7b1eb17ad24730a1651fccd46c43826d1bbc2ac -> 925d80f479bb026b0fb3deb27503780b13f74123
$ hg bookmarks -Tjson
[
@@ -194,14 +201,17 @@
rename bookmark using .
$ hg book rename-me
- $ hg book -m . renamed
+ $ hg book -m . renamed --config "$TESTHOOK"
+ test-hook-bookmark: rename-me: db815d6d32e69058eadefc8cffbad37675707975 ->
+ test-hook-bookmark: renamed: -> db815d6d32e69058eadefc8cffbad37675707975
$ hg bookmark
X2 1:925d80f479bb
Y 2:db815d6d32e6
Z 0:f7b1eb17ad24
* renamed 2:db815d6d32e6
$ hg up -q Y
- $ hg book -d renamed
+ $ hg book -d renamed --config "$TESTHOOK"
+ test-hook-bookmark: renamed: db815d6d32e69058eadefc8cffbad37675707975 ->
rename bookmark using . with no active bookmark
@@ -354,11 +364,13 @@
[255]
bookmark with a name that matches a node id
- $ hg bookmark 925d80f479bb db815d6d32e6
+ $ hg bookmark 925d80f479bb db815d6d32e6 --config "$TESTHOOK"
bookmark 925d80f479bb matches a changeset hash
(did you leave a -r out of an 'hg bookmark' command?)
bookmark db815d6d32e6 matches a changeset hash
(did you leave a -r out of an 'hg bookmark' command?)
+ test-hook-bookmark: 925d80f479bb: -> db815d6d32e69058eadefc8cffbad37675707975
+ test-hook-bookmark: db815d6d32e6: -> db815d6d32e69058eadefc8cffbad37675707975
$ hg bookmark -d 925d80f479bb
$ hg bookmark -d db815d6d32e6
@@ -406,7 +418,8 @@
force bookmark with existing name
- $ hg bookmark -f X2
+ $ hg bookmark -f X2 --config "$TESTHOOK"
+ test-hook-bookmark: X2: 925d80f479bb026b0fb3deb27503780b13f74123 -> db815d6d32e69058eadefc8cffbad37675707975
force bookmark back to where it was, should deactivate it