D264: exchange: drop support for lock-based unbundling (BC)
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Tue Aug 8 03:24:13 UTC 2017
indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.
REVISION SUMMARY
Locking over the wire protocol and the "addchangegroup" wire
protocol command has been deprecated since https://phab.mercurial-scm.org/rHGe8c4f3d3df8c461d4868268c3faeda9639a9a902, which was
first part of Mercurial 0.9.1.
Support for handling these commands from sshserver was dropped in
https://phab.mercurial-scm.org/rHG9f6e0e7ef82884e3ec66455dac7312820c2b35ce in 2015, effectively locking out pre 0.9.1 clients
from new servers.
However, client-side code for calling lock and addchangegroup is
still present in exchange.py and the various peer classes to
facilitate pushing to pre 0.9.1 servers.
The lock-based pushing mechanism is extremely brittle. 0.9.1 was
released in July 2006 and I highly doubt anyone is still running
such an ancient version of Mercurial on a server. I'm about to
refactor the peer API and I don't think it is worth keeping
support for this ancient protocol feature. So, this commit removes
client support for the lock-based pushing mechanism. This means
modern clients will no longer be able to push to pre 0.9.1 servers.
REPOSITORY
rHG Mercurial
REVISION DETAIL
https://phab.mercurial-scm.org/D264
AFFECTED FILES
mercurial/exchange.py
mercurial/httppeer.py
mercurial/localrepo.py
mercurial/sshpeer.py
CHANGE DETAILS
diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py
--- a/mercurial/sshpeer.py
+++ b/mercurial/sshpeer.py
@@ -17,21 +17,6 @@
wireproto,
)
-class remotelock(object):
- def __init__(self, repo):
- self.repo = repo
- def release(self):
- self.repo.unlock()
- self.repo = None
- def __enter__(self):
- return self
- def __exit__(self, exc_type, exc_val, exc_tb):
- if self.repo:
- self.release()
- def __del__(self):
- if self.repo:
- self.release()
-
def _serverquote(s):
if not s:
return s
@@ -337,33 +322,4 @@
self.pipeo.flush()
self.readerr()
- def lock(self):
- self._call("lock")
- return remotelock(self)
-
- def unlock(self):
- self._call("unlock")
-
- def addchangegroup(self, cg, source, url, lock=None):
- '''Send a changegroup to the remote server. Return an integer
- similar to unbundle(). DEPRECATED, since it requires locking the
- remote.'''
- d = self._call("addchangegroup")
- if d:
- self._abort(error.RepoError(_("push refused: %s") % d))
- for d in iter(lambda: cg.read(4096), ''):
- self.pipeo.write(d)
- self.readerr()
-
- self.pipeo.flush()
-
- self.readerr()
- r = self._recv()
- if not r:
- return 1
- try:
- return int(r)
- except ValueError:
- self._abort(error.ResponseError(_("unexpected response:"), r))
-
instance = sshpeer
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -237,9 +237,6 @@
except error.PushRaced as exc:
raise error.ResponseError(_('push failed:'), str(exc))
- def lock(self):
- return self._repo.lock()
-
def pushkey(self, namespace, key, old, new):
return self._repo.pushkey(namespace, key, old, new)
diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py
--- a/mercurial/httppeer.py
+++ b/mercurial/httppeer.py
@@ -132,9 +132,6 @@
(' '.join(self.caps or ['none'])))
return self.caps
- def lock(self):
- raise error.Abort(_('operation not supported over http'))
-
def _callstream(self, cmd, _compressible=False, **args):
if cmd == 'pushkey':
args['data'] = ''
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -433,16 +433,13 @@
" %s") % (', '.join(sorted(missing)))
raise error.Abort(msg)
- # there are two ways to push to remote repo:
- #
- # addchangegroup assumes local user can lock remote
- # repo (local filesystem, old ssh servers).
- #
- # unbundle assumes local user cannot lock remote repo (new ssh
- # servers, http servers).
-
if not pushop.remote.canpush():
raise error.Abort(_("destination does not support push"))
+
+ if not pushop.remote.capable('unbundle'):
+ raise error.Abort(_('cannot push: destination does not support the '
+ 'unbundle wire protocol command'))
+
# get local lock as we might write phase data
localwlock = locallock = None
try:
@@ -468,21 +465,14 @@
'push-response',
pushop.remote.url())
pushop.repo.checkpush(pushop)
- lock = None
- unbundle = pushop.remote.capable('unbundle')
- if not unbundle:
- lock = pushop.remote.lock()
- try:
- _pushdiscovery(pushop)
- if not _forcebundle1(pushop):
- _pushbundle2(pushop)
- _pushchangeset(pushop)
- _pushsyncphase(pushop)
- _pushobsolete(pushop)
- _pushbookmark(pushop)
- finally:
- if lock is not None:
- lock.release()
+ _pushdiscovery(pushop)
+ if not _forcebundle1(pushop):
+ _pushbundle2(pushop)
+ _pushchangeset(pushop)
+ _pushsyncphase(pushop)
+ _pushobsolete(pushop)
+ _pushbookmark(pushop)
+
if pushop.trmanager:
pushop.trmanager.close()
finally:
@@ -948,9 +938,12 @@
pushop.stepsdone.add('changesets')
if not _pushcheckoutgoing(pushop):
return
+
+ # Should have verified this in push().
+ assert pushop.remote.capable('unbundle')
+
pushop.repo.prepushoutgoinghooks(pushop)
outgoing = pushop.outgoing
- unbundle = pushop.remote.capable('unbundle')
# TODO: get bundlecaps from remote
bundlecaps = None
# create a changegroup from local
@@ -969,24 +962,18 @@
bundlecaps=bundlecaps)
# apply changegroup to remote
- if unbundle:
- # local repo finds heads on server, finds out what
- # revs it must push. once revs transferred, if server
- # finds it has different heads (someone else won
- # commit/push race), server aborts.
- if pushop.force:
- remoteheads = ['force']
- else:
- remoteheads = pushop.remoteheads
- # ssh: return remote's addchangegroup()
- # http: return remote's addchangegroup() or 0 for error
- pushop.cgresult = pushop.remote.unbundle(cg, remoteheads,
- pushop.repo.url())
+ # local repo finds heads on server, finds out what
+ # revs it must push. once revs transferred, if server
+ # finds it has different heads (someone else won
+ # commit/push race), server aborts.
+ if pushop.force:
+ remoteheads = ['force']
else:
- # we return an integer indicating remote head count
- # change
- pushop.cgresult = pushop.remote.addchangegroup(cg, 'push',
- pushop.repo.url())
+ remoteheads = pushop.remoteheads
+ # ssh: return remote's addchangegroup()
+ # http: return remote's addchangegroup() or 0 for error
+ pushop.cgresult = pushop.remote.unbundle(cg, remoteheads,
+ pushop.repo.url())
def _pushsyncphase(pushop):
"""synchronise phase information locally and remotely"""
To: indygreg, #hg-reviewers
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list