Hello,
We used to have a standard git repo, which had plenty of binary files. We used a pre-receive hook to parse the headers of the files and see if they follow our standard. Now we want to move to LFS for these files and accordingly reworked the pre-receive hook to cancel the push if we spot an issue with the files being pushed. This works in the following way:
- An user pushes a commit with binary files
- LFS pushes first the binary objects
- GIT pushes the rest of the source code
- pre-receive hook starts and checks the binary files
If on step 4 we want to cancel the push, this is okay. However the binary LFS objects stay in the LFS store and use space. I ran manually:
“remove_unreferenced_lfs_objects_worker” background job, but the files are still there.
Is this an expected behaviour? What would be appropriate cleanup steps?
Regards
In order to reproduce it, you need to create a git hook under “/var/opt/gitlab/git-data/repositories/[@hashed/]yourrepo.git/custom_hooks/pre-receive” (must be executable):
#!/bin/bash
# Pre-receive hook that will block any new commits that contain dds files with invalid format
errorLevel=0
zero_commit="0000000000000000000000000000000000000000"
# Do not traverse over commits that are already in the repository
# (e.g. in a different branch)
# This prevents funny errors if pre-receive hooks got enabled after some
# commits got already in and then somebody tries to create a new branch
# If this is unwanted behavior, just set the variable to empty
excludeExisting="--not --all"
while read oldrev newrev refname; do
echo $refname $oldrev $newrev
# branch or tag get deleted
if [ "$newrev" = "$zero_commit" ]; then
continue
fi
# Check for new branch or tag
if [ "$oldrev" = "$zero_commit" ]; then
span=`git rev-list $newrev $excludeExisting`
else
span=`git rev-list $oldrev..$newrev $excludeExisting`
fi
for COMMIT in $span;
do
while IFS= read -r FILE; do
case "$FILE" in
*.bin )
echo "ERROR: You are not allowed to push \"bin\" files -> \"$FILE\""
echo "File is located under your lfs object store folder in subfolder:"
echo "$(git show $newrev:"$FILE" | grep 'oid sha' | awk -F':' '{print $2}' | sed 's/\([a-f0-9][a-f0-9]\)\([a-f0-9][a-f0-9]\)\(.*\)/\1\/\2\/\3/g')"
errorLevel=1
;;
esac
done <<< "$(git log -1 --name-only --pretty=format:'' $COMMIT)"
done
done
exit $errorLevel
enable LFS in a newly cloned test repo:
git lfs install
git lfs track '*.bin'
git add .gitattributes
dd if=/dev/urandom bs=1M count=1 | gzip -c > ./file.bin
git add file.bin
git commit -m "Add files"
git push origin master