mirror of
https://chromium.googlesource.com/chromium/tools/depot_tools.git
synced 2026-01-11 18:51:29 +00:00
[scm] Cache ResolveCommit call
The cache won't be used if ResolveCommit throws an exception or when non-sha1 is used. This optimization saves about 7% of overall gclient sync on chromium/src. R=gavinmak@google.com Change-Id: I9c36d937dc7b8553818888e2e9c4eecd029a978c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/5147496 Reviewed-by: Gavin Mak <gavinmak@google.com> Commit-Queue: Josip Sokcevic <sokcevic@chromium.org>
This commit is contained in:
26
scm.py
26
scm.py
@@ -96,6 +96,7 @@ def only_int(val):
|
||||
|
||||
class GIT(object):
|
||||
current_version = None
|
||||
rev_parse_cache = {}
|
||||
|
||||
@staticmethod
|
||||
def ApplyEnvVars(kwargs):
|
||||
@@ -461,20 +462,27 @@ class GIT(object):
|
||||
|
||||
@staticmethod
|
||||
def ResolveCommit(cwd, rev):
|
||||
cache_key = None
|
||||
# We do this instead of rev-parse --verify rev^{commit}, since on
|
||||
# Windows git can be either an executable or batch script, each of which
|
||||
# requires escaping the caret (^) a different way.
|
||||
if gclient_utils.IsFullGitSha(rev):
|
||||
# Only cache full SHAs
|
||||
cache_key = hash(cwd + rev)
|
||||
if val := GIT.rev_parse_cache.get(cache_key):
|
||||
return val
|
||||
|
||||
# git-rev parse --verify FULL_GIT_SHA always succeeds, even if we
|
||||
# don't have FULL_GIT_SHA locally. Removing the last character
|
||||
# forces git to check if FULL_GIT_SHA refers to an object in the
|
||||
# local database.
|
||||
rev = rev[:-1]
|
||||
try:
|
||||
return GIT.Capture(['rev-parse', '--quiet', '--verify', rev],
|
||||
cwd=cwd)
|
||||
except subprocess2.CalledProcessError:
|
||||
return None
|
||||
res = GIT.Capture(['rev-parse', '--quiet', '--verify', rev], cwd=cwd)
|
||||
if cache_key:
|
||||
# We don't expect concurrent execution, so we don't lock anything.
|
||||
GIT.rev_parse_cache[cache_key] = res
|
||||
|
||||
return res
|
||||
|
||||
@staticmethod
|
||||
def IsValidRevision(cwd, rev, sha_only=False):
|
||||
@@ -482,9 +490,11 @@ class GIT(object):
|
||||
|
||||
sha_only: Fail unless rev is a sha hash.
|
||||
"""
|
||||
sha = GIT.ResolveCommit(cwd, rev)
|
||||
if sha is None:
|
||||
return False
|
||||
try:
|
||||
sha = GIT.ResolveCommit(cwd, rev)
|
||||
except subprocess2.CalledProcessError:
|
||||
return None
|
||||
|
||||
if sha_only:
|
||||
return sha == rev.lower()
|
||||
return True
|
||||
|
||||
@@ -143,8 +143,10 @@ class RealGitTest(fake_repos.FakeReposTestBase):
|
||||
self.skipTest('git fake repos not available')
|
||||
|
||||
def testResolveCommit(self):
|
||||
self.assertIsNone(scm.GIT.ResolveCommit(self.cwd, 'zebra'))
|
||||
self.assertIsNone(scm.GIT.ResolveCommit(self.cwd, 'r123456'))
|
||||
with self.assertRaises(Exception):
|
||||
scm.GIT.ResolveCommit(self.cwd, 'zebra')
|
||||
with self.assertRaises(Exception):
|
||||
scm.GIT.ResolveCommit(self.cwd, 'r123456')
|
||||
first_rev = self.githash('repo_1', 1)
|
||||
self.assertEqual(first_rev, scm.GIT.ResolveCommit(self.cwd, first_rev))
|
||||
self.assertEqual(self.githash('repo_1', 2),
|
||||
|
||||
Reference in New Issue
Block a user