Git Hooks: Merge hook scripts and tests from blender-devops
This commit is contained in:
94
git-hooks/deny-binary
Executable file
94
git-hooks/deny-binary
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash -eu
|
||||
#
|
||||
# Reject commits with binary files, which should have used LFS instead. Allow
|
||||
# overriding when "override restrictions" is in the commit message.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-receive" or place it in
|
||||
# a "pre-receive.d" folder.
|
||||
|
||||
# Use 'strict mode': http://redsymbol.net/articles/unofficial-bash-strict-mode/
|
||||
set -o pipefail
|
||||
|
||||
nullsha="0000000000000000000000000000000000000000"
|
||||
status=0
|
||||
# This is the message to include in your commit to override.
|
||||
commit_override_msg="override restrictions"
|
||||
|
||||
handle_pipefails() {
|
||||
# ignore exit code 141 from simple command pipes
|
||||
# - use with: cmd1 | cmd2 || handle_pipefails $?
|
||||
(( $1 == 141 )) && return 0
|
||||
return $1
|
||||
}
|
||||
|
||||
# Read stdin for ref information.
|
||||
while read oldrev newrev refname; do
|
||||
# Skip branch deletions.
|
||||
if [ "$newrev" = "$nullsha" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Set oldrev to HEAD if this is branch creation.
|
||||
if [ "$oldrev" = "$nullsha" ]; then
|
||||
oldrev="HEAD"
|
||||
fi
|
||||
|
||||
# Check for branches and tags, but not pull requests in refs/pull. Otherwise Gitea
|
||||
# fails to create a pull request without explaining why.
|
||||
if [[ "$refname" == refs/heads/* ]]; then
|
||||
:
|
||||
elif [[ "$refname" == refs/tags/* ]]; then
|
||||
:
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Loop over each commit.
|
||||
for commit in $(git rev-list --objects ${oldrev}..${newrev} |
|
||||
git cat-file --batch-check='%(objectname) %(objecttype) %(objectsize) %(rest)' | grep commit | awk '{print $1}'); do
|
||||
|
||||
# Get list of potentially binary files in this commit
|
||||
mapfile -t binary_files < <(git log --diff-filter=d --pretty=format:%H -M100% --numstat ${commit}^! | grep -e "- - \w" | awk '{print $3}')
|
||||
|
||||
if [ ${#binary_files[@]} -eq 0 ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check for override message
|
||||
override=0
|
||||
if git log --pretty=format:%B ${commit}^! | grep -qi "${commit_override_msg}"; then
|
||||
override=1
|
||||
fi
|
||||
|
||||
rejected_files=()
|
||||
for file in "${binary_files[@]}"; do
|
||||
# Check if it's an LFS pointer
|
||||
# Use handle_pipefails as we may run into SIGPIPE error code
|
||||
if git show "${commit}:${file}" | git lfs pointer --check --stdin || handle_pipefails $?; then
|
||||
continue
|
||||
fi
|
||||
rejected_files+=("$file")
|
||||
done
|
||||
|
||||
if [ ${#rejected_files[@]} -gt 0 ]; then
|
||||
if [ "$override" -gt 0 ]; then
|
||||
echo "Your push contains binary files but was accepted because of override commit message:"
|
||||
else
|
||||
status=1
|
||||
echo "Your push was rejected because it contains binary files not tracked by Git LFS:"
|
||||
fi
|
||||
echo "Commit: $commit"
|
||||
for file in "${rejected_files[@]}"; do
|
||||
echo "File: $file"
|
||||
done
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
if [ "$status" -ne "0" ]; then
|
||||
echo
|
||||
echo "You must make sure that the binary files are tracked with Git LFS or seek help from the repo administrators."
|
||||
echo "(Perhaps you did not setup Git LFS with 'git lfs install'?)"
|
||||
echo
|
||||
fi
|
||||
exit $status
|
||||
Reference in New Issue
Block a user