diff --git a/hgext/keyword.py b/hgext/keyword.py --- a/hgext/keyword.py +++ b/hgext/keyword.py @@ -480,7 +480,14 @@ def reposetup(ui, repo): # other extensions can still wrap repo.commitctx directly self.commitctx = self.kwcommitctx try: - return super(kwrepo, self).commit(*args, **opts) + self._kwcommithooks = {} + n = super(kwrepo, self).commit(*args, **opts) + if self._kwcommithooks: + xp1, xp2 = self._kwxp1, self._kwxp2 + for name, cmd in self._kwcommithooks.iteritems(): + ui.setconfig('hooks', name, cmd) + self.hook('commit', node=n, parent1=xp1, parent2=xp2) + return n finally: del self.commitctx @@ -490,23 +497,18 @@ def reposetup(ui, repo): wlock = self.wlock() lock = self.lock() # store and postpone commit hooks - commithooks = {} for name, cmd in ui.configitems('hooks'): if name.split('.', 1)[0] == 'commit': - commithooks[name] = cmd + self._kwcommithooks[name] = cmd ui.setconfig('hooks', name, None) - if commithooks: + if self._kwcommithooks: # store parents for commit hooks p1, p2 = ctx.p1(), ctx.p2() - xp1, xp2 = p1.hex(), p2 and p2.hex() or '' + self._kwxp1, self._kwxp2 = p1.hex(), p2 and p2.hex() or '' n = super(kwrepo, self).commitctx(ctx, error) kwt.overwrite(n, True, None) - if commithooks: - for name, cmd in commithooks.iteritems(): - ui.setconfig('hooks', name, cmd) - self.hook('commit', node=n, parent1=xp1, parent2=xp2) return n finally: release(lock, wlock) diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -846,6 +846,8 @@ class localrepository(repo.repository): msgfile.close() try: + hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '') + self.hook("precommit", throw=True, parent1=hookp1, parent2=hookp2) ret = self.commitctx(cctx, True) except: if edited: @@ -861,15 +863,14 @@ class localrepository(repo.repository): self.dirstate.forget(f) self.dirstate.setparents(ret) ms.reset() - - return ret - finally: wlock.release() + self.hook("commit", node=hex(ret), parent1=hookp1, parent2=hookp2) + return ret + def commitctx(self, ctx, error=False): """Add a new revision to current repository. - Revision information is passed via the context argument. """ @@ -880,9 +881,6 @@ class localrepository(repo.repository): m2 = p2.manifest() user = ctx.user() - xp1, xp2 = p1.hex(), p2 and p2.hex() or '' - self.hook("precommit", throw=True, parent1=xp1, parent2=xp2) - lock = self.lock() try: tr = self.transaction() @@ -925,6 +923,7 @@ class localrepository(repo.repository): trp, p1.node(), p2.node(), user, ctx.date(), ctx.extra().copy()) p = lambda: self.changelog.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) self.changelog.finalize(trp) @@ -932,8 +931,6 @@ class localrepository(repo.repository): if self._branchcache: self.branchtags() - - self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2) return n finally: del tr diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -511,8 +511,9 @@ def update(repo, node, branchmerge, forc repo.dirstate.setparents(fp1, fp2) if not branchmerge and not fastforward: repo.dirstate.setbranch(p2.branch()) - repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3]) - - return stats finally: wlock.release() + + if not partial: + repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3]) + return stats diff --git a/tests/test-hook b/tests/test-hook --- a/tests/test-hook +++ b/tests/test-hook @@ -205,8 +205,8 @@ echo '# make sure --traceback works' echo '[hooks]' > .hg/hgrc echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc -echo a >> a -hg --traceback commit -A -m a 2>&1 | grep '^Traceback' +echo aa > a +hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback' cd .. hg init c @@ -224,9 +224,9 @@ echo 'hookext = hookext.py' >> .hg/hgrc touch foo hg add foo -hg ci -m 'add foo' +hg ci -d '0 0' -m 'add foo' echo >> foo -hg ci --debug -m 'change foo' | sed -e 's/ at .*>/>/' +hg ci --debug -d '0 0' -m 'change foo' | sed -e 's/ at .*>/>/' hg showconfig hooks | sed -e 's/ at .*>/>/' @@ -246,7 +246,7 @@ echo '[hooks]' > ../repo/.hg/hgrc echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc cd ../repo -hg commit +hg commit -d '0 0' cd ../../b echo '# make sure --traceback works on hook import failure' @@ -260,6 +260,14 @@ echo '[hooks]' > .hg/hgrc echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc echo a >> a -hg --traceback commit -Ama 2>&1 | egrep '^(exception|Traceback|ImportError)' +hg --traceback commit -d '0 0' -ma 2>&1 | egrep '^(exception|Traceback|ImportError)' + +echo '# commit and update hooks should run after command completion (issue 1827)' +echo '[hooks]' > .hg/hgrc +echo 'commit = hg id' >> .hg/hgrc +echo 'update = hg id' >> .hg/hgrc +echo bb > a +hg ci -d '0 0' -ma +hg up 0 exit 0 diff --git a/tests/test-hook.out b/tests/test-hook.out --- a/tests/test-hook.out +++ b/tests/test-hook.out @@ -171,3 +171,7 @@ exception from second failed import atte Traceback (most recent call last): ImportError: No module named hgext_importfail Traceback (most recent call last): +# commit and update hooks should run after command completion (issue 1827) +8da618c33484 tip +29b62aeb769f +1 files updated, 0 files merged, 0 files removed, 0 files unresolved