##// END OF EJS Templates
sshrepo: when creating a repo, raise an error if it already exists
Benoit Boissinot -
r3036:adf7f342 default
parent child Browse files
Show More
@@ -1,213 +1,214 b''
1 1 # sshrepo.py - ssh repository proxy class for mercurial
2 2 #
3 3 # Copyright 2005, 2006 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, create=0):
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 location %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
34 34 if create:
35 35 try:
36 36 self.validate_repo(ui, sshcmd, args, remotecmd)
37 return # the repo is good, nothing more to do
38 37 except hg.RepoError:
39 38 pass
39 else:
40 raise hg.RepoError(_("repository %s already exists") % path)
40 41
41 42 cmd = '%s %s "%s init %s"'
42 43 cmd = cmd % (sshcmd, args, remotecmd, self.path)
43 44
44 45 ui.note('running %s\n' % cmd)
45 46 res = os.system(cmd)
46 47 if res != 0:
47 48 raise hg.RepoError(_("could not create remote repo"))
48 49
49 50 self.validate_repo(ui, sshcmd, args, remotecmd)
50 51
51 52 def url(self):
52 53 return self._url
53 54
54 55 def validate_repo(self, ui, sshcmd, args, remotecmd):
55 56 # cleanup up previous run
56 57 self.cleanup()
57 58
58 59 cmd = '%s %s "%s -R %s serve --stdio"'
59 60 cmd = cmd % (sshcmd, args, remotecmd, self.path)
60 61
61 62 ui.note('running %s\n' % cmd)
62 63 self.pipeo, self.pipei, self.pipee = os.popen3(cmd, 'b')
63 64
64 65 # skip any noise generated by remote shell
65 66 self.do_cmd("hello")
66 67 r = self.do_cmd("between", pairs=("%s-%s" % ("0"*40, "0"*40)))
67 68 lines = ["", "dummy"]
68 69 max_noise = 500
69 70 while lines[-1] and max_noise:
70 71 l = r.readline()
71 72 self.readerr()
72 73 if lines[-1] == "1\n" and l == "\n":
73 74 break
74 75 if l:
75 76 ui.debug(_("remote: "), l)
76 77 lines.append(l)
77 78 max_noise -= 1
78 79 else:
79 80 raise hg.RepoError(_("no response from remote hg"))
80 81
81 82 self.capabilities = ()
82 83 lines.reverse()
83 84 for l in lines:
84 85 if l.startswith("capabilities:"):
85 86 self.capabilities = l[:-1].split(":")[1].split()
86 87 break
87 88
88 89 def readerr(self):
89 90 while 1:
90 91 size = util.fstat(self.pipee).st_size
91 92 if size == 0: break
92 93 l = self.pipee.readline()
93 94 if not l: break
94 95 self.ui.status(_("remote: "), l)
95 96
96 97 def cleanup(self):
97 98 try:
98 99 self.pipeo.close()
99 100 self.pipei.close()
100 101 # read the error descriptor until EOF
101 102 for l in self.pipee:
102 103 self.ui.status(_("remote: "), l)
103 104 self.pipee.close()
104 105 except:
105 106 pass
106 107
107 108 __del__ = cleanup
108 109
109 110 def do_cmd(self, cmd, **args):
110 111 self.ui.debug(_("sending %s command\n") % cmd)
111 112 self.pipeo.write("%s\n" % cmd)
112 113 for k, v in args.items():
113 114 self.pipeo.write("%s %d\n" % (k, len(v)))
114 115 self.pipeo.write(v)
115 116 self.pipeo.flush()
116 117
117 118 return self.pipei
118 119
119 120 def call(self, cmd, **args):
120 121 r = self.do_cmd(cmd, **args)
121 122 l = r.readline()
122 123 self.readerr()
123 124 try:
124 125 l = int(l)
125 126 except:
126 127 raise hg.RepoError(_("unexpected response '%s'") % l)
127 128 return r.read(l)
128 129
129 130 def lock(self):
130 131 self.call("lock")
131 132 return remotelock(self)
132 133
133 134 def unlock(self):
134 135 self.call("unlock")
135 136
136 137 def heads(self):
137 138 d = self.call("heads")
138 139 try:
139 140 return map(bin, d[:-1].split(" "))
140 141 except:
141 142 raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "..."))
142 143
143 144 def branches(self, nodes):
144 145 n = " ".join(map(hex, nodes))
145 146 d = self.call("branches", nodes=n)
146 147 try:
147 148 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
148 149 return br
149 150 except:
150 151 raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "..."))
151 152
152 153 def between(self, pairs):
153 154 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
154 155 d = self.call("between", pairs=n)
155 156 try:
156 157 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
157 158 return p
158 159 except:
159 160 raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "..."))
160 161
161 162 def changegroup(self, nodes, kind):
162 163 n = " ".join(map(hex, nodes))
163 164 return self.do_cmd("changegroup", roots=n)
164 165
165 166 def unbundle(self, cg, heads, source):
166 167 d = self.call("unbundle", heads=' '.join(map(hex, heads)))
167 168 if d:
168 169 raise hg.RepoError(_("push refused: %s") % d)
169 170
170 171 while 1:
171 172 d = cg.read(4096)
172 173 if not d: break
173 174 self.pipeo.write(str(len(d)) + '\n')
174 175 self.pipeo.write(d)
175 176 self.readerr()
176 177
177 178 self.pipeo.write('0\n')
178 179 self.pipeo.flush()
179 180
180 181 self.readerr()
181 182 d = self.pipei.readline()
182 183 if d != '\n':
183 184 return 1
184 185
185 186 l = int(self.pipei.readline())
186 187 r = self.pipei.read(l)
187 188 if not r:
188 189 return 1
189 190 return int(r)
190 191
191 192 def addchangegroup(self, cg, source, url):
192 193 d = self.call("addchangegroup")
193 194 if d:
194 195 raise hg.RepoError(_("push refused: %s") % d)
195 196 while 1:
196 197 d = cg.read(4096)
197 198 if not d: break
198 199 self.pipeo.write(d)
199 200 self.readerr()
200 201
201 202 self.pipeo.flush()
202 203
203 204 self.readerr()
204 205 l = int(self.pipei.readline())
205 206 r = self.pipei.read(l)
206 207 if not r:
207 208 return 1
208 209 return int(r)
209 210
210 211 def stream_out(self):
211 212 return self.do_cmd('stream_out')
212 213
213 214 instance = sshrepository
General Comments 0
You need to be logged in to leave comments. Login now