changeset 8059:000aa9cb25f1

vcs: refactor and simplify _get_revision This will be more thorough checking that revisions actually exist, and will in some cases give better error messages. But mainly, prepare for py3 where this was easier to make work correctly.
author Mads Kiilerich <mads@kiilerich.com>
date Thu, 02 Jan 2020 02:04:57 +0100
parents ca9df5a30ab2
children 2a902d81cb6f
files kallithea/lib/vcs/backends/git/repository.py kallithea/lib/vcs/backends/hg/repository.py
diffstat 2 files changed, 24 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/lib/vcs/backends/git/repository.py	Thu Dec 26 22:39:10 2019 +0100
+++ b/kallithea/lib/vcs/backends/git/repository.py	Thu Jan 02 02:04:57 2020 +0100
@@ -257,52 +257,50 @@
 
     def _get_revision(self, revision):
         """
-        For git backend we always return integer here. This way we ensure
-        that changeset's revision attribute would become integer.
+        Given any revision identifier, returns a 40 char string with revision hash.
         """
-
-        is_null = lambda o: len(o) == revision.count('0')
-
         if self._empty:
             raise EmptyRepositoryError("There are no changesets yet")
 
         if revision in (None, '', 'tip', 'HEAD', 'head', -1):
-            return self.revisions[-1]
+            revision = -1
 
-        is_bstr = isinstance(revision, (str, unicode))
-        if ((is_bstr and revision.isdigit() and len(revision) < 12)
-            or isinstance(revision, int) or is_null(revision)
-        ):
+        if isinstance(revision, int):
             try:
-                revision = self.revisions[int(revision)]
+                return self.revisions[revision]
             except IndexError:
                 msg = ("Revision %s does not exist for %s" % (revision, self))
                 raise ChangesetDoesNotExistError(msg)
 
-        elif is_bstr:
+        if isinstance(revision, (str, unicode)):
+            if revision.isdigit() and (len(revision) < 12 or len(revision) == revision.count('0')):
+                try:
+                    return self.revisions[int(revision)]
+                except IndexError:
+                    msg = "Revision %r does not exist for %s" % (revision, self)
+                    raise ChangesetDoesNotExistError(msg)
+
             # get by branch/tag name
             _ref_revision = self._parsed_refs.get(revision)
             if _ref_revision:  # and _ref_revision[1] in ['H', 'RH', 'T']:
                 return _ref_revision[0]
 
-            _tags_shas = self.tags.values()
+            if revision in self.revisions:
+                return revision
+
             # maybe it's a tag ? we don't have them in self.revisions
-            if revision in _tags_shas:
-                return _tags_shas[_tags_shas.index(revision)]
+            if revision in self.tags.values():
+                return revision
 
-            elif not SHA_PATTERN.match(revision) or revision not in self.revisions:
+            if SHA_PATTERN.match(revision):
                 msg = ("Revision %s does not exist for %s" % (revision, self))
                 raise ChangesetDoesNotExistError(msg)
 
-        # Ensure we return full id
-        if not SHA_PATTERN.match(str(revision)):
-            raise ChangesetDoesNotExistError("Given revision %s not recognized"
-                % revision)
-        return revision
+        raise ChangesetDoesNotExistError("Given revision %r not recognized" % revision)
 
     def get_ref_revision(self, ref_type, ref_name):
         """
-        Returns ``MercurialChangeset`` object representing repository's
+        Returns ``GitChangeset`` object representing repository's
         changeset at the given ``revision``.
         """
         return self._get_revision(ref_name)
--- a/kallithea/lib/vcs/backends/hg/repository.py	Thu Dec 26 22:39:10 2019 +0100
+++ b/kallithea/lib/vcs/backends/hg/repository.py	Thu Jan 02 02:04:57 2020 +0100
@@ -20,7 +20,7 @@
 from kallithea.lib.vcs.backends.base import BaseRepository, CollectionGenerator
 from kallithea.lib.vcs.exceptions import (
     BranchDoesNotExistError, ChangesetDoesNotExistError, EmptyRepositoryError, RepositoryError, TagAlreadyExistError, TagDoesNotExistError, VCSError)
-from kallithea.lib.vcs.utils import author_email, author_name, date_fromtimestamp, makedate, safe_str, safe_unicode
+from kallithea.lib.vcs.utils import author_email, author_name, date_fromtimestamp, makedate, safe_bytes, safe_str, safe_unicode
 from kallithea.lib.vcs.utils.hgcompat import (
     Abort, RepoError, RepoLookupError, clone, diffopts, get_contact, hex, hg_url, httpbasicauthhandler, httpdigestauthhandler, httppeer, localrepo, match_exact, nullid, patch, peer, scmutil, sshpeer, tag, ui)
 from kallithea.lib.vcs.utils.lazy import LazyProperty
@@ -405,19 +405,17 @@
 
     def _get_revision(self, revision):
         """
-        Gets an ID revision given as str. This will always return a full
-        40 char revision number
+        Given any revision identifier, returns a 40 char string with revision hash.
 
         :param revision: str or int or None
         """
-        if isinstance(revision, unicode):
-            revision = safe_str(revision)
-
         if self._empty:
             raise EmptyRepositoryError("There are no changesets yet")
 
         if revision in [-1, None]:
             revision = 'tip'
+        elif isinstance(revision, unicode):
+            revision = safe_bytes(revision)
 
         try:
             if isinstance(revision, int):