mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 23:07:18 +03:00
hook: centralize passing HG_PENDING to external hook process
This patch centralizes passing HG_PENDING to external hook process into '_exthook()'. To make in-memory changes visible to external hook process, this patch does: - write (or schedule to write) in-memory dirstate changes, and - set HG_PENDING environment variable, if: - a transaction is running, and - there are in-memory changes to be visible This patch tests some commands with some hooks, because transaction activity of a same hook differs from each other ("---": "not tested"). ======== ========= ========= ============ command preupdate precommit pretxncommit ======== ========= ========= ============ unshelve o --- --- backout x --- --- import --- o o qrefresh --- x o ======== ========= ========= ============ Each hooks are examined separately to prevent in-memory changes from being visible to external process accidentally by side effect of hooks previously invoked.
This commit is contained in:
parent
36207b46bf
commit
8f93d72f88
@ -407,15 +407,13 @@ class cg1unpacker(object):
|
||||
repo.invalidatevolatilesets()
|
||||
|
||||
if changesets > 0:
|
||||
p = lambda: tr.writepending() and repo.root or ""
|
||||
if 'node' not in tr.hookargs:
|
||||
tr.hookargs['node'] = hex(cl.node(clstart))
|
||||
hookargs = dict(tr.hookargs)
|
||||
else:
|
||||
hookargs = dict(tr.hookargs)
|
||||
hookargs['node'] = hex(cl.node(clstart))
|
||||
repo.hook('pretxnchangegroup', throw=True, pending=p,
|
||||
**hookargs)
|
||||
repo.hook('pretxnchangegroup', throw=True, **hookargs)
|
||||
|
||||
added = [cl.node(r) for r in xrange(clstart, clend)]
|
||||
publishing = repo.publishing()
|
||||
|
@ -118,6 +118,13 @@ def _exthook(ui, repo, name, cmd, args, throw):
|
||||
|
||||
starttime = time.time()
|
||||
env = {}
|
||||
|
||||
# make in-memory changes visible to external process
|
||||
tr = repo.currenttransaction()
|
||||
repo.dirstate.write(tr)
|
||||
if tr and tr.writepending():
|
||||
env['HG_PENDING'] = repo.root
|
||||
|
||||
for k, v in args.iteritems():
|
||||
if callable(v):
|
||||
v = v()
|
||||
|
@ -994,8 +994,7 @@ class localrepository(object):
|
||||
reporef = weakref.ref(self)
|
||||
def validate(tr):
|
||||
"""will run pre-closing hooks"""
|
||||
pending = lambda: tr.writepending() and self.root or ""
|
||||
reporef().hook('pretxnclose', throw=True, pending=pending,
|
||||
reporef().hook('pretxnclose', throw=True,
|
||||
txnname=desc, **tr.hookargs)
|
||||
def releasefn(tr, success):
|
||||
repo = reporef()
|
||||
@ -1682,10 +1681,9 @@ class localrepository(object):
|
||||
n = self.changelog.add(mn, files, ctx.description(),
|
||||
trp, p1.node(), p2.node(),
|
||||
user, ctx.date(), ctx.extra().copy())
|
||||
p = lambda: tr.writepending() and self.root or ""
|
||||
xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
|
||||
self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
|
||||
parent2=xp2, pending=p)
|
||||
parent2=xp2)
|
||||
# set the new commit is proper phase
|
||||
targetphase = subrepo.newcommitphase(self.ui, ctx)
|
||||
if targetphase:
|
||||
@ -1865,8 +1863,6 @@ class localrepository(object):
|
||||
hookargs = {}
|
||||
if tr is not None:
|
||||
hookargs.update(tr.hookargs)
|
||||
pending = lambda: tr.writepending() and self.root or ""
|
||||
hookargs['pending'] = pending
|
||||
hookargs['namespace'] = namespace
|
||||
hookargs['key'] = key
|
||||
hookargs['old'] = old
|
||||
|
@ -259,6 +259,60 @@ check line 1 is back
|
||||
line 2
|
||||
line 3
|
||||
|
||||
Test visibility of in-memory dirstate changes outside transaction to
|
||||
external hook process
|
||||
|
||||
$ cat > $TESTTMP/checkvisibility.sh <<EOF
|
||||
> echo "==== \$1:"
|
||||
> hg parents --template "{rev}:{node|short}\n"
|
||||
> echo "===="
|
||||
> EOF
|
||||
|
||||
"hg backout --merge REV1" at REV2 below implies steps below:
|
||||
|
||||
(1) update to REV1 (REV2 => REV1)
|
||||
(2) revert by REV1^1
|
||||
(3) commit backnig out revision (REV3)
|
||||
(4) update to REV2 (REV3 => REV2)
|
||||
(5) merge with REV3 (REV2 => REV2, REV3)
|
||||
|
||||
== test visibility to external preupdate hook
|
||||
|
||||
$ hg update -q -C 2
|
||||
$ hg --config extensions.strip= strip 3
|
||||
saved backup bundle to * (glob)
|
||||
|
||||
$ cat >> .hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
|
||||
> EOF
|
||||
|
||||
("-m" is needed to avoid writing dirstte changes out at other than
|
||||
invocation of the hook to be examined)
|
||||
|
||||
$ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
|
||||
==== preupdate:
|
||||
2:6ea3f2a197a2
|
||||
====
|
||||
reverting a
|
||||
created new head
|
||||
changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
|
||||
==== preupdate:
|
||||
3:d92a3f57f067
|
||||
====
|
||||
merging with changeset 3:d92a3f57f067
|
||||
==== preupdate:
|
||||
2:6ea3f2a197a2
|
||||
====
|
||||
merging a
|
||||
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
|
||||
(branch merge, don't forget to commit)
|
||||
|
||||
$ cat >> .hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> preupdate.visibility =
|
||||
> EOF
|
||||
|
||||
$ cd ..
|
||||
|
||||
backout should not back out subsequent changesets
|
||||
|
@ -533,6 +533,110 @@ external process
|
||||
$ hg --cwd b revert --no-backup a
|
||||
$ rm -f b/foo
|
||||
|
||||
== test visibility to precommit external hook
|
||||
|
||||
$ cat >> b/.hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> precommit.visibility = sh $TESTTMP/checkvisibility.sh
|
||||
> EOF
|
||||
|
||||
$ (cd b && sh "$TESTTMP/checkvisibility.sh")
|
||||
====
|
||||
VISIBLE 0:80971e65b431
|
||||
ACTUAL 0:80971e65b431
|
||||
====
|
||||
|
||||
$ hg --cwd b import ../patch1 ../patch2 ../patch3
|
||||
applying ../patch1
|
||||
====
|
||||
VISIBLE 0:80971e65b431
|
||||
M a
|
||||
ACTUAL 0:80971e65b431
|
||||
M a
|
||||
====
|
||||
applying ../patch2
|
||||
====
|
||||
VISIBLE 1:1d4bd90af0e4
|
||||
M a
|
||||
ACTUAL 0:80971e65b431
|
||||
M a
|
||||
====
|
||||
applying ../patch3
|
||||
====
|
||||
VISIBLE 2:6d019af21222
|
||||
A foo
|
||||
ACTUAL 0:80971e65b431
|
||||
M a
|
||||
====
|
||||
|
||||
$ hg --cwd b rollback -q
|
||||
$ (cd b && sh "$TESTTMP/checkvisibility.sh")
|
||||
====
|
||||
VISIBLE 0:80971e65b431
|
||||
M a
|
||||
ACTUAL 0:80971e65b431
|
||||
M a
|
||||
====
|
||||
$ hg --cwd b revert --no-backup a
|
||||
$ rm -f b/foo
|
||||
|
||||
$ cat >> b/.hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> precommit.visibility =
|
||||
> EOF
|
||||
|
||||
== test visibility to pretxncommit external hook
|
||||
|
||||
$ cat >> b/.hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> pretxncommit.visibility = sh $TESTTMP/checkvisibility.sh
|
||||
> EOF
|
||||
|
||||
$ (cd b && sh "$TESTTMP/checkvisibility.sh")
|
||||
====
|
||||
VISIBLE 0:80971e65b431
|
||||
ACTUAL 0:80971e65b431
|
||||
====
|
||||
|
||||
$ hg --cwd b import ../patch1 ../patch2 ../patch3
|
||||
applying ../patch1
|
||||
====
|
||||
VISIBLE 0:80971e65b431
|
||||
M a
|
||||
ACTUAL 0:80971e65b431
|
||||
M a
|
||||
====
|
||||
applying ../patch2
|
||||
====
|
||||
VISIBLE 1:1d4bd90af0e4
|
||||
M a
|
||||
ACTUAL 0:80971e65b431
|
||||
M a
|
||||
====
|
||||
applying ../patch3
|
||||
====
|
||||
VISIBLE 2:6d019af21222
|
||||
A foo
|
||||
ACTUAL 0:80971e65b431
|
||||
M a
|
||||
====
|
||||
|
||||
$ hg --cwd b rollback -q
|
||||
$ (cd b && sh "$TESTTMP/checkvisibility.sh")
|
||||
====
|
||||
VISIBLE 0:80971e65b431
|
||||
M a
|
||||
ACTUAL 0:80971e65b431
|
||||
M a
|
||||
====
|
||||
$ hg --cwd b revert --no-backup a
|
||||
$ rm -f b/foo
|
||||
|
||||
$ cat >> b/.hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> pretxncommit.visibility =
|
||||
> EOF
|
||||
|
||||
$ rm -r b
|
||||
|
||||
|
||||
|
@ -242,3 +242,85 @@ dropping status of "file2")
|
||||
====
|
||||
0:25e397dabed2
|
||||
====
|
||||
|
||||
== test visibility to precommit external hook
|
||||
|
||||
$ hg update -C -q
|
||||
$ rm -f file2
|
||||
$ hg qpush -q second-patch --config hooks.pretxncommit.unexpectedabort=
|
||||
now at: second-patch
|
||||
$ echo bbbb >> file2
|
||||
|
||||
$ cat >> .hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> precommit.checkvisibility = sh "$TESTTMP/checkvisibility.sh"
|
||||
> EOF
|
||||
|
||||
$ sh "$TESTTMP/checkvisibility.sh"
|
||||
====
|
||||
1:e30108269082
|
||||
M file2
|
||||
====
|
||||
|
||||
$ hg qrefresh
|
||||
====
|
||||
0:25e397dabed2
|
||||
A file2
|
||||
====
|
||||
transaction abort!
|
||||
rollback completed
|
||||
refresh interrupted while patch was popped! (revert --all, qpush to recover)
|
||||
abort: pretxncommit.unexpectedabort hook exited with status 1
|
||||
[255]
|
||||
|
||||
$ sh "$TESTTMP/checkvisibility.sh"
|
||||
====
|
||||
0:25e397dabed2
|
||||
====
|
||||
|
||||
$ cat >> .hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> precommit.checkvisibility =
|
||||
> EOF
|
||||
|
||||
== test visibility to pretxncommit external hook
|
||||
|
||||
$ hg update -C -q
|
||||
$ rm -f file2
|
||||
$ hg qpush -q second-patch --config hooks.pretxncommit.unexpectedabort=
|
||||
now at: second-patch
|
||||
$ echo bbbb >> file2
|
||||
|
||||
$ cat >> .hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> pretxncommit.checkvisibility = sh "$TESTTMP/checkvisibility.sh"
|
||||
> # make checkvisibility run before unexpectedabort
|
||||
> priority.pretxncommit.checkvisibility = 10
|
||||
> EOF
|
||||
|
||||
$ sh "$TESTTMP/checkvisibility.sh"
|
||||
====
|
||||
1:e30108269082
|
||||
M file2
|
||||
====
|
||||
|
||||
$ hg qrefresh
|
||||
====
|
||||
0:25e397dabed2
|
||||
A file2
|
||||
====
|
||||
transaction abort!
|
||||
rollback completed
|
||||
refresh interrupted while patch was popped! (revert --all, qpush to recover)
|
||||
abort: pretxncommit.unexpectedabort hook exited with status 1
|
||||
[255]
|
||||
|
||||
$ sh "$TESTTMP/checkvisibility.sh"
|
||||
====
|
||||
0:25e397dabed2
|
||||
====
|
||||
|
||||
$ cat >> .hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> pretxncommit.checkvisibility =
|
||||
> EOF
|
||||
|
@ -1011,6 +1011,84 @@ with general delta
|
||||
7e30d8ac6f23cfc84330fd7e698730374615d21a
|
||||
$ cd ..
|
||||
|
||||
Test visibility of in-memory changes inside transaction to external hook
|
||||
------------------------------------------------------------------------
|
||||
|
||||
$ cd repo
|
||||
|
||||
$ echo xxxx >> x
|
||||
$ hg commit -m "#5: changes to invoke rebase"
|
||||
|
||||
$ cat > $TESTTMP/checkvisibility.sh <<EOF
|
||||
> echo "==== \$1:"
|
||||
> hg parents --template "VISIBLE {rev}:{node|short}\n"
|
||||
> # test that pending changes are hidden
|
||||
> unset HG_PENDING
|
||||
> hg parents --template "ACTUAL {rev}:{node|short}\n"
|
||||
> echo "===="
|
||||
> EOF
|
||||
|
||||
$ cat >> .hg/hgrc <<EOF
|
||||
> [defaults]
|
||||
> # to fix hash id of temporary revisions
|
||||
> unshelve = --date '0 0'
|
||||
> EOF
|
||||
|
||||
"hg unshelve" at REV5 implies steps below:
|
||||
|
||||
(1) commit changes in the working directory (REV6)
|
||||
(2) unbundle shelved revision (REV7)
|
||||
(3) rebase: merge REV7 into REV6 (REV6 => REV6, REV7)
|
||||
(4) rebase: commit merged revision (REV8)
|
||||
(5) rebase: update to REV6 (REV8 => REV6)
|
||||
(6) update to REV5 (REV6 => REV5)
|
||||
(7) abort transaction
|
||||
|
||||
== test visibility to external preupdate hook
|
||||
|
||||
$ cat >> .hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
|
||||
> 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)
|
||||
==== preupdate:
|
||||
VISIBLE 6:66b86db80ee4
|
||||
ACTUAL 5:703117a2acfb
|
||||
====
|
||||
==== preupdate:
|
||||
VISIBLE 8:cb2a4e59c2d5
|
||||
ACTUAL 5:703117a2acfb
|
||||
====
|
||||
==== preupdate:
|
||||
VISIBLE 6:66b86db80ee4
|
||||
ACTUAL 5:703117a2acfb
|
||||
====
|
||||
|
||||
$ cat >> .hg/hgrc <<EOF
|
||||
> [hooks]
|
||||
> preupdate.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
|
||||
---------------------------------------------------------------
|
||||
$ hg init salvage
|
||||
|
Loading…
Reference in New Issue
Block a user