Skip to content

Instantly share code, notes, and snippets.

@covard
Last active March 5, 2024 20:38
Show Gist options
  • Save covard/4341bd6f7a189b259795a72df355552f to your computer and use it in GitHub Desktop.
Save covard/4341bd6f7a189b259795a72df355552f to your computer and use it in GitHub Desktop.
Git pre commit hook to prevent language and committing to certain branches

Git Pre Commit Hook

This will prevent you from commiting any debug statements or swear words or commit to the wrong branch. After adding this file to the .git/hooks/pre-commit file then you will need to do the following:

Global / Repo Specific (2 options)


Option 1: Global

$ mkdir -p ~/.git-templates/hooks
$ touch ~/.git-templates/hooks/pre-commit
$ chmod +x ~/.git-templates/hooks/pre-commit
$ git config --global init.templatedir '~/.git-templates'

Run this if existing repo

$ git init

Option 2: Repo Specific

$ mv .git/hooks/pre-commit.sample .git/hooks/pre-commit
$ chmod +x .git/hooks/pre-commit

Pre-Commit File

#!/usr/bin/env ruby

# Validates that you don't commit forbidden keywords to the repo
# You can skip this checking with 'git commit --no-verify'

exit 0 if ARGV.include?('--no-verify')
# Update this list with your own forbidden keywords
KEYWORDS = %w(binding.pry debugger byebug)

def red(text)
  "\033[31m#{text}\033[0m"
end

def yellow(text)
  "\033[33m#{text}\033[0m"
end

def cyan(text)
  "\033[36m#{text}\033[0m"
end

def magenta(text)
  "\033[35m#{text}\033[0m"
end

def green(text)
  "\033[32m#{text}\033[0m"
end

# list all the files staged for commit
files_changed = %x(git diff --cached --name-only --).split
FORBIDDEN_BRANCHES = ["staging", "master", "dev", "qa", "development"]

def current_branch()
  branches = `git branch --no-color`.split(/\n/)
  current = branches.select{ |b| b =~ /\s*\*/ }.first
  current.gsub(/[\*\s]/, "")
end
branch = current_branch

if (FORBIDDEN_BRANCHES.include?(branch))
  puts
  puts " STOP THE PRESS!"
  puts " You are trying to commit on the *#{branch}* branch."
  puts " Surely you don't mean that?"
  puts
  puts " If you really do, force the commit by adding --no-verify to the command."
  puts

  exit 1
end

# search files for keywords
%x(git grep -q -E "#{KEYWORDS.join('|')}" #{files_changed.join(' ')})
if $?.exitstatus.zero?
  puts "# Check following lines:"
  files_changed.each do |file|
    KEYWORDS.each do |keyword|
      %x(git grep -q #{keyword} #{file})
      if $?.exitstatus.zero?
        line = %x(git grep -n #{keyword} #{file} | awk -F ":" '{print $2}').split.join(', ')
        puts "#\t#{red(file)}:#{line} contains #{yellow keyword}."
      end
    end
  end
  puts "Use 'git commit --no-verify' to skip this validation"
  exit 1
end

brakeman_results = `brakeman`
unless brakeman_results.empty?
  brakeman_results.split("\n").each_with_index do |result, indx|
    if result == "== Warning Types =="
      puts red(result)
    elsif result == 'No warnings found'
      puts green(result)
    else
      puts cyan(result)
    end
  end
  puts
end

puts 'starting pronto'
pronto_results = `pronto run -c origin/dev --staged --unstaged`


unless pronto_results.empty?
  puts '*' * 100
  puts "\t\t\t\t #{red('Pronto Results')}"
  puts
  pronto_results.split(/\n/).each do |result|
    split_result = result.split('W:')
    puts "#{yellow(split_result.first)} W: #{red(split_result.last)}"
  end
  puts
  puts '*' * 100
  # exit 1
end
@covard
Copy link
Author

covard commented Apr 2, 2021

included brakeman and pronto/rubocop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment