From 2d2d1db041cb57bd2134cdbfa7b1ddb4ba52bac2 Mon Sep 17 00:00:00 2001 From: Bart van der Braak Date: Wed, 14 Jan 2026 15:06:11 +0100 Subject: [PATCH] Git Hooks: Fix and test binary file moves (#19) Co-authored-by: Sebastian Parborg Reviewed-on: https://projects.blender.org/infrastructure/gitea-custom/pulls/19 --- git-hooks/deny-binary | 13 +++++- .../51_move_legacy_file_with_binary.sh | 45 +++++++++++++++++++ git-hooks/test/run_deny_binary_tests.sh | 1 + 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100755 git-hooks/test/deny_binary/51_move_legacy_file_with_binary.sh diff --git a/git-hooks/deny-binary b/git-hooks/deny-binary index b164928..9f1cb22 100755 --- a/git-hooks/deny-binary +++ b/git-hooks/deny-binary @@ -48,8 +48,11 @@ while read oldrev newrev refname; do 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}') - + mapfile -t binary_files < <( + git log --diff-filter=d --pretty=format:%H -M100% --numstat ${commit}^! | + awk -F'\t' '$1=="-" && $2=="-" {print $3}' + ) + if [ ${#binary_files[@]} -eq 0 ]; then continue fi @@ -62,6 +65,12 @@ while read oldrev newrev refname; do rejected_files=() for file in "${binary_files[@]}"; do + if [[ $file == *" => "* ]]; then + # If the name contains " => " then this probably means the file was moved. + # If it was just moved, then it must still be a binary file. + rejected_files+=("$file") + continue + fi # 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 diff --git a/git-hooks/test/deny_binary/51_move_legacy_file_with_binary.sh b/git-hooks/test/deny_binary/51_move_legacy_file_with_binary.sh new file mode 100755 index 0000000..4bb2b17 --- /dev/null +++ b/git-hooks/test/deny_binary/51_move_legacy_file_with_binary.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +# Test: Show rejected files correctly when moving binary files +# +# This test is expected to fail since the binary file is supposed +# to be covered by Git LFS. This test verifies the reject message +# for correctly parsing and displaying the file move. + +set -e + +SCRIPT=$(readlink -f "$0") +SCRIPT_PATH=$(dirname "$SCRIPT") + +. ${SCRIPT_PATH}/functions + +setup_temp_git_identity + +ORIGIN_REPO_DIR=`setup_bare_origin_repository` +WORK_GIT_DIR=`clone_repository "${ORIGIN_REPO_DIR}"` + +dd if=/dev/zero of="${WORK_GIT_DIR}/data.bin" bs=1 count=32k +git -C "${WORK_GIT_DIR}" add data.bin +git -C "${WORK_GIT_DIR}" commit --message "Initial commit" +if ! git -C "${WORK_GIT_DIR}" push; then + exit 1 +fi + +install_hook "${ORIGIN_REPO_DIR}" "${SCRIPT_PATH}/../../deny-binary" "pre-receive" + +mkdir -p "${WORK_GIT_DIR}/bindata" +git -C "${WORK_GIT_DIR}" mv data.bin bindata/data.bin +git -C "${WORK_GIT_DIR}" commit --message "Move binary file" + +set +e +PUSH_OUTPUT=$(git -C "${WORK_GIT_DIR}" push 2>&1) +PUSH_STATUS=$? +set -e + +if [ "${PUSH_STATUS}" -eq 0 ] || echo "${PUSH_OUTPUT}" | grep -q "fatal:"; then + exit 1 +fi + +echo +echo "Test passed!" +exit 0 diff --git a/git-hooks/test/run_deny_binary_tests.sh b/git-hooks/test/run_deny_binary_tests.sh index 8120db3..3b118c3 100755 --- a/git-hooks/test/run_deny_binary_tests.sh +++ b/git-hooks/test/run_deny_binary_tests.sh @@ -8,3 +8,4 @@ SCRIPT_PATH=$(dirname "$SCRIPT") . "${SCRIPT_PATH}/common/functions" run_tests_in_directory "${SCRIPT_PATH}/deny_binary" +rm -rf "${SCRIPT_PATH}/deny_binary/tmp" \ No newline at end of file