Reputation: 24316
In GHE (GitHub Enterprise), is it possible to share pre-commit hooks across all existing (and new) repositories? For example I want to deny JKS files being committed in the first place.
I understand these can be by-passed and simply want to make it harder to do the wrong thing.
Upvotes: 1
Views: 1912
Reputation: 76449
There is no way to do what you're requesting.
First, hooks aren't transferred as part of the repository. Because they can execute arbitrary code, Git doesn't provide a way to transfer them as part of the repository or automatically change them. You can include a set of hooks in a repository, but it's up to the user (or a part of your build system) to install them or not. Oftentimes users have custom hooks as part of the development process, and your build system would overwrite those.
Second, GitHub provides templating mechanisms, but doesn't provide a way to automatically install a file in all new repositories. Even if they did, it would be easy for a user pushing a new repository to simply push over it.
Third, to modify all existing repositories, you'd need to make a commit in each one. You could script this using the API, but it would require permissions for each repository, so you'd have to be an administrator to do that. And as mentioned before, you'd still have to have a way for each one to install hooks.
What you can do is use a pre-receive
hook on the server (enabled for all repositories) which rejects a push which contains these files. Since these files could have any name, you'd likely need to iterate over every blob in every commit that was pushed and see if it starts with the appropriate magic byte sequence. If you're happy with just looking for file patterns, you could do something like the following:
#!/bin/sh -e
while read old new ref
do
# Deleted ref.
if echo "$new" | grep -qsE '^0+$'
then
continue
fi
if echo "$old" | grep -qsE '^0+$'
then
# Newly created ref.
start=
else
# Updated ref.
start="$old.."
fi
git rev-list "$start$new" | (while read rev
do
output=$(git ls-tree -r --name-only "$rev" | grep '.jks$') || true
if [ -n "$output" ]
then
echo "Revision $rev from $ref contains forbidden files:"
echo "$output"
exit 1
fi
done)
done
Upvotes: 3