From d55e6884adb82c98bf00ce13b7d77f65375b323c Mon Sep 17 00:00:00 2001 From: Alfred Melch Date: Thu, 26 Aug 2021 11:47:46 +0200 Subject: [PATCH] pre-receive: add prevent-foxtrot script --- pre-receive.d/prevent-foxtrot-merge.sh | 44 ++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 pre-receive.d/prevent-foxtrot-merge.sh diff --git a/pre-receive.d/prevent-foxtrot-merge.sh b/pre-receive.d/prevent-foxtrot-merge.sh new file mode 100644 index 0000000..cb907df --- /dev/null +++ b/pre-receive.d/prevent-foxtrot-merge.sh @@ -0,0 +1,44 @@ +#!/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/head/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