diff --git a/rhodecode/lib/utils2.py b/rhodecode/lib/utils2.py --- a/rhodecode/lib/utils2.py +++ b/rhodecode/lib/utils2.py @@ -655,7 +655,7 @@ def get_clone_url(request, uri_tmpl, rep 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 :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 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 diff --git a/rhodecode/lib/vcs/backends/base.py b/rhodecode/lib/vcs/backends/base.py --- a/rhodecode/lib/vcs/backends/base.py +++ b/rhodecode/lib/vcs/backends/base.py @@ -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. diff --git a/rhodecode/lib/vcs/backends/git/repository.py b/rhodecode/lib/vcs/backends/git/repository.py --- a/rhodecode/lib/vcs/backends/git/repository.py +++ b/rhodecode/lib/vcs/backends/git/repository.py @@ -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] diff --git a/rhodecode/lib/vcs/backends/hg/repository.py b/rhodecode/lib/vcs/backends/hg/repository.py --- a/rhodecode/lib/vcs/backends/hg/repository.py +++ b/rhodecode/lib/vcs/backends/hg/repository.py @@ -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`. diff --git a/rhodecode/lib/vcs/backends/svn/repository.py b/rhodecode/lib/vcs/backends/svn/repository.py --- a/rhodecode/lib/vcs/backends/svn/repository.py +++ b/rhodecode/lib/vcs/backends/svn/repository.py @@ -277,7 +277,7 @@ class SubversionRepository(base.BaseRepo 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: diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -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) diff --git a/rhodecode/model/pull_request.py b/rhodecode/model/pull_request.py --- a/rhodecode/model/pull_request.py +++ b/rhodecode/model/pull_request.py @@ -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: