##// END OF EJS Templates
Never exit directly from commands.dispatch(), but pass return code to caller....
Never exit directly from commands.dispatch(), but pass return code to caller. Usually the caller is commands.run(). Some extensions still use sys.exit(), this is catched, too. Fixed wrong return statement in commands.recover() yielding a zero exit code.

File last commit:

r2046:d14497cb default
r2057:fef2d653 default
Show More
sshrepo.py
155 lines | 4.5 KiB | text/x-python | PythonLexer
# sshrepo.py - ssh repository proxy class for mercurial
#
# Copyright 2005 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
from node import *
from remoterepo import *
from i18n import gettext as _
from demandload import *
demandload(globals(), "hg os re stat")
class sshrepository(remoterepository):
def __init__(self, ui, path):
self.url = path
self.ui = ui
m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path)
if not m:
raise hg.RepoError(_("couldn't parse destination %s") % path)
self.user = m.group(2)
self.host = m.group(3)
self.port = m.group(5)
self.path = m.group(7) or "."
args = self.user and ("%s@%s" % (self.user, self.host)) or self.host
args = self.port and ("%s -p %s") % (args, self.port) or args
sshcmd = self.ui.config("ui", "ssh", "ssh")
remotecmd = self.ui.config("ui", "remotecmd", "hg")
cmd = '%s %s "%s -R %s serve --stdio"'
cmd = cmd % (sshcmd, args, remotecmd, self.path)
ui.note('running %s\n' % cmd)
self.pipeo, self.pipei, self.pipee = os.popen3(cmd, 'b')
# skip any noise generated by remote shell
r = self.do_cmd("between", pairs=("%s-%s" % ("0"*40, "0"*40)))
l1 = ""
l2 = "dummy"
max_noise = 500
while l2 and max_noise:
l2 = r.readline()
self.readerr()
if l1 == "1\n" and l2 == "\n":
break
if l1:
ui.debug(_("remote: "), l1)
l1 = l2
max_noise -= 1
else:
if l1:
ui.debug(_("remote: "), l1)
raise hg.RepoError(_("no response from remote hg"))
def readerr(self):
while 1:
size = os.fstat(self.pipee.fileno())[stat.ST_SIZE]
if size == 0: break
l = self.pipee.readline()
if not l: break
self.ui.status(_("remote: "), l)
def __del__(self):
try:
self.pipeo.close()
self.pipei.close()
# read the error descriptor until EOF
for l in self.pipee:
self.ui.status(_("remote: "), l)
self.pipee.close()
except:
pass
def dev(self):
return -1
def do_cmd(self, cmd, **args):
self.ui.debug(_("sending %s command\n") % cmd)
self.pipeo.write("%s\n" % cmd)
for k, v in args.items():
self.pipeo.write("%s %d\n" % (k, len(v)))
self.pipeo.write(v)
self.pipeo.flush()
return self.pipei
def call(self, cmd, **args):
r = self.do_cmd(cmd, **args)
l = r.readline()
self.readerr()
try:
l = int(l)
except:
raise hg.RepoError(_("unexpected response '%s'") % l)
return r.read(l)
def lock(self):
self.call("lock")
return remotelock(self)
def unlock(self):
self.call("unlock")
def heads(self):
d = self.call("heads")
try:
return map(bin, d[:-1].split(" "))
except:
raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "..."))
def branches(self, nodes):
n = " ".join(map(hex, nodes))
d = self.call("branches", nodes=n)
try:
br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
return br
except:
raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "..."))
def between(self, pairs):
n = "\n".join(["-".join(map(hex, p)) for p in pairs])
d = self.call("between", pairs=n)
try:
p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
return p
except:
raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "..."))
def changegroup(self, nodes, kind):
n = " ".join(map(hex, nodes))
f = self.do_cmd("changegroup", roots=n)
return self.pipei
def addchangegroup(self, cg):
d = self.call("addchangegroup")
if d:
raise hg.RepoError(_("push refused: %s"), d)
while 1:
d = cg.read(4096)
if not d: break
self.pipeo.write(d)
self.readerr()
self.pipeo.flush()
self.readerr()
l = int(self.pipei.readline())
r = self.pipei.read(l)
if not r:
return 1
return int(r)