mirror of
https://chromium.googlesource.com/chromium/tools/depot_tools.git
synced 2026-01-11 18:51:29 +00:00
Add gclient installhooks to add pre-commit hook
With submodules, users can accidentally stage and commit gitlink changes. Add a new gclient command to install a pre-commit hook to automatically drop gitlink changes that don't correspond to a DEPS change. Dropping gitlinks can be bypassed by setting SKIP_GITLINK_PRECOMMIT=1. Bug: 1481266 Change-Id: Idd8b273e7d8e37d52627964e8ed6004d068b6b7a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/4863221 Reviewed-by: Joanna Wang <jojwang@chromium.org> Commit-Queue: Gavin Mak <gavinmak@google.com> Reviewed-by: Josip Sokcevic <sokcevic@chromium.org>
This commit is contained in:
71
hooks/pre-commit.py
Normal file
71
hooks/pre-commit.py
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2023 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
"""A git pre-commit hook to drop staged gitlink changes.
|
||||
|
||||
To bypass this hook, set SKIP_GITLINK_PRECOMMIT=1.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
sys.path.insert(0, ROOT_DIR)
|
||||
|
||||
import git_common
|
||||
from gclient_eval import SYNC
|
||||
|
||||
SKIP_VAR = 'SKIP_GITLINK_PRECOMMIT'
|
||||
|
||||
|
||||
def main():
|
||||
if os.getenv(SKIP_VAR) == '1':
|
||||
print(f'{SKIP_VAR} is set. Committing gitlinks, if any.')
|
||||
exit(0)
|
||||
|
||||
has_deps_diff = False
|
||||
staged_gitlinks = []
|
||||
diff = git_common.run('diff-index', '--cached', 'HEAD')
|
||||
for line in diff.splitlines():
|
||||
path = line.split()[-1]
|
||||
if path == 'DEPS':
|
||||
has_deps_diff = True
|
||||
continue
|
||||
if line.startswith(':160000 160000'):
|
||||
staged_gitlinks.append(path)
|
||||
|
||||
if not staged_gitlinks or has_deps_diff:
|
||||
exit(0)
|
||||
|
||||
# There are staged gitlinks and DEPS wasn't changed. Get git_dependencies
|
||||
# migration state in DEPS.
|
||||
state = None
|
||||
try:
|
||||
with open('DEPS', 'r') as f:
|
||||
for l in f.readlines():
|
||||
if l.startswith('git_dependencies'):
|
||||
state = l.split()[-1].strip(' "\'')
|
||||
break
|
||||
except OSError:
|
||||
# Don't abort the commit if DEPS wasn't found.
|
||||
exit(0)
|
||||
|
||||
if state != SYNC:
|
||||
# DEPS only has to be in sync with gitlinks when state is SYNC.
|
||||
exit(0)
|
||||
|
||||
print(f'Found no change to DEPS, unstaging {len(staged_gitlinks)} '
|
||||
f'staged gitlink(s) found in diff:\n{diff}')
|
||||
git_common.run('restore', '--staged', '--', *staged_gitlinks)
|
||||
|
||||
disable_msg = f'To disable this hook, set {SKIP_VAR}=1'
|
||||
if len(staged_gitlinks) == len(diff.splitlines()):
|
||||
print('Found no changes after unstaging gitlinks, aborting commit.')
|
||||
print(disable_msg)
|
||||
exit(1)
|
||||
print(disable_msg)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user