Skip to content

Instantly share code, notes, and snippets.

@freshtonic
Created March 8, 2012 06:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save freshtonic/1999083 to your computer and use it in GitHub Desktop.
Save freshtonic/1999083 to your computer and use it in GitHub Desktop.
Git hook to disallow non-fastforward updates (also disallows merges into feature branches in order to keep them cleanly rebaseable)
#!/usr/bin/env ruby
# This update hook enforces the following policies
# 1) release and master branches are fast-forward only
# 2) feature branches cannot contain merges
$refname = ARGV[0]
$oldrev = ARGV[1]
$newrev = ARGV[2]
puts "Enforcing Policies... \n(#{$refname}) (#{$oldrev[0,6]}) (#{$newrev[0,6]})"
# Enforce fast-forward-only branches.
NO_NON_FASTFORWARD_BLACKLIST = [/\brelease\b/, /\bmaster\b/]
# Disallow merges in feature branches.
NO_MERGE_BLACKLIST = [/\bfeature\b/]
def abort_on_non_fastforward(blacklist)
if blacklist.any?{ |pattern| $refname =~ pattern}
missed_refs = `git rev-list #{$newrev}..#{$oldrev}`
missed_ref_count = missed_refs.split("\n").size
if missed_ref_count > 0
puts "[POLICY] Cannot push a non fast-forward reference"
exit 1
end
end
end
def abort_on_merge(blacklist)
if blacklist.any?{|pattern| $refname =~ pattern}
feature_commits = `git rev-list #{$refname} ^master ^$(git merge-base master #{$refname})`.lines.map do |l|
l.strip
end
if feature_commits.any?{|sha| is_merge_commit?(sha.strip) }
STDERR.puts <<-MSG
[ POLICY ] There are merge commits on #{$refname}. Feature branches should not
contain merge commits. In order to keep a feature branch up to date with
master, rebase it. Once you have rebased your feature branch to remove the
merge commits, you will be able to push it here.
MSG
exit 1
end
end
end
def is_merge_commit?(sha)
`git cat-file -p #{sha}`.lines.select{|l| l =~ /^parent/}.count > 1
end
abort_on_non_fastforward(NO_NON_FASTFORWARD_BLACKLIST)
abort_on_merge(NO_MERGE_BLACKLIST)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment