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