xref: /aosp_15_r20/external/flashrom/util/git-hooks/pre-push (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
1*0d6140beSAndroid Build Coastguard Worker#!/bin/sh
2*0d6140beSAndroid Build Coastguard Worker
3*0d6140beSAndroid Build Coastguard Worker# A hook script to verify what is about to be pushed.  Called by "git
4*0d6140beSAndroid Build Coastguard Worker# push" after it has checked the remote status, but before anything has been
5*0d6140beSAndroid Build Coastguard Worker# pushed.  If this script exits with a non-zero status nothing will be pushed.
6*0d6140beSAndroid Build Coastguard Worker#
7*0d6140beSAndroid Build Coastguard Worker# This hook is called with the following parameters:
8*0d6140beSAndroid Build Coastguard Worker#
9*0d6140beSAndroid Build Coastguard Worker# $1 -- Name of the remote to which the push is being done
10*0d6140beSAndroid Build Coastguard Worker# $2 -- URL to which the push is being done
11*0d6140beSAndroid Build Coastguard Worker#
12*0d6140beSAndroid Build Coastguard Worker# If pushing without using a named remote those arguments will be equal.
13*0d6140beSAndroid Build Coastguard Worker#
14*0d6140beSAndroid Build Coastguard Worker# Information about the commits which are being pushed is supplied as lines to
15*0d6140beSAndroid Build Coastguard Worker# the standard input in the form:
16*0d6140beSAndroid Build Coastguard Worker#
17*0d6140beSAndroid Build Coastguard Worker#   <local ref> <local sha1> <remote ref> <remote sha1>
18*0d6140beSAndroid Build Coastguard Worker
19*0d6140beSAndroid Build Coastguard Workerremote="$1"
20*0d6140beSAndroid Build Coastguard Workerurl="$2"
21*0d6140beSAndroid Build Coastguard Worker
22*0d6140beSAndroid Build Coastguard Workerzero=0000000000000000000000000000000000000000
23*0d6140beSAndroid Build Coastguard Worker
24*0d6140beSAndroid Build Coastguard Workerupstream_pattern="github\.com.flashrom/flashrom(\.git)?|flashrom\.org.git/flashrom(\.git)?"
25*0d6140beSAndroid Build Coastguard Worker
26*0d6140beSAndroid Build Coastguard Worker# Only care about the upstream repositories
27*0d6140beSAndroid Build Coastguard Workerif echo "$url" | grep -q -v -E "$upstream_pattern" ; then
28*0d6140beSAndroid Build Coastguard Worker	exit 0
29*0d6140beSAndroid Build Coastguard Workerfi
30*0d6140beSAndroid Build Coastguard Worker
31*0d6140beSAndroid Build Coastguard Workerwhile read local_ref local_sha remote_ref remote_sha ; do
32*0d6140beSAndroid Build Coastguard Worker
33*0d6140beSAndroid Build Coastguard Worker	# Only allow the stable and staging branches as well as versioned stable branches (e.g., 0.0.x).
34*0d6140beSAndroid Build Coastguard Worker	# The matching expression's RE is always anchored to the first character (^ is undefined).
35*0d6140beSAndroid Build Coastguard Worker	# The outer parentheses are needed to print out the whole matched string.
36*0d6140beSAndroid Build Coastguard Worker	version=$(expr ${remote_ref#*refs/heads/} : '\(\([0-9]\+\.\)\{2,\}x\)$')
37*0d6140beSAndroid Build Coastguard Worker	if [ "$remote_ref" != "refs/heads/staging" ] && \
38*0d6140beSAndroid Build Coastguard Worker	   [ "$remote_ref" != "refs/heads/stable" ] && \
39*0d6140beSAndroid Build Coastguard Worker	   [ -z "$version" ]; then
40*0d6140beSAndroid Build Coastguard Worker		echo "Feature branches not allowed ($remote_ref)." >&2
41*0d6140beSAndroid Build Coastguard Worker		exit 1
42*0d6140beSAndroid Build Coastguard Worker	fi
43*0d6140beSAndroid Build Coastguard Worker
44*0d6140beSAndroid Build Coastguard Worker	if [ "$local_sha" = $zero ]; then
45*0d6140beSAndroid Build Coastguard Worker		echo "Deletion of branches is prohibited." >&2
46*0d6140beSAndroid Build Coastguard Worker		exit 1
47*0d6140beSAndroid Build Coastguard Worker	fi
48*0d6140beSAndroid Build Coastguard Worker
49*0d6140beSAndroid Build Coastguard Worker	# Check for Signed-off-by and Acked-by
50*0d6140beSAndroid Build Coastguard Worker	commit=$(git rev-list -n 1 --all-match --invert-grep -E \
51*0d6140beSAndroid Build Coastguard Worker		--grep '^Signed-off-by: .+ <.+@.+\..+>$' \
52*0d6140beSAndroid Build Coastguard Worker		--grep '^Acked-by: .+ <.+@.+\..+>$' \
53*0d6140beSAndroid Build Coastguard Worker		"$remote_sha..$local_sha")
54*0d6140beSAndroid Build Coastguard Worker	if [ -n "$commit" ]; then
55*0d6140beSAndroid Build Coastguard Worker		echo "Commit $local_sha in $local_ref is missing either \"Signed-off-by\"" \
56*0d6140beSAndroid Build Coastguard Worker			" or \"Acked-by\" lines, not pushing." >&2
57*0d6140beSAndroid Build Coastguard Worker		exit 1
58*0d6140beSAndroid Build Coastguard Worker	fi
59*0d6140beSAndroid Build Coastguard Worker
60*0d6140beSAndroid Build Coastguard Worker	# Make _really_ sure we do not rewrite history of any head/branch
61*0d6140beSAndroid Build Coastguard Worker	if [ "${remote_ref#*refs/heads/}" != "$remote_ref" ]; then
62*0d6140beSAndroid Build Coastguard Worker		nonreachable=$(git rev-list $remote_sha ^$local_sha | head -1)
63*0d6140beSAndroid Build Coastguard Worker		if [ -n "$nonreachable" ]; then
64*0d6140beSAndroid Build Coastguard Worker			echo "Only fast-forward pushes are allowed on branches." >&2
65*0d6140beSAndroid Build Coastguard Worker			echo "At least $nonreachable is not included in $remote_sha while pushing to " \
66*0d6140beSAndroid Build Coastguard Worker			     "$remote_ref" >&2
67*0d6140beSAndroid Build Coastguard Worker			exit 1
68*0d6140beSAndroid Build Coastguard Worker		fi
69*0d6140beSAndroid Build Coastguard Worker	fi
70*0d6140beSAndroid Build Coastguard Worker
71*0d6140beSAndroid Build Coastguard Worker	# FIXME: check commit log format (subject without full stop at the end etc).
72*0d6140beSAndroid Build Coastguard Worker	# FIXME: do buildbot checks if authorized?
73*0d6140beSAndroid Build Coastguard Workerdone
74*0d6140beSAndroid Build Coastguard Worker
75*0d6140beSAndroid Build Coastguard Workerexit 0
76