Patchwork [12,of,12,stable] bundle2: gracefully handle hook abort

login
register
mail settings
Submitter Pierre-Yves David
Date April 22, 2014, 8:10 p.m.
Message ID <c5b9f3cab113191b3138.1398197456@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/4430/
State Accepted
Commit bcfd44abad933390b1b21d7ffcd107fca0023dd2
Headers show

Comments

Pierre-Yves David - April 22, 2014, 8:10 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1398121995 25200
#      Mon Apr 21 16:13:15 2014 -0700
# Branch stable
# Node ID c5b9f3cab113191b3138cc695e6391bcb3e006ec
# Parent  fbf039ac0e2ea7cfcfdcd7c06b532c31cdaad60f
bundle2: gracefully handle hook abort

We make sure any exception raised during the whole span of handling bundle2
processing are decorated. This let us catch exceptions raised by hooks prior to
transaction commit.
Matt Mackall - April 22, 2014, 9:30 p.m.
On Tue, 2014-04-22 at 13:10 -0700, pierre-yves.david@ens-lyon.org wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1398121995 25200
> #      Mon Apr 21 16:13:15 2014 -0700
> # Branch stable
> # Node ID c5b9f3cab113191b3138cc695e6391bcb3e006ec
> # Parent  fbf039ac0e2ea7cfcfdcd7c06b532c31cdaad60f
> bundle2: gracefully handle hook abort

These are queued, thanks. Your grammar error rate seems to be improving.

Patch

diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -736,20 +736,24 @@  def unbundle(repo, cg, heads, source, ur
     lock = repo.lock()
     try:
         check_heads(repo, heads, 'uploading changes')
         # push can proceed
         if util.safehasattr(cg, 'params'):
-            tr = repo.transaction('unbundle')
-            tr.hookargs['bundle2-exp'] = '1'
-            r = bundle2.processbundle(repo, cg, lambda: tr).reply
-            cl = repo.unfiltered().changelog
-            p = cl.writepending() and repo.root or ""
-            repo.hook('b2x-pretransactionclose', throw=True, source=source,
-                      url=url, pending=p, **tr.hookargs)
-            tr.close()
-            repo.hook('b2x-transactionclose', source=source, url=url,
-                      **tr.hookargs)
+            try:
+                tr = repo.transaction('unbundle')
+                tr.hookargs['bundle2-exp'] = '1'
+                r = bundle2.processbundle(repo, cg, lambda: tr).reply
+                cl = repo.unfiltered().changelog
+                p = cl.writepending() and repo.root or ""
+                repo.hook('b2x-pretransactionclose', throw=True, source=source,
+                          url=url, pending=p, **tr.hookargs)
+                tr.close()
+                repo.hook('b2x-transactionclose', source=source, url=url,
+                          **tr.hookargs)
+            except Exception, exc:
+                exc.duringunbundle2 = True
+                raise
         else:
             r = changegroup.addchangegroup(repo, cg, source, url)
     finally:
         if tr is not None:
             tr.release()
diff --git a/tests/test-bundle2.t b/tests/test-bundle2.t
--- a/tests/test-bundle2.t
+++ b/tests/test-bundle2.t
@@ -1041,5 +1041,42 @@  Doing the actual push: race
   pushing to http://localhost:$HGPORT2/
   searching for changes
   abort: push failed:
   'repository changed while pushing - please try again'
   [255]
+
+Doing the actual push: hook abort
+
+  $ cat << EOF >> $HGRCPATH
+  > [failpush]
+  > reason =
+  > [hooks]
+  > b2x-pretransactionclose.failpush = false
+  > EOF
+
+  $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
+  $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
+  $ cat other.pid >> $DAEMON_PIDS
+
+  $ hg -R main push other -r e7ec4e813ba6
+  pushing to other
+  searching for changes
+  transaction abort!
+  rollback completed
+  abort: b2x-pretransactionclose.failpush hook exited with status 1
+  [255]
+
+  $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
+  pushing to ssh://user@dummy/other
+  searching for changes
+  abort: b2x-pretransactionclose.failpush hook exited with status 1
+  remote: transaction abort!
+  remote: rollback completed
+  [255]
+
+  $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
+  pushing to http://localhost:$HGPORT2/
+  searching for changes
+  abort: b2x-pretransactionclose.failpush hook exited with status 1
+  [255]
+
+