From f0357e839447600333baada6ad2626eed9e77ded Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Fri, 13 Mar 2026 18:23:19 +0100 Subject: [PATCH] Hooks: Update deny_binary to correctly handle pushes to new repos Before, the hook would allow pushing binary files to newly created empty repos. Now we handle and test this in our test suite. --- hooks/deny_binary | 14 ++++-- .../20_initial_binary_file_test.sh | 6 +-- .../23_force_add_binary_file_test.sh | 29 +++++++++++ .../40_add_binary_file_and_convert_test.sh | 2 - .../52_branch_legacy_file_iteration_test.sh | 50 +++++++++++++++++++ 5 files changed, 92 insertions(+), 9 deletions(-) create mode 100755 hooks/test/deny_binary/23_force_add_binary_file_test.sh create mode 100755 hooks/test/deny_binary/52_branch_legacy_file_iteration_test.sh diff --git a/hooks/deny_binary b/hooks/deny_binary index 9f1cb22..48e5ace 100755 --- a/hooks/deny_binary +++ b/hooks/deny_binary @@ -28,9 +28,17 @@ while read oldrev newrev refname; do continue fi - # Set oldrev to HEAD if this is branch creation. if [ "$oldrev" = "$nullsha" ]; then - oldrev="HEAD" + if [ $(git rev-parse HEAD) = "HEAD" ]; then + # Iterate over all commits if there is no HEAD. + # This happens when the repo has just been initalized + rev_range=${newrev} + else + # Don't iterate over any commits already in the default branch of the repo + rev_range=HEAD..${newrev} + fi + else + rev_range=${oldrev}..${newrev} fi # Check for branches and tags, but not pull requests in refs/pull. Otherwise Gitea @@ -44,7 +52,7 @@ while read oldrev newrev refname; do fi # Loop over each commit. - for commit in $(git rev-list --objects ${oldrev}..${newrev} | + for commit in $(git rev-list --objects ${rev_range} | git cat-file --batch-check='%(objectname) %(objecttype) %(objectsize) %(rest)' | grep commit | awk '{print $1}'); do # Get list of potentially binary files in this commit diff --git a/hooks/test/deny_binary/20_initial_binary_file_test.sh b/hooks/test/deny_binary/20_initial_binary_file_test.sh index f6ece8f..f2be87d 100755 --- a/hooks/test/deny_binary/20_initial_binary_file_test.sh +++ b/hooks/test/deny_binary/20_initial_binary_file_test.sh @@ -2,9 +2,7 @@ # Test: Add binary file to an empty repository and try to push. # -# It is expected to pass as part of a logic which allows to branch off -# existing branches where it is possible to have binary files that were -# added prior to migration to Git LFS. +# It should fail as we should block binary files from be pushed. set -e @@ -23,7 +21,7 @@ install_hook "${ORIGIN_REPO_DIR}" "${SCRIPT_PATH}/../../deny_binary" "pre-receiv 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 +if git -C "${WORK_GIT_DIR}" push; then exit 1 fi diff --git a/hooks/test/deny_binary/23_force_add_binary_file_test.sh b/hooks/test/deny_binary/23_force_add_binary_file_test.sh new file mode 100755 index 0000000..54e667d --- /dev/null +++ b/hooks/test/deny_binary/23_force_add_binary_file_test.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +# Test: Add binary file to an empty repository and push it by bypassing the hook. +# + +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}"` + +install_hook "${ORIGIN_REPO_DIR}" "${SCRIPT_PATH}/../../deny_binary" "pre-receive" + +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, override restrictions" +if ! git -C "${WORK_GIT_DIR}" push; then + exit 1 +fi + +echo +echo "Test passed!" +exit 0 diff --git a/hooks/test/deny_binary/40_add_binary_file_and_convert_test.sh b/hooks/test/deny_binary/40_add_binary_file_and_convert_test.sh index 514498b..d2916d1 100755 --- a/hooks/test/deny_binary/40_add_binary_file_and_convert_test.sh +++ b/hooks/test/deny_binary/40_add_binary_file_and_convert_test.sh @@ -36,8 +36,6 @@ git -C "${WORK_GIT_DIR}" lfs track "*.bin" git -C "${WORK_GIT_DIR}" add .gitattributes git -C "${WORK_GIT_DIR}" commit --message "Track .bin files with Git LFS" -git -C "${WORK_GIT_DIR}" lfs migrate import --no-rewrite --yes data.bin - if git -C "${WORK_GIT_DIR}" push; then exit 1 fi diff --git a/hooks/test/deny_binary/52_branch_legacy_file_iteration_test.sh b/hooks/test/deny_binary/52_branch_legacy_file_iteration_test.sh new file mode 100755 index 0000000..3a98aa5 --- /dev/null +++ b/hooks/test/deny_binary/52_branch_legacy_file_iteration_test.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +# Test: Ensure that we don't iterate over legacy files when branching +# +# Ensure that we don't iterate over legacy commits when pushing new branches + +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" + +git -C "${WORK_GIT_DIR}" lfs install +git -C "${WORK_GIT_DIR}" lfs track "*.bin" +git -C "${WORK_GIT_DIR}" add .gitattributes +touch "${WORK_GIT_DIR}/data.bin" +git -C "${WORK_GIT_DIR}" commit --message "Track .bin files with Git LFS" + +if ! git -C "${WORK_GIT_DIR}" push; then + exit 1 +fi + +git -C "${WORK_GIT_DIR}" branch new_branch +git -C "${WORK_GIT_DIR}" switch new_branch +touch "${WORK_GIT_DIR}/text_file" +git -C "${WORK_GIT_DIR}" add text_file +git -C "${WORK_GIT_DIR}" commit --message "Add regular text file" + +if ! git -C "${WORK_GIT_DIR}" push --set-upstream origin new_branch; then + exit 1 +fi + +echo +echo "Test passed!" +exit 0