summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--git_config.py42
-rw-r--r--project.py73
2 files changed, 91 insertions, 24 deletions
diff --git a/git_config.py b/git_config.py
index 9ddb2edc..ed5a44a4 100644
--- a/git_config.py
+++ b/git_config.py
@@ -16,7 +16,8 @@
16import os 16import os
17import re 17import re
18import sys 18import sys
19from error import GitError 19from urllib2 import urlopen, HTTPError
20from error import GitError, UploadError
20from git_command import GitCommand 21from git_command import GitCommand
21 22
22R_HEADS = 'refs/heads/' 23R_HEADS = 'refs/heads/'
@@ -261,6 +262,45 @@ class Remote(object):
261 self.projectname = self._Get('projectname') 262 self.projectname = self._Get('projectname')
262 self.fetch = map(lambda x: RefSpec.FromString(x), 263 self.fetch = map(lambda x: RefSpec.FromString(x),
263 self._Get('fetch', all=True)) 264 self._Get('fetch', all=True))
265 self._review_protocol = None
266
267 @property
268 def ReviewProtocol(self):
269 if self._review_protocol is None:
270 if self.review is None:
271 return None
272
273 u = self.review
274 if not u.startswith('http:') and not u.startswith('https:'):
275 u = 'http://%s' % u
276 if not u.endswith('/'):
277 u += '/'
278 u += 'ssh_info'
279
280 try:
281 info = urlopen(u).read()
282 if info == 'NOT_AVAILABLE':
283 raise UploadError('Upload over ssh unavailable')
284
285 self._review_protocol = 'ssh'
286 self._review_host = info.split(" ")[0]
287 self._review_port = info.split(" ")[1]
288
289 except HTTPError, e:
290 if e.code == 404:
291 self._review_protocol = 'http-post'
292 else:
293 raise UploadError('Cannot guess Gerrit version')
294 return self._review_protocol
295
296 def SshReviewUrl(self, userEmail):
297 if self.ReviewProtocol != 'ssh':
298 return None
299 return 'ssh://%s@%s:%s/%s' % (
300 userEmail.split("@")[0],
301 self._review_host,
302 self._review_port,
303 self.projectname)
264 304
265 def ToLocal(self, rev): 305 def ToLocal(self, rev):
266 """Convert a remote revision string to something we have locally. 306 """Convert a remote revision string to something we have locally.
diff --git a/project.py b/project.py
index 7743ca10..5d036c35 100644
--- a/project.py
+++ b/project.py
@@ -46,6 +46,8 @@ def _info(fmt, *args):
46def not_rev(r): 46def not_rev(r):
47 return '^' + r 47 return '^' + r
48 48
49def sq(r):
50 return "'" + r.replace("'", "'\''") + "'"
49 51
50hook_list = None 52hook_list = None
51def repo_hooks(): 53def repo_hooks():
@@ -475,33 +477,58 @@ class Project(object):
475 if not dest_branch.startswith(R_HEADS): 477 if not dest_branch.startswith(R_HEADS):
476 dest_branch = R_HEADS + dest_branch 478 dest_branch = R_HEADS + dest_branch
477 479
478 base_list = []
479 for name, id in self._allrefs.iteritems():
480 if branch.remote.WritesTo(name):
481 base_list.append(not_rev(name))
482 if not base_list:
483 raise GitError('no base refs, cannot upload %s' % branch.name)
484
485 if not branch.remote.projectname: 480 if not branch.remote.projectname:
486 branch.remote.projectname = self.name 481 branch.remote.projectname = self.name
487 branch.remote.Save() 482 branch.remote.Save()
488 483
489 print >>sys.stderr, '' 484 if branch.remote.ReviewProtocol == 'http-post':
490 _info("Uploading %s to %s:", branch.name, self.name) 485 base_list = []
491 try: 486 for name, id in self._allrefs.iteritems():
492 UploadBundle(project = self, 487 if branch.remote.WritesTo(name):
493 server = branch.remote.review, 488 base_list.append(not_rev(name))
494 email = self.UserEmail, 489 if not base_list:
495 dest_project = branch.remote.projectname, 490 raise GitError('no base refs, cannot upload %s' % branch.name)
496 dest_branch = dest_branch, 491
497 src_branch = R_HEADS + branch.name, 492 print >>sys.stderr, ''
498 bases = base_list, 493 _info("Uploading %s to %s:", branch.name, self.name)
499 people = people, 494 try:
500 replace_changes = replace_changes) 495 UploadBundle(project = self,
501 except proto_client.ClientLoginError: 496 server = branch.remote.review,
502 raise UploadError('Login failure') 497 email = self.UserEmail,
503 except urllib2.HTTPError, e: 498 dest_project = branch.remote.projectname,
504 raise UploadError('HTTP error %d' % e.code) 499 dest_branch = dest_branch,
500 src_branch = R_HEADS + branch.name,
501 bases = base_list,
502 people = people,
503 replace_changes = replace_changes)
504 except proto_client.ClientLoginError:
505 raise UploadError('Login failure')
506 except urllib2.HTTPError, e:
507 raise UploadError('HTTP error %d' % e.code)
508
509 elif branch.remote.ReviewProtocol == 'ssh':
510 if dest_branch.startswith(R_HEADS):
511 dest_branch = dest_branch[len(R_HEADS):]
512
513 rp = ['gerrit receive-pack']
514 for e in people[0]:
515 rp.append('--reviewer=%s' % sq(e))
516 for e in people[1]:
517 rp.append('--cc=%s' % sq(e))
518
519 cmd = ['push']
520 cmd.append('--receive-pack=%s' % " ".join(rp))
521 cmd.append(branch.remote.SshReviewUrl(self.UserEmail))
522 cmd.append('%s:refs/for/%s' % (R_HEADS + branch.name, dest_branch))
523 if replace_changes:
524 for change_id,commit_id in replace_changes.iteritems():
525 cmd.append('%s:refs/changes/%s/new' % (commit_id, change_id))
526 if GitCommand(self, cmd, bare = True).Wait() != 0:
527 raise UploadError('Upload failed')
528
529 else:
530 raise UploadError('Unsupported protocol %s' \
531 % branch.remote.review)
505 532
506 msg = "posted to %s for %s" % (branch.remote.review, dest_branch) 533 msg = "posted to %s for %s" % (branch.remote.review, dest_branch)
507 self.bare_git.UpdateRef(R_PUB + branch.name, 534 self.bare_git.UpdateRef(R_PUB + branch.name,