#!/bin/bash # Copyright (c) 2016 G. Sylvie Davies. http://bit-booster.com/ # Copyright (c) 2016 torek. http://stackoverflow.com/users/1256452/torek # Copyright (c) 2021 Alfred Melch. https://melch.pro # License: MIT license. https://opensource.org/licenses/MIT # From: https://blog.developer.atlassian.com/stop-foxtrots-now/ NULL_REV="0000000000000000000000000000000000000000" # refname (e.g. refs/heads/master) will be updated from oldrev (commit hash) to newrev (commit hash) while read oldrev newrev refname do if [ $oldrev = $NULL_REV ]; then # pushing a new branch exit 0 fi if [ $newrev = $NULL_REV ]; then # deleting a branch exit 0 fi if [ "$refname" = "refs/heads/master" ] || [ "$refname" = "refs/heads/main" ]; then # Find the first parent of the commit where oldrev is a parent # git log: list commits from newrev to oldrev # %H: commit hash # %P: parent hashes (list of parents) # grep: filter for oldrev # Should appear once as a parent # awk: print the second word # The second word is the first parent. Third word would be second parent, ... MATCH=`git log --first-parent --pretty='%H %P' $oldrev..$newrev | grep $oldrev | awk '{ print $2 }'` # First parent should be the oldrev if [ "$oldrev" = "$MATCH" ]; then exit 0 else echo >&2 "*** Push rejected! Foxtrot merge blocked! ***" echo "See: https://blog.developer.atlassian.com/stop-foxtrots-now/" exit 1 fi fi done