Last active
November 24, 2017 13:43
-
-
Save mbrehin/1a61066020c131e507520dea7663f3c7 to your computer and use it in GitHub Desktop.
Git `update` hook (server side)
This file contains hidden or 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
#!/usr/bin/ruby | |
# Enforce custom commit message format | |
def check_message_format(refname, oldrev, newrev) | |
message_format_regex = /\[ref: (\d+)\]/ | |
# You would probably have to adjust the way you're retrieving user identity. | |
# You can also load user identity from each analysed commit. | |
user = ENV['USER'] | |
# Initialize empty map to store errors | |
errors = [] | |
puts "Enforcing Policie on #{refname} (#{oldrev[0,6]}..#{newrev[0,6]})…" | |
missed_revs = `git rev-list #{oldrev}..#{newrev}`.split("\n") | |
missed_revs.each do |rev| | |
message = `git cat-file commit #{rev} | sed '1,/^$/d'` | |
# Check if current commit message matched expected format | |
if !message_format_regex.match(message) | |
# If user wasn't loaded, then try to load it from first commit | |
user = `git show -s --pretty=format:'%an' #{rev}` unless user | |
errors << rev[0,6] | |
end | |
end | |
# Print errors to STDOUT when something went wrong | |
if errors.any? | |
puts_red "[POLICY] 😡 Shame to #{user}!" | |
if errors.size > 1 | |
puts_red "[POLICY] 😱 Some messages are not formatted correctly (commits #{errors.join(', ')})" | |
else | |
puts_red "[POLICY] 😨 Commit #{errors.first} message is not well formatted" | |
end | |
exit 1 | |
end | |
end | |
# We don't want any user to push on master. | |
# This can be done using protecting branches on GitHub, GitLab and many other Git servers. | |
def prevent_master_update(refname) | |
if refname =~ /(refs\/)?(heads\/)?master/ | |
puts_red "You are not allowed to push to `master`" | |
exit 1 | |
end | |
end | |
# Print message in red | |
def puts_red(message) | |
puts "\e[31m#{message}\e[0m" | |
end | |
puts 'Running update hook…' | |
# Loads values from STDIN | |
refname, oldrev, newrev = *ARGV | |
prevent_master_update(refname) | |
check_message_format(refname, oldrev, newrev) | |
puts 'Everything went fine! 👏' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to install on GitLab CE?
Here is a summary of GitLab custom hooks behavior.
Create a
custom_hooks
subdirectory in your project path with the expected file:And you're done!
More about that example
That example has been inspired (not to say copy/pasted) from Git SCM.