From cb81efa3002929bd5a9423c4da3cf748cedae266 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= <karel.koci@nic.cz>
Date: Wed, 15 Sep 2021 09:19:44 +0200
Subject: [PATCH] githooks/pre-push: allow fast-forward of hbk and hbl

The original check was that hbk and hbl can be pushed only with hbd and
hbl, in case of hbk, branches. It is what we mostly want but there are
cases when we do not update hbd or hbl and only hbk or hbl that are
valid as well. The example of such operation is merge of hbd to
hbl or merge of hbl to hbk, which is always fast-forward due to our
workflow.
This halts push only if hbk or hbl commit is not ancestor of hbd instead
of halting it always when hbd or hbl is not being updated.
---
 .githooks/pre-push | 40 +++++++++++++++++++++++++++-------------
 1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/.githooks/pre-push b/.githooks/pre-push
index db6701020..dc1761e87 100755
--- a/.githooks/pre-push
+++ b/.githooks/pre-push
@@ -77,23 +77,37 @@ while read -r local_ref local_sha1 remote_ref remote_sha1; do
 	esac
 done
 
-if [[ -n "$push_hbk" || -n "$push_hbl" ]]; then
-	if [[ -z "$push_hbd" ]]; then
-		if [[ -n "$push_hbk" ]]; then
+if [[ -n "$push_hbk" ]]; then
+	if [[ -z "$push_hbl" || -z "$push_hbd" ]]; then
+		# We allow fast forward. That means forward to any commit in hbd branch
+		# history. This includes hbl as well due to our workflow. Important
+		# thing here to note is that there should be no way that hbl is not
+		# ancestor of hbd and if we are trying to push that the second check for
+		# hbl caches that. That way we can safely check here only against hbd.
+		if ! git merge-base --is-ancestor "$push_hbk" "$(git rev-parse "$remote_name/hbd")"; then
 			echo "HBL and HBD branches have to be always updated with HBK branch." >&2
-		else
-			echo "HBD branch has to be always updated with HBL branch." >&2
+			echo "Push all of them at the same time with: git push origin hbk hbl hbd" >&2
+			exit 1
 		fi
-		echo "Push all of them at the same time with: git push origin hbk hbl hbd" >&2
+	fi
+	if [[ -z "$push_hbl" ]] && ! git merge-base --is-ancestor "$push_hbk" "$push_hbl"; then
+		echo "Tip commit of HBK is not merged to HBL branch." >&2
 		exit 1
 	fi
-	if [[ -n "$push_hbk" ]]; then
-		if ! git merge-base --is-ancestor "$push_hbk" "$push_hbl"; then
-			echo "Tip commit of HBK is not merged to HBL branch." >&2
-			exit 1
-		fi
-		if ! git merge-base --is-ancestor "$push_hbk" "$push_hbd"; then
-			echo "Tip commit of HBK is not merged to HBD branch." >&2
+	if [[ -n "$push_hbd" ]] && ! git merge-base --is-ancestor "$push_hbk" "$push_hbd"; then
+		echo "Tip commit of HBK is not merged to HBD branch." >&2
+		exit 1
+	fi
+fi
+if [[ -n "$push_hbl" ]]; then
+	if [[ -z "$push_hbd" ]]; then
+		if ! git merge-base --is-ancestor "$push_hbl" "$(git rev-parse "$remote_name/hbd")"; then
+			echo "HBL branch have to be always updated with HBD branch." >&2
+			if [[ -z "$push_hbk" ]]; then
+				echo "Push all of them at the same time with: git push origin hbl hbd" >&2
+			else
+				echo "Push all of them at the same time with: git push origin hbk hbl hbd" >&2
+			fi
 			exit 1
 		fi
 	else
-- 
GitLab