Patchwork [2,of,2,STABLE] pushkey: gracefully handle prepushkey hook failure (issue4455)

login
register
mail settings
Submitter Pierre-Yves David
Date Nov. 30, 2014, 3:35 a.m.
Message ID <54c2cccc82b0031256f7.1417318558@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/6895/
State Accepted
Commit 53a65929ef1f74ee062eae6f2aa47d787ed012b8
Headers show

Comments

Pierre-Yves David - Nov. 30, 2014, 3:35 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1417317467 28800
#      Sat Nov 29 19:17:47 2014 -0800
# Branch stable
# Node ID 54c2cccc82b0031256f7a1fa8dfeef1e77197b59
# Parent  24883146c0e464584151b960c220572c80541529
pushkey: gracefully handle prepushkey hook failure (issue4455)

This allow to gracefully report the failure of the bookmark push and carry on.
Before this change set. Local push would plain quit and wireprotocol would
failed in various ungraceful way.
Matt Mackall - Dec. 1, 2014, 10:29 p.m.
On Sat, 2014-11-29 at 19:35 -0800, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1417317467 28800
> #      Sat Nov 29 19:17:47 2014 -0800
> # Branch stable
> # Node ID 54c2cccc82b0031256f7a1fa8dfeef1e77197b59
> # Parent  24883146c0e464584151b960c220572c80541529
> pushkey: gracefully handle prepushkey hook failure (issue4455)

These are queued for stable, thanks.

Patch

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1752,12 +1752,18 @@  class localrepository(object):
         finally:
             self.ui.restoreconfig(quiet)
         return ret
 
     def pushkey(self, namespace, key, old, new):
-        self.hook('prepushkey', throw=True, namespace=namespace, key=key,
-                  old=old, new=new)
+        try:
+            self.hook('prepushkey', throw=True, namespace=namespace, key=key,
+                      old=old, new=new)
+        except error.HookAbort, exc:
+            self.ui.write_err(_("pushkey-abort: %s\n") % exc)
+            if exc.hint:
+                self.ui.write_err(_("(%s)\n") % exc.hint)
+            return False
         self.ui.debug('pushing key for "%s:%s"\n' % (namespace, key))
         ret = pushkey.push(self, namespace, key, old, new)
         self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
                   ret=ret)
         return ret
diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t
--- a/tests/test-bookmarks-pushpull.t
+++ b/tests/test-bookmarks-pushpull.t
@@ -484,6 +484,79 @@  pushing an unchanged bookmark should res
   pushing to ../unchanged-b
   searching for changes
   no changes found
   [1]
 
-  $ cd ..
+
+Check hook preventing push (issue4455)
+======================================
+
+  $ hg bookmarks
+   * @                         0:55482a6fb4b1
+  $ hg log -G
+  @  0:55482a6fb4b1 initial
+  
+  $ hg init ../issue4455-dest
+  $ hg push ../issue4455-dest # changesets only
+  pushing to ../issue4455-dest
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  $ cat >> .hg/hgrc << EOF
+  > [paths]
+  > local=../issue4455-dest/
+  > ssh=ssh://user@dummy/issue4455-dest
+  > http=http://localhost:$HGPORT/
+  > [ui]
+  > ssh=python "$TESTDIR/dummyssh"
+  > EOF
+  $ cat >> ../issue4455-dest/.hg/hgrc << EOF
+  > [hooks]
+  > prepushkey=false
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > EOF
+  $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
+  $ hg -R ../issue4455-dest serve -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
+  $ cat ../issue4455.pid >> $DAEMON_PIDS
+
+Local push
+----------
+
+  $ hg push -B @ local
+  pushing to $TESTTMP/issue4455-dest (glob)
+  searching for changes
+  no changes found
+  pushkey-abort: prepushkey hook exited with status 1
+  exporting bookmark @ failed!
+  [1]
+  $ hg -R ../issue4455-dest/ bookmarks
+  no bookmarks set
+
+Using ssh
+---------
+
+  $ hg push -B @ ssh
+  pushing to ssh://user@dummy/issue4455-dest
+  searching for changes
+  no changes found
+  remote: pushkey-abort: prepushkey hook exited with status 1
+  exporting bookmark @ failed!
+  [1]
+  $ hg -R ../issue4455-dest/ bookmarks
+  no bookmarks set
+
+Using http
+----------
+
+  $ hg push -B @ http
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  remote: pushkey-abort: prepushkey hook exited with status 1
+  exporting bookmark @ failed!
+  [1]
+  $ hg -R ../issue4455-dest/ bookmarks
+  no bookmarks set
diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -213,12 +213,13 @@  test that prepushkey can prevent incomin
   listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
   listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
   no changes found
   listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
   prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000
-  abort: prepushkey hook exited with status 1
-  [255]
+  pushkey-abort: prepushkey hook exited with status 1
+  exporting bookmark baz failed!
+  [1]
   $ cd ../a
 
 test that prelistkeys can prevent listing keys
 
   $ echo "prelistkeys = python \"$TESTDIR/printenv.py\" prelistkeys.forbid 1" >> .hg/hgrc
diff --git a/tests/test-ssh.t b/tests/test-ssh.t
--- a/tests/test-ssh.t
+++ b/tests/test-ssh.t
@@ -390,13 +390,13 @@  Test hg-ssh in read-only mode:
   pushing to ssh://user@dummy/*/remote (glob)
   searching for changes
   remote: Permission denied
   remote: abort: prechangegroup.hg-ssh hook failed
   remote: Permission denied
-  remote: abort: prepushkey.hg-ssh hook failed
-  abort: unexpected response: empty string
-  [255]
+  remote: pushkey-abort: prepushkey.hg-ssh hook failed
+  updating 6c0482d977a3 to public failed!
+  [1]
 
   $ cd ..
 
 stderr from remote commands should be printed before stdout from local code (issue4336)