evolve: prevent a crash in httpclient_pushobsmarkers() when pushing
I've been running into a crash when pushing from my hg repo in a Fedora 16 VM to
Win7 running 'hg serve', even with extensions disabled on both sides:
../hg push -r . pc
pushing to http://192.168.1.4:8000/
searching for changes
no changes found
pushing 2 obsolescence markers (263 bytes)
** unknown exception encountered, please report by visiting
...
File "hg-evolve/hgext/evolve.py", line 2482, in _pushobsolete
remote.evoext_pushobsmarkers_0(obsdata)
File "hg-evolve/hgext/evolve.py", line 2522, in httpclient_pushobsmarkers
ret, output = self._call('evoext_pushobsmarkers_0', data=obsfile)
ValueError: too many values to unpack
I'm not sure how this repo differs from the one in the test suite, so I'm not
sure how to craft a test for this. The failure occurs even when there _are_
csets to push. There was no crash if no obsolete markers needed to be pushed.
At any rate, this code was stolen from httppeer._callpush(), where it calls
self._call(). The socket exception handling wasn't necessary to fix the crash,
but the calling code might as well be duplicated in its entirety.
A successful push with this patch looks like this. Note the final line is _not_
in the output of the http push in test-simple4server.t:
../hg push -r . pc
pushing to http://192.168.1.4:8000/
searching for changes
remote has heads on branch 'default' that are not known locally: 3af110194a0c
56000e3ae44d 57ac6e51d290 7da4355c21b8 and 8 others
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 0 changes to 1 files (+1 heads)
pushing 4 obsolescence markers (525 bytes)
remote: 2 obsolescence markers added
--- a/hgext/evolve.py Thu Mar 05 10:45:53 2015 -0800
+++ b/hgext/evolve.py Thu Mar 05 20:02:07 2015 -0500
@@ -2519,11 +2519,20 @@
(Cannot simply use _callpush as http is doing some special handling)"""
self.requirecap('_evoext_pushobsmarkers_0',
_('push obsolete markers faster'))
- ret, output = self._call('evoext_pushobsmarkers_0', data=obsfile)
- for l in output.splitlines(True):
- if l.strip():
- self.ui.status(_('remote: '), l)
- return ret
+ try:
+ r = self._call('evoext_pushobsmarkers_0', data=obsfile)
+ vals = r.split('\n', 1)
+ if len(vals) < 2:
+ raise error.ResponseError(_("unexpected response:"), r)
+
+ for l in vals[1].splitlines(True):
+ if l.strip():
+ self.ui.status(_('remote: '), l)
+ return vals[0]
+ except socket.error, err:
+ if err.args[0] in (errno.ECONNRESET, errno.EPIPE):
+ raise util.Abort(_('push failed: %s') % err.args[1])
+ raise util.Abort(err.args[1])
@eh.wrapfunction(localrepo.localrepository, '_restrictcapabilities')
def local_pushobsmarker_capabilities(orig, repo, caps):