Cache tags -> commits for performance
This optimization only really improves things when there are
1000s of tags.
@@ -203,9 +203,19 @@ class Backend(BaseVCS):
def tags(self):
versions = []
repo = git.Repo(self.working_dir)
+
+ # Build a cache of tag -> commit
+ # GitPython is not very optimized for reading large numbers of tags
+ ref_cache = {} # 'ref/tags/<tag>' -> hexsha
+ for hexsha, ref in git.TagReference._iter_packed_refs(repo):
+ ref_cache[ref] = hexsha
+
for tag in repo.tags:
+ if tag.path in ref_cache:
+ hexsha = ref_cache[tag.path]
+ else:
try:
- versions.append(VCSVersion(self, str(tag.commit), str(tag)))
+ hexsha = str(tag.commit)
except ValueError:
# ValueError: Cannot resolve commit as tag TAGNAME points to a
# blob object - use the `.object` property instead to access it
@@ -213,6 +223,8 @@ class Backend(BaseVCS):
# https://github.com/rtfd/readthedocs.org/issues/4440
log.warning('Git tag skipped: %s', tag, exc_info=True)
continue
+
+ versions.append(VCSVersion(self, hexsha, str(tag)))
return versions
@property
