##// END OF EJS Templates
Keep session variables when linking from hgwebdir's index to repositories.
Keep session variables when linking from hgwebdir's index to repositories.

File last commit:

r3275:7ae37d99 default
r3365:cf680c9a default
Show More
sshrepo.py
207 lines | 5.9 KiB | text/x-python | PythonLexer
mpm@selenic.com
sshrepo: adjust file comment
r1096 # sshrepo.py - ssh repository proxy class for mercurial
mpm@selenic.com
Break apart hg.py...
r1089 #
Vadim Gelfer
update copyrights.
r2859 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
mpm@selenic.com
Break apart hg.py...
r1089 #
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
mpm@selenic.com
Fix sshrepo imports
r1103 from node import *
from remoterepo import *
Benoit Boissinot
i18n first part: make '_' available for files who need it
r1400 from i18n import gettext as _
Bryan O'Sullivan
Fix lots of exception-related problems....
r1251 from demandload import *
Vadim Gelfer
merge with crew.
r2177 demandload(globals(), "hg os re stat util")
mpm@selenic.com
Break apart hg.py...
r1089
class sshrepository(remoterepository):
Sean Meiners
Added ability to clone from a local repository to a (new) remote one....
r2549 def __init__(self, ui, path, create=0):
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 self._url = path
mpm@selenic.com
Break apart hg.py...
r1089 self.ui = ui
m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path)
if not m:
Vadim Gelfer
change some repo messages in small ways....
r2473 raise hg.RepoError(_("couldn't parse location %s") % path)
mpm@selenic.com
Break apart hg.py...
r1089
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")
Sean Meiners
Added ability to clone from a local repository to a (new) remote one....
r2549
if create:
cmd = '%s %s "%s init %s"'
cmd = cmd % (sshcmd, args, remotecmd, self.path)
ui.note('running %s\n' % cmd)
res = os.system(cmd)
if res != 0:
raise hg.RepoError(_("could not create remote repo"))
self.validate_repo(ui, sshcmd, args, remotecmd)
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 def url(self):
return self._url
Sean Meiners
Added ability to clone from a local repository to a (new) remote one....
r2549 def validate_repo(self, ui, sshcmd, args, remotecmd):
Benoit Boissinot
sshrepo: flush stderr before connecting to the hg server
r3034 # cleanup up previous run
self.cleanup()
Bryan O'Sullivan
Give ssh a better chance of working on Windows....
r1330 cmd = '%s %s "%s -R %s serve --stdio"'
mpm@selenic.com
Break apart hg.py...
r1089 cmd = cmd % (sshcmd, args, remotecmd, self.path)
Bryan O'Sullivan
Help debugability: print ssh command being used when --verbose.
r1332 ui.note('running %s\n' % cmd)
Bryan O'Sullivan
Give ssh a better chance of working on Windows....
r1330 self.pipeo, self.pipei, self.pipee = os.popen3(cmd, 'b')
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
ssh: skip noise generated by remote shell...
r2028 # skip any noise generated by remote shell
Matt Mackall
ssh: add capability detection at startup...
r2421 self.do_cmd("hello")
Matt Mackall
ssh: skip noise generated by remote shell...
r2028 r = self.do_cmd("between", pairs=("%s-%s" % ("0"*40, "0"*40)))
Matt Mackall
ssh: gather initial output so we can do capability detection
r2420 lines = ["", "dummy"]
Thomas Arendsen Hein
Show remote ssh noise only with --debug and increase the limit to 500 lines....
r2046 max_noise = 500
Matt Mackall
ssh: gather initial output so we can do capability detection
r2420 while lines[-1] and max_noise:
l = r.readline()
Matt Mackall
ssh: skip noise generated by remote shell...
r2028 self.readerr()
Matt Mackall
ssh: gather initial output so we can do capability detection
r2420 if lines[-1] == "1\n" and l == "\n":
Matt Mackall
ssh: skip noise generated by remote shell...
r2028 break
Matt Mackall
ssh: gather initial output so we can do capability detection
r2420 if l:
ui.debug(_("remote: "), l)
lines.append(l)
Thomas Arendsen Hein
Don't enter an endless loop if remote hg doesn't answer, show remote noise....
r2040 max_noise -= 1
else:
Benoit Boissinot
ssh: make the error message more clear, add a testcase
r3275 raise hg.RepoError(_("no suitable response from remote hg"))
Matt Mackall
ssh: skip noise generated by remote shell...
r2028
Matt Mackall
ssh: add capability detection at startup...
r2421 self.capabilities = ()
lines.reverse()
for l in lines:
if l.startswith("capabilities:"):
self.capabilities = l[:-1].split(":")[1].split()
break
mpm@selenic.com
Break apart hg.py...
r1089 def readerr(self):
while 1:
Vadim Gelfer
fix file handling bugs on windows....
r2176 size = util.fstat(self.pipee).st_size
zbynek@alex.kolej.mff.cuni.cz
Replacing select.select() with os.fstat() which works also on windows.
r1357 if size == 0: break
mpm@selenic.com
Break apart hg.py...
r1089 l = self.pipee.readline()
if not l: break
Benoit Boissinot
i18n part2: use '_' for all strings who are part of the user interface
r1402 self.ui.status(_("remote: "), l)
mpm@selenic.com
Break apart hg.py...
r1089
Benoit Boissinot
sshrepo: flush stderr before connecting to the hg server
r3034 def cleanup(self):
mpm@selenic.com
Break apart hg.py...
r1089 try:
self.pipeo.close()
self.pipei.close()
Matt Mackall
Partially revert ssh change so we read all of remote ssh stream
r1358 # read the error descriptor until EOF
for l in self.pipee:
Benoit Boissinot
i18n part2: use '_' for all strings who are part of the user interface
r1402 self.ui.status(_("remote: "), l)
mpm@selenic.com
Break apart hg.py...
r1089 self.pipee.close()
except:
pass
Benoit Boissinot
sshrepo: flush stderr before connecting to the hg server
r3034 __del__ = cleanup
mpm@selenic.com
Break apart hg.py...
r1089 def do_cmd(self, cmd, **args):
Benoit Boissinot
i18n part2: use '_' for all strings who are part of the user interface
r1402 self.ui.debug(_("sending %s command\n") % cmd)
mpm@selenic.com
Break apart hg.py...
r1089 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:
Benoit Boissinot
i18n part2: use '_' for all strings who are part of the user interface
r1402 raise hg.RepoError(_("unexpected response '%s'") % l)
mpm@selenic.com
Break apart hg.py...
r1089 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:
Benoit Boissinot
i18n part2: use '_' for all strings who are part of the user interface
r1402 raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "..."))
mpm@selenic.com
Break apart hg.py...
r1089
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:
Benoit Boissinot
i18n part2: use '_' for all strings who are part of the user interface
r1402 raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "..."))
mpm@selenic.com
Break apart hg.py...
r1089
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:
Benoit Boissinot
i18n part2: use '_' for all strings who are part of the user interface
r1402 raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "..."))
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
add preoutgoing and outgoing hooks....
r1736 def changegroup(self, nodes, kind):
mpm@selenic.com
Break apart hg.py...
r1089 n = " ".join(map(hex, nodes))
Benoit Boissinot
fix unused variable warning from pychecker
r2449 return self.do_cmd("changegroup", roots=n)
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 def unbundle(self, cg, heads, source):
d = self.call("unbundle", heads=' '.join(map(hex, heads)))
if d:
raise hg.RepoError(_("push refused: %s") % d)
while 1:
d = cg.read(4096)
if not d: break
self.pipeo.write(str(len(d)) + '\n')
self.pipeo.write(d)
self.readerr()
self.pipeo.write('0\n')
self.pipeo.flush()
self.readerr()
d = self.pipei.readline()
if d != '\n':
return 1
l = int(self.pipei.readline())
r = self.pipei.read(l)
if not r:
return 1
return int(r)
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 def addchangegroup(self, cg, source, url):
mpm@selenic.com
Break apart hg.py...
r1089 d = self.call("addchangegroup")
if d:
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 raise hg.RepoError(_("push refused: %s") % d)
mpm@selenic.com
Break apart hg.py...
r1089 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())
Vadim Gelfer
add merge command. means same thing as "update -m"....
r2019 r = self.pipei.read(l)
if not r:
return 1
return int(r)
Vadim Gelfer
add support for streaming clone....
r2612
def stream_out(self):
return self.do_cmd('stream_out')
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740
instance = sshrepository