backends: use reference explicitly to properly translate GIT references to commits such as numeric branches

This commit is contained in:
Milka Kuzminski 2021-03-16 23:18:52 +01:00
parent a801004fc7
commit 2cc353de2c
7 changed files with 31 additions and 15 deletions

View file

@ -655,7 +655,7 @@ def get_clone_url(request, uri_tmpl, repo_name, repo_id, repo_type, **override):
def get_commit_safe(repo, commit_id=None, commit_idx=None, pre_load=None,
maybe_unreachable=False):
maybe_unreachable=False, reference_obj=None):
"""
Safe version of get_commit if this commit doesn't exists for a
repository it returns a Dummy one instead
@ -665,6 +665,7 @@ def get_commit_safe(repo, commit_id=None, commit_idx=None, pre_load=None,
:param commit_idx: numeric commit index
:param pre_load: optional list of commit attributes to load
:param maybe_unreachable: translate unreachable commits on git repos
:param reference_obj: explicitly search via a reference obj in git. E.g "branch:123" would mean branch "123"
"""
# TODO(skreft): remove these circular imports
from rhodecode.lib.vcs.backends.base import BaseRepository, EmptyCommit
@ -676,7 +677,7 @@ def get_commit_safe(repo, commit_id=None, commit_idx=None, pre_load=None,
try:
commit = repo.get_commit(
commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load,
maybe_unreachable=maybe_unreachable)
maybe_unreachable=maybe_unreachable, reference_obj=reference_obj)
except (RepositoryError, LookupError):
commit = EmptyCommit()
return commit

View file

@ -72,6 +72,10 @@ class Reference(_Reference):
if self.type == 'book':
return self.name
@property
def to_unicode(self):
return reference_to_unicode(self)
def unicode_to_reference(raw):
"""
@ -483,7 +487,7 @@ class BaseRepository(object):
self._is_empty = False
def get_commit(self, commit_id=None, commit_idx=None, pre_load=None,
translate_tag=None, maybe_unreachable=False):
translate_tag=None, maybe_unreachable=False, reference_obj=None):
"""
Returns instance of `BaseCommit` class. If `commit_id` and `commit_idx`
are both None, most recent commit is returned.

View file

@ -228,7 +228,8 @@ class GitRepository(BaseRepository):
return []
return output.splitlines()
def _lookup_commit(self, commit_id_or_idx, translate_tag=True, maybe_unreachable=False):
def _lookup_commit(self, commit_id_or_idx, translate_tag=True, maybe_unreachable=False, reference_obj=None):
def is_null(value):
return len(value) == commit_id_or_idx.count('0')
@ -239,15 +240,20 @@ class GitRepository(BaseRepository):
*map(safe_str, [commit_id_or_idx, self.name]))
is_bstr = isinstance(commit_id_or_idx, (str, unicode))
if ((is_bstr and commit_id_or_idx.isdigit() and len(commit_id_or_idx) < 12)
or isinstance(commit_id_or_idx, int) or is_null(commit_id_or_idx)):
is_branch = reference_obj and reference_obj.branch
is_numeric_idx = \
(is_bstr and commit_id_or_idx.isdigit() and len(commit_id_or_idx) < 12) \
or isinstance(commit_id_or_idx, int)
if not is_branch and (is_numeric_idx or is_null(commit_id_or_idx)):
try:
commit_id_or_idx = self.commit_ids[int(commit_id_or_idx)]
except Exception:
raise CommitDoesNotExistError(commit_missing_err)
elif is_bstr:
# Need to call remote to translate id for tagging scenario
# Need to call remote to translate id for tagging scenarios,
# or branch that are numeric
try:
remote_data = self._remote.get_object(commit_id_or_idx,
maybe_unreachable=maybe_unreachable)
@ -413,11 +419,12 @@ class GitRepository(BaseRepository):
return
def get_commit(self, commit_id=None, commit_idx=None, pre_load=None,
translate_tag=True, maybe_unreachable=False):
translate_tag=True, maybe_unreachable=False, reference_obj=None):
"""
Returns `GitCommit` object representing commit from git repository
at the given `commit_id` or head (most recent commit) if None given.
"""
if self.is_empty():
raise EmptyRepositoryError("There are no commits yet")
@ -443,7 +450,9 @@ class GitRepository(BaseRepository):
commit_id = "tip"
if translate_tag:
commit_id = self._lookup_commit(commit_id, maybe_unreachable=maybe_unreachable)
commit_id = self._lookup_commit(
commit_id, maybe_unreachable=maybe_unreachable,
reference_obj=reference_obj)
try:
idx = self._commit_ids[commit_id]

View file

@ -437,7 +437,7 @@ class MercurialRepository(BaseRepository):
return os.path.join(self.path, '.hg', '.hgrc')
def get_commit(self, commit_id=None, commit_idx=None, pre_load=None,
translate_tag=None, maybe_unreachable=False):
translate_tag=None, maybe_unreachable=False, reference_obj=None):
"""
Returns ``MercurialCommit`` object representing repository's
commit at the given `commit_id` or `commit_idx`.

View file

@ -277,7 +277,7 @@ class SubversionRepository(base.BaseRepository):
return os.path.join(self.path, 'hooks')
def get_commit(self, commit_id=None, commit_idx=None, pre_load=None,
translate_tag=None, maybe_unreachable=False):
translate_tag=None, maybe_unreachable=False, reference_obj=None):
if self.is_empty():
raise EmptyRepositoryError("There are no commits yet")
if commit_id is not None:

View file

@ -2398,10 +2398,10 @@ class Repository(Base, BaseModel):
# SCM PROPERTIES
#==========================================================================
def get_commit(self, commit_id=None, commit_idx=None, pre_load=None, maybe_unreachable=False):
def get_commit(self, commit_id=None, commit_idx=None, pre_load=None, maybe_unreachable=False, reference_obj=None):
return get_commit_safe(
self.scm_instance(), commit_id, commit_idx, pre_load=pre_load,
maybe_unreachable=maybe_unreachable)
maybe_unreachable=maybe_unreachable, reference_obj=reference_obj)
def get_changeset(self, rev=None, pre_load=None):
warnings.warn("Use get_commit", DeprecationWarning)

View file

@ -908,7 +908,8 @@ class PullRequestModel(BaseModel):
try:
if source_ref_type in self.REF_TYPES:
source_commit = source_repo.get_commit(source_ref_name)
source_commit = source_repo.get_commit(
source_ref_name, reference_obj=pull_request.source_ref_parts)
else:
source_commit = source_repo.get_commit(source_ref_id)
except CommitDoesNotExistError:
@ -922,7 +923,8 @@ class PullRequestModel(BaseModel):
try:
if target_ref_type in self.REF_TYPES:
target_commit = target_repo.get_commit(target_ref_name)
target_commit = target_repo.get_commit(
target_ref_name, reference_obj=pull_request.target_ref_parts)
else:
target_commit = target_repo.get_commit(target_ref_id)
except CommitDoesNotExistError: