[PATCH 12 of 12 stable] bundle2: gracefully handle hook abort

pierre-yves.david at ens-lyon.org pierre-yves.david at ens-lyon.org
Tue Apr 22 15:10:56 CDT 2014


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at 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.

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]
+
+


More information about the Mercurial-devel mailing list