Skip to content
Snippets Groups Projects
Commit 949e8c626d19 authored by Katsunori FUJIWARA's avatar Katsunori FUJIWARA
Browse files

merge: make in-memory changes visible to external update hooks

51844b8b5017 (while 3.4 code-freeze) made all 'update' hooks run after
releasing wlock for visibility of in-memory dirstate changes. But this
breaks paired invocation of 'preupdate' and 'update' hooks.

For example, 'hg backout --merge' for TARGET revision, which isn't
parent of CURRENT, consists of steps below:

  1. update from CURRENT to TARGET
  2. commit BACKOUT revision, which backs TARGET out
  3. update from BACKOUT to CURRENT
  4. merge TARGET into CURRENT

Then, we expects hooks to run in the order below:

  - 'preupdate' on CURRENT for (1)
  - 'update'    on TARGET  for (1)
  - 'preupdate' on BACKOUT for (3)
  - 'update'    on CURRENT for (3)
  - 'preupdate' on TARGET  for (4)
  - 'update'    on CURRENT/TARGET for (4)

But hooks actually run in the order below:

  - 'preupdate' on CURRENT for (1)
  - 'preupdate' on BACKOUT for (3)
  - 'preupdate' on TARGET  for (4)
  - 'update'    on TARGET  for (1), but actually on CURRENT/TARGET
  - 'update'    on CURRENT for (3), but actually on CURRENT/TARGET
  - 'update'    on CURRENT for (4), but actually on CURRENT/TARGET

Root cause of the issue focused by 51844b8b5017 is that external
'update' hook process can't view in-memory changes (especially, of
dirstate), because they aren't written out until the end of
transaction (or wlock).

Now, hooks can be invoked just after updating, because previous
patches made in-memory changes visible to external process.

This patch may break backward compatibility from the point of view of
"scheduling hook execution", but should be reasonable because 'update'
hooks had been executed in this order before 3.4.

This patch tests "hg backout" and "hg unshelve", because the former
activates the transaction before 'update' hook invocation, but the
former doesn't.
parent 520defbc0335
No related branches found
No related tags found
No related merge requests found
......@@ -1244,9 +1244,7 @@
wlock.release()
if not partial:
def updatehook(parent1=xp1, parent2=xp2, error=stats[3]):
repo.hook('update', parent1=parent1, parent2=parent2, error=error)
repo._afterlock(updatehook)
repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
return stats
def graft(repo, ctx, pctx, labels):
......
......@@ -313,6 +313,41 @@
> preupdate.visibility =
> EOF
== test visibility to external update hook
$ hg update -q -C 2
$ hg --config extensions.strip= strip 3
saved backup bundle to * (glob)
$ cat >> .hg/hgrc <<EOF
> [hooks]
> update.visibility = sh $TESTTMP/checkvisibility.sh update
> EOF
$ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
==== update:
1:5a50a024c182
====
reverting a
created new head
changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
==== update:
2:6ea3f2a197a2
====
merging with changeset 3:d92a3f57f067
merging a
==== update:
2:6ea3f2a197a2
3:d92a3f57f067
====
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ cat >> .hg/hgrc <<EOF
> [hooks]
> update.visibility =
> EOF
$ cd ..
backout should not back out subsequent changesets
......
......@@ -119,4 +119,5 @@
$ echo '[hooks]' >> .hg/hgrc
$ echo 'update = echo hooked' >> .hg/hgrc
$ hg update
hooked
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
......@@ -122,5 +123,4 @@
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
hooked
$ hg blackbox -l 5
1970/01/01 00:00:00 bob (*)> update (glob)
1970/01/01 00:00:00 bob (*)> writing .hg/cache/tags2-visible with 0 tags (glob)
......
......@@ -223,4 +223,5 @@
$ echo "update = printenv.py update" >> .hg/hgrc
$ hg update
preupdate hook: HG_PARENT1=539e4b31b6dc
update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
......@@ -226,5 +227,4 @@
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc
pushkey hook
......@@ -644,4 +644,5 @@
$ hg ci -ma
223eafe2750c tip
$ hg up 0 --config extensions.largefiles=
cb9a9f314b8b
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
......@@ -647,5 +648,4 @@
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
cb9a9f314b8b
make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
that is passed to pre/post hooks
......
......@@ -1087,6 +1087,52 @@
ACTUAL 5:703117a2acfb
====
== test visibility to external update hook
$ hg update -q -C 5
$ cat >> .hg/hgrc <<EOF
> [hooks]
> update.visibility = sh $TESTTMP/checkvisibility.sh update
> EOF
$ echo nnnn >> n
$ sh $TESTTMP/checkvisibility.sh before-unshelving
==== before-unshelving:
VISIBLE 5:703117a2acfb
ACTUAL 5:703117a2acfb
====
$ hg unshelve --keep default
temporarily committing pending changes (restore with 'hg unshelve --abort')
rebasing shelved changes
rebasing 7:fcbb97608399 "changes to 'create conflict'" (tip)
==== update:
VISIBLE 6:66b86db80ee4
VISIBLE 7:fcbb97608399
ACTUAL 5:703117a2acfb
====
==== update:
VISIBLE 6:66b86db80ee4
ACTUAL 5:703117a2acfb
====
==== update:
VISIBLE 5:703117a2acfb
ACTUAL 5:703117a2acfb
====
$ cat >> .hg/hgrc <<EOF
> [hooks]
> update.visibility =
> EOF
$ sh $TESTTMP/checkvisibility.sh after-unshelving
==== after-unshelving:
VISIBLE 5:703117a2acfb
ACTUAL 5:703117a2acfb
====
$ cd ..
test Abort unshelve always gets user out of the unshelved state
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment