Last active
March 13, 2024 08:45
-
-
Save nauar/826f85d25d692d9bc009312cb71577dd to your computer and use it in GitHub Desktop.
GIT pre-receive hook for checking file size and filename extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This script is a pre-receive hook allowing pushes whose every file: | |
# - is smaller than 20 M | |
# - and its extension is not one of the following: | |
# - dll | |
# - exe | |
# - war | |
# - ear | |
# - jar | |
# and whose directories are not named 'node_modules'. | |
GITCMD="git" | |
NULLSHA="0000000000000000000000000000000000000000" | |
EMPTYTREESHA=$($GITCMD hash-object -t tree /dev/null) # SHA1: "4b825dc642cb6eb9a060e54bf8d69288fbee4904" | |
MAXSIZE="20" | |
MAXBYTES=$(( $MAXSIZE * 1048576 )) | |
EXIT=0 | |
PRIVATELOGFILE="/tmp/git_private.log" | |
function private_log() { | |
moment=`date '+%d/%m/%Y %H:%M:%S'` | |
echo "[ $moment ] [ POLICY CHECK ] $1" >> $PRIVATELOGFILE | |
} | |
function log() { | |
moment=`date '+%d/%m/%Y %H:%M:%S'` | |
echo "[ $moment ] [ POLICY CHECK ] $1" | |
} | |
log "Starting validation..." | |
while read oldref newref refname; do | |
private_log "OLDREF: $oldref NEWREF: $newref REFNAME: $refname" | |
# Avoid removed branches | |
if [ "${newref}" = "${NULLSHA}" ]; then | |
continue | |
fi | |
# Set oldref properly if this is branch creation. | |
if [ "${oldref}" = "${NULLSHA}" ]; then | |
oldref=$EMPTYTREESHA | |
fi | |
# Ignore case | |
shopt -s nocaseglob | |
newFiles=$($GITCMD diff --stat --name-only --diff-filter=ACMRT ${oldref}..${newref}) | |
if [[ $? -ne 0 ]]; then | |
log "Error 101: Repository incosistency. Cancelling push..." | |
exit 1; | |
fi | |
old_IFS=$IFS | |
IFS=' | |
' | |
for filename in $newFiles; do | |
private_log "Filename: $filename" | |
filesize=$($GITCMD cat-file -s "${newref}:${filename}") 2> $PRIVATELOGFILE | |
if [[ -z $filesize ]]; then filesize=0; fi | |
filesize_mb=$(($filesize / 1048576)) | |
if [ "${filesize}" -gt "${MAXBYTES}" ]; then | |
log "File $filename is greater than $MAXSIZE MB. Its size is $filesize_mb MB." | |
exit 1 | |
fi | |
if [[ "$filename" =~ "node_modules" ]]; then | |
log "Folder 'node_modules' not allowed: $filename." | |
exit 1 | |
else | |
if [[ "$filename" =~ \.dll$ ]] || [[ "$filename" =~ \.exe$ ]] || [[ "$filename" =~ \.war$ ]] || [[ "$filename" =~ \.ear$ ]] || [[ "$filename" =~ \.jar$ ]]; then | |
extension="${filename##*.}" | |
log "Files with extension $extension not allowed. Please remove file $filename" | |
exit 1 | |
fi | |
fi | |
done | |
IFS=$old_IFS | |
done |
@nauar Thanks for your script.
@kdevineni Can you try this command?
git show --pretty="" --name-only <new_ref>
@nauar Thanks for your script. @kdevineni Can you try this command? git show --pretty="" --name-only <new_ref>
@srinivas974 "git show --pretty="" --name-only <new_ref>" only returns files from the commit reference specified .
Doesn't return all the changes made in the current branch
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@nauar
This script is great and does the job.....Thanks for the script....
I have a problem when a new branch is pushed , its scan entire changes , I want to scan only the changes in the current(new) branch excluding the master commits from which it was branched.
Here is my case.....
If I create new local branch from master , make some changes/commits and push.
I want to scan only the the commits/changes that are made in this new branch.
Locally I can get the changes using the command
"git cherry master | head -n 2 | tail -1" >> returns the commit of the master that this branch is created.
I want to replace the variable oldref in the script with the output of the cherry command. but the command doesn't return anything when executed from pre-receive hook
Any suggestions on how I can get the oldref with cherry command output?