Optimize CheckForCommitObjects by batching git ls-tree operations

Significantly reduces the execution time of presubmit checks by
optimizing CheckForCommitObjects.

For CLs with fewer than 1000 affected files, run `git ls-tree` only on
specific files instead of scanning the full tree. This yields a ~70x
speedup (~0.97s -> ~0.01s) for typical CLs.

Change-Id: Ia8b89dbb14a5129ba79944282deba52a3558bdf2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/7234371
Commit-Queue: Josiah Kiehl <kiehl@google.com>
Reviewed-by: Yiwei Zhang <yiwzhang@google.com>
This commit is contained in:
Josiah Kiehl
2025-12-09 15:07:14 -08:00
committed by LUCI CQ
parent 0861b0e55c
commit 7c09ebfd12
3 changed files with 164 additions and 11 deletions

View File

@@ -757,9 +757,6 @@ class CheckAyeAyeTest(unittest.TestCase):
self.assertEqual(results[0].type, 'error')
self.assertIn("Failed to run.", results[0].message)
if __name__ == '__main__':
unittest.main()
class CheckForCommitObjectsTest(unittest.TestCase):
@@ -772,6 +769,7 @@ class CheckForCommitObjectsTest(unittest.TestCase):
self.patcher = mock.patch('presubmit_canned_checks._ParseDeps')
self.mock_parse_deps = self.patcher.start()
self.mock_parse_deps.return_value = {'git_dependencies': 'DEPS'}
self.input_api.change.RepositoryRoot = lambda: ''
def tearDown(self):
self.patcher.stop()
@@ -865,3 +863,53 @@ class CheckForCommitObjectsTest(unittest.TestCase):
results = presubmit_canned_checks.CheckForCommitObjects(
self.input_api, self.output_api)
self.assertEqual(0, len(results))
def testRunFromSubdir_SmallFiles_NoSubmodules(self):
self.input_api.presubmit_local_path = os.path.join(ROOT_DIR, 'subdir')
self.input_api.change.RepositoryRoot = lambda: ROOT_DIR
self.input_api.files = [MockAffectedFile('foo.txt', 'content')]
self.input_api.subprocess.check_output.return_value = b''
results = presubmit_canned_checks.CheckForCommitObjects(
self.input_api, self.output_api)
self.assertEqual(0, len(results))
def testRunFromSubdir_SmallFiles_WithSubmodules(self):
self.input_api.presubmit_local_path = os.path.join(ROOT_DIR, 'subdir')
self.input_api.change.RepositoryRoot = lambda: ROOT_DIR
self.input_api.files = [MockAffectedFile('foo.txt', 'content')]
self.input_api.subprocess.check_output.return_value = b'160000 commit 1234\tsubmodule\0'
results = presubmit_canned_checks.CheckForCommitObjects(
self.input_api, self.output_api)
self.assertEqual(1, len(results))
self.assertIn('submodule', results[0].items)
def testRunFromSubdir_LargeFiles_NoSubmodules(self):
self.input_api.presubmit_local_path = os.path.join(ROOT_DIR, 'subdir')
self.input_api.change.RepositoryRoot = lambda: ROOT_DIR
self.input_api.files = [
MockAffectedFile(f'f{i}', '') for i in range(1001)
]
self.input_api.subprocess.check_output.return_value = b''
results = presubmit_canned_checks.CheckForCommitObjects(
self.input_api, self.output_api)
self.assertEqual(0, len(results))
def testRunFromSubdir_LargeFiles_WithSubmodules(self):
self.input_api.presubmit_local_path = os.path.join(ROOT_DIR, 'subdir')
self.input_api.change.RepositoryRoot = lambda: ROOT_DIR
self.input_api.files = [
MockAffectedFile(f'f{i}', '') for i in range(1001)
]
self.input_api.subprocess.check_output.return_value = b'160000 commit 1234\tsubmodule\0'
results = presubmit_canned_checks.CheckForCommitObjects(
self.input_api, self.output_api)
self.assertEqual(1, len(results))
self.assertIn('submodule', results[0].items)
if __name__ == '__main__':
unittest.main()