##// END OF EJS Templates
Partially revert ssh change so we read all of remote ssh stream
Matt Mackall -
r1358:20abfd48 default
parent child Browse files
Show More
@@ -1,130 +1,132 b''
1 # sshrepo.py - ssh repository proxy class for mercurial
1 # sshrepo.py - ssh repository proxy class for mercurial
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from node import *
8 from node import *
9 from remoterepo import *
9 from remoterepo import *
10 from demandload import *
10 from demandload import *
11 demandload(globals(), "hg os re stat")
11 demandload(globals(), "hg os re stat")
12
12
13 class sshrepository(remoterepository):
13 class sshrepository(remoterepository):
14 def __init__(self, ui, path):
14 def __init__(self, ui, path):
15 self.url = path
15 self.url = path
16 self.ui = ui
16 self.ui = ui
17
17
18 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path)
18 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path)
19 if not m:
19 if not m:
20 raise hg.RepoError("couldn't parse destination %s" % path)
20 raise hg.RepoError("couldn't parse destination %s" % path)
21
21
22 self.user = m.group(2)
22 self.user = m.group(2)
23 self.host = m.group(3)
23 self.host = m.group(3)
24 self.port = m.group(5)
24 self.port = m.group(5)
25 self.path = m.group(7) or "."
25 self.path = m.group(7) or "."
26
26
27 args = self.user and ("%s@%s" % (self.user, self.host)) or self.host
27 args = self.user and ("%s@%s" % (self.user, self.host)) or self.host
28 args = self.port and ("%s -p %s") % (args, self.port) or args
28 args = self.port and ("%s -p %s") % (args, self.port) or args
29
29
30 sshcmd = self.ui.config("ui", "ssh", "ssh")
30 sshcmd = self.ui.config("ui", "ssh", "ssh")
31 remotecmd = self.ui.config("ui", "remotecmd", "hg")
31 remotecmd = self.ui.config("ui", "remotecmd", "hg")
32 cmd = '%s %s "%s -R %s serve --stdio"'
32 cmd = '%s %s "%s -R %s serve --stdio"'
33 cmd = cmd % (sshcmd, args, remotecmd, self.path)
33 cmd = cmd % (sshcmd, args, remotecmd, self.path)
34
34
35 ui.note('running %s\n' % cmd)
35 ui.note('running %s\n' % cmd)
36 self.pipeo, self.pipei, self.pipee = os.popen3(cmd, 'b')
36 self.pipeo, self.pipei, self.pipee = os.popen3(cmd, 'b')
37
37
38 def readerr(self):
38 def readerr(self):
39 while 1:
39 while 1:
40 size = os.fstat(self.pipee.fileno())[stat.ST_SIZE]
40 size = os.fstat(self.pipee.fileno())[stat.ST_SIZE]
41 if size == 0: break
41 if size == 0: break
42 l = self.pipee.readline()
42 l = self.pipee.readline()
43 if not l: break
43 if not l: break
44 self.ui.status("remote: ", l)
44 self.ui.status("remote: ", l)
45
45
46 def __del__(self):
46 def __del__(self):
47 try:
47 try:
48 self.pipeo.close()
48 self.pipeo.close()
49 self.pipei.close()
49 self.pipei.close()
50 readerr()
50 # read the error descriptor until EOF
51 for l in self.pipee:
52 self.ui.status("remote: ", l)
51 self.pipee.close()
53 self.pipee.close()
52 except:
54 except:
53 pass
55 pass
54
56
55 def dev(self):
57 def dev(self):
56 return -1
58 return -1
57
59
58 def do_cmd(self, cmd, **args):
60 def do_cmd(self, cmd, **args):
59 self.ui.debug("sending %s command\n" % cmd)
61 self.ui.debug("sending %s command\n" % cmd)
60 self.pipeo.write("%s\n" % cmd)
62 self.pipeo.write("%s\n" % cmd)
61 for k, v in args.items():
63 for k, v in args.items():
62 self.pipeo.write("%s %d\n" % (k, len(v)))
64 self.pipeo.write("%s %d\n" % (k, len(v)))
63 self.pipeo.write(v)
65 self.pipeo.write(v)
64 self.pipeo.flush()
66 self.pipeo.flush()
65
67
66 return self.pipei
68 return self.pipei
67
69
68 def call(self, cmd, **args):
70 def call(self, cmd, **args):
69 r = self.do_cmd(cmd, **args)
71 r = self.do_cmd(cmd, **args)
70 l = r.readline()
72 l = r.readline()
71 self.readerr()
73 self.readerr()
72 try:
74 try:
73 l = int(l)
75 l = int(l)
74 except:
76 except:
75 raise hg.RepoError("unexpected response '%s'" % l)
77 raise hg.RepoError("unexpected response '%s'" % l)
76 return r.read(l)
78 return r.read(l)
77
79
78 def lock(self):
80 def lock(self):
79 self.call("lock")
81 self.call("lock")
80 return remotelock(self)
82 return remotelock(self)
81
83
82 def unlock(self):
84 def unlock(self):
83 self.call("unlock")
85 self.call("unlock")
84
86
85 def heads(self):
87 def heads(self):
86 d = self.call("heads")
88 d = self.call("heads")
87 try:
89 try:
88 return map(bin, d[:-1].split(" "))
90 return map(bin, d[:-1].split(" "))
89 except:
91 except:
90 raise hg.RepoError("unexpected response '%s'" % (d[:400] + "..."))
92 raise hg.RepoError("unexpected response '%s'" % (d[:400] + "..."))
91
93
92 def branches(self, nodes):
94 def branches(self, nodes):
93 n = " ".join(map(hex, nodes))
95 n = " ".join(map(hex, nodes))
94 d = self.call("branches", nodes=n)
96 d = self.call("branches", nodes=n)
95 try:
97 try:
96 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
98 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
97 return br
99 return br
98 except:
100 except:
99 raise hg.RepoError("unexpected response '%s'" % (d[:400] + "..."))
101 raise hg.RepoError("unexpected response '%s'" % (d[:400] + "..."))
100
102
101 def between(self, pairs):
103 def between(self, pairs):
102 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
104 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
103 d = self.call("between", pairs=n)
105 d = self.call("between", pairs=n)
104 try:
106 try:
105 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
107 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
106 return p
108 return p
107 except:
109 except:
108 raise hg.RepoError("unexpected response '%s'" % (d[:400] + "..."))
110 raise hg.RepoError("unexpected response '%s'" % (d[:400] + "..."))
109
111
110 def changegroup(self, nodes):
112 def changegroup(self, nodes):
111 n = " ".join(map(hex, nodes))
113 n = " ".join(map(hex, nodes))
112 f = self.do_cmd("changegroup", roots=n)
114 f = self.do_cmd("changegroup", roots=n)
113 return self.pipei
115 return self.pipei
114
116
115 def addchangegroup(self, cg):
117 def addchangegroup(self, cg):
116 d = self.call("addchangegroup")
118 d = self.call("addchangegroup")
117 if d:
119 if d:
118 raise hg.RepoError("push refused: %s", d)
120 raise hg.RepoError("push refused: %s", d)
119
121
120 while 1:
122 while 1:
121 d = cg.read(4096)
123 d = cg.read(4096)
122 if not d: break
124 if not d: break
123 self.pipeo.write(d)
125 self.pipeo.write(d)
124 self.readerr()
126 self.readerr()
125
127
126 self.pipeo.flush()
128 self.pipeo.flush()
127
129
128 self.readerr()
130 self.readerr()
129 l = int(self.pipei.readline())
131 l = int(self.pipei.readline())
130 return self.pipei.read(l) != ""
132 return self.pipei.read(l) != ""
General Comments 0
You need to be logged in to leave comments. Login now