201
201
return PermissionDenied(url, message)
202
202
if message.endswith(' does not appear to be a git repository'):
203
203
return NotBranchError(url, message)
204
if message == 'pre-receive hook declined':
205
return PermissionDenied(url, message)
204
206
if re.match('(.+) is not a valid repository name',
205
207
message.splitlines()[0]):
206
208
return NotBranchError(url, message)
210
'GitLab: You are not allowed to push code to protected branches '
212
return PermissionDenied(url, message)
207
213
m = re.match(r'Permission to ([^ ]+) denied to ([^ ]+)\.', message)
209
215
return PermissionDenied(m.group(1), 'denied to %s' % m.group(2))
211
217
return RemoteGitError(message)
220
def parse_git_hangup(url, e):
221
"""Parse the error lines from a git servers stderr on hangup.
223
:param url: URL of the remote repository
224
:param e: A HangupException
226
stderr_lines = getattr(e, 'stderr_lines', None)
229
if all(line.startswith(b'remote: ') for line in stderr_lines):
231
line[len(b'remote: '):] for line in stderr_lines]
232
interesting_lines = [
233
line for line in stderr_lines
234
if line and line.replace(b'=', b'')]
235
if len(interesting_lines) == 1:
236
interesting_line = interesting_lines[0]
237
return parse_git_error(
238
url, interesting_line.decode('utf-8', 'surrogateescape'))
239
return RemoteGitError(
240
b'\n'.join(stderr_lines).decode('utf-8', 'surrogateescape'))
214
243
class GitSmartTransport(Transport):
216
245
def __init__(self, url, _client=None):
408
437
format=(format.encode('ascii') if format else None),
410
prefix=(prefix.encode('utf-8') if prefix else None))
439
prefix=(encode_git_path(prefix) if prefix else None))
440
except HangupException as e:
441
raise parse_git_hangup(self.transport.external_url(), e)
411
442
except GitProtocolError as e:
412
443
raise parse_git_error(self.transport.external_url(), e)
430
461
self._refs = remote_refs_dict_to_container(
431
462
result.refs, result.symrefs)
464
except HangupException as e:
465
raise parse_git_hangup(self.transport.external_url(), e)
433
466
except GitProtocolError as e:
434
467
raise parse_git_error(self.transport.external_url(), e)
451
484
return self._client.send_pack(
452
485
self._client_path, get_changed_refs_wrapper,
453
486
generate_pack_data, progress)
487
except HangupException as e:
488
raise parse_git_hangup(self.transport.external_url(), e)
454
489
except GitProtocolError as e:
455
490
raise parse_git_error(self.transport.external_url(), e)
482
517
def generate_pack_data(have, want, ofs_delta=False):
483
518
return pack_objects_to_data([])
484
self.send_pack(get_changed_refs, generate_pack_data)
519
result = self.send_pack(get_changed_refs, generate_pack_data)
520
if result is not None and not isinstance(result, dict):
521
error = result.ref_status.get(refname)
523
raise RemoteGitError(error)
487
526
def user_url(self):
546
585
def push_branch(self, source, revision_id=None, overwrite=False,
547
586
remember=False, create_prefix=False, lossy=False,
587
name=None, tag_selector=None):
549
588
"""Push the source branch into this ControlDir."""
550
589
if revision_id is None:
551
590
# No revision supplied by the user, default to the branch
553
592
revision_id = source.last_revision()
594
if not source.repository.has_revision(revision_id):
595
raise NoSuchRevision(source, revision_id)
555
597
push_result = GitPushResult()
556
598
push_result.workingtree_updated = None
560
602
push_result.branch_push_result = None
561
603
repo = self.find_repository()
562
604
refname = self._get_selected_ref(name)
563
ref_chain, old_sha = self.get_refs_container().follow(refname)
565
actual_refname = ref_chain[-1]
606
ref_chain, old_sha = self.get_refs_container().follow(refname)
607
except NotBranchError:
567
608
actual_refname = refname
612
actual_refname = ref_chain[-1]
614
actual_refname = refname
568
615
if isinstance(source, GitBranch) and lossy:
569
616
raise errors.LossyPushToSameVCS(source.controldir, self)
570
617
source_store = get_object_store(source.repository)
584
631
raise errors.NoRoundtrippingSupport(
585
632
source, self.open_branch(name=name, nascent_ok=True))
586
633
if not overwrite:
634
old_sha = remote_refs.get(actual_refname)
587
635
if remote_divergence(old_sha, new_sha, source_store):
588
636
raise DivergedBranches(
589
637
source, self.open_branch(name, nascent_ok=True))
590
638
ret[actual_refname] = new_sha
592
640
for tagname, revid in source.tags.get_tag_dict().items():
641
if tag_selector and not tag_selector(tagname):
595
645
new_sha = source_store._lookup_revision_sha1(revid)
601
651
new_sha = repo.lookup_bzr_revision_id(revid)[0]
602
652
except errors.NoSuchRevision:
655
if not source.repository.has_revision(revid):
604
657
ret[tag_name_to_ref(tagname)] = new_sha
606
659
with source_store.lock_read():
608
generate_pack_data = source_store.generate_lossy_pack_data
610
generate_pack_data = source_store.generate_pack_data
611
new_refs = self.send_pack(get_changed_refs, generate_pack_data)
660
def generate_pack_data(have, want, progress=None,
662
git_repo = getattr(source.repository, '_git', None)
664
shallow = git_repo.get_shallow()
668
return source_store.generate_lossy_pack_data(
669
have, want, shallow=shallow,
670
progress=progress, ofs_delta=ofs_delta)
672
return source_store.generate_pack_data(
673
have, want, shallow=shallow,
674
progress=progress, ofs_delta=ofs_delta)
676
return source_store.generate_pack_data(
677
have, want, progress=progress, ofs_delta=ofs_delta)
678
dw_result = self.send_pack(get_changed_refs, generate_pack_data)
679
if not isinstance(dw_result, dict):
680
new_refs = dw_result.refs
681
error = dw_result.ref_status.get(actual_refname)
683
raise RemoteGitError(error)
684
for ref, error in dw_result.ref_status.items():
686
trace.warning('unable to open ref %s: %s',
688
else: # dulwich < 0.20.4
612
690
push_result.new_revid = repo.lookup_foreign_revision_id(
613
691
new_refs[actual_refname])
614
692
if old_sha is not None:
710
788
raise NotGitRepository()
711
789
elif response.status != 200:
712
790
raise GitProtocolError("unexpected http resp %d for %s" %
713
(response.code, url))
791
(response.status, url))
715
793
# TODO: Optimization available by adding `preload_content=False` to the
716
794
# request and just passing the `read` method on instead of going via
870
949
def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
872
952
fd, path = tempfile.mkstemp(suffix=".pack")
874
954
self.fetch_pack(determine_wants, graph_walker,
928
1008
def generate_pack_data(have, want, ofs_delta=False):
929
1009
return pack_objects_to_data([])
930
self.repository.send_pack(get_changed_refs, generate_pack_data)
1010
result = self.repository.send_pack(
1011
get_changed_refs, generate_pack_data)
1012
if result and not isinstance(result, dict):
1013
error = result.ref_status.get(ref)
1015
raise RemoteGitError(error)
933
1018
class RemoteGitBranch(GitBranch):
1011
1096
return {self.ref: sha}
1012
1097
def generate_pack_data(have, want, ofs_delta=False):
1013
1098
return pack_objects_to_data([])
1014
self.repository.send_pack(get_changed_refs, generate_pack_data)
1099
result = self.repository.send_pack(
1100
get_changed_refs, generate_pack_data)
1101
if result is not None and not isinstance(result, dict):
1102
error = result.ref_status.get(self.ref)
1104
raise RemoteGitError(error)
1015
1105
self._sha = sha