libcamera/utils/hooks/pre-push
Laurent Pinchart 40d9947781 utils: hooks: pre-push: Check push to integration/* branches
Branches named integration/* are candidates for merge in the master
branch. Subject them to the same checks in the pre-push git hook.

An important difference between integration branches and the master
branch is that the former are typically created as new branches. We
can't check the whole history as there are known bad commits, so we have
to identify the base commit for the integration branch. The best
approximation is to use the remote master branch for the tree being
pushed to.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-10-19 13:14:54 +03:00

102 lines
2.5 KiB
Bash
Executable file

#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# A hook script to prevent pushing unsuitable commits to the master or
# integration branches. Criteria to determine unsuitable commits are listed
# below.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
# <local ref> <local sha1> <remote ref> <remote sha1>
z40=0000000000000000000000000000000000000000
remote_name="$1"
remote_url="$2"
while read -r local_ref local_sha remote_ref remote_sha
do
case "$remote_ref" in
refs/heads/master)
;;
refs/heads/integration/*)
;;
*)
continue
esac
# If the remote branch gets deleted, there's nothing to check.
if [ "$local_sha" = $z40 ]
then
continue
fi
# Check if we are creating a new branch or updating an existing one.
if [ "$remote_sha" = $z40 ]
then
if [ "$remote_ref" = "refs/heads/master" ]
then
# There are known invalid commits in the full history,
# skip the checks if we are pushing the master branch
# (for instance to an empty repository).
continue
else
# We're pushing a new integration branch, check all
# commits on top of the master branch.
range="remotes/$remote_name/master..$local_sha"
fi
else
# Update to existing branch, examine new commits only.
range="$remote_sha..$local_sha"
fi
#
# Find invalid commits.
#
errors=0
for commit in $(git rev-list "$range")
do
msg=$(git cat-file commit "$commit")
# 1. The commit message shall not contain a local changelog.
if echo "$msg" | grep -q '^--- *$'
then
echo >&2 "Found local changelog in commit $commit"
errors=$((errors+1))
fi
# 2. The commit message shall have a Signed-off-by line
# corresponding the committer.
committer=$(echo "$msg" | grep '^committer ' | head -1 | \
cut -d ' ' -f 2- | rev | cut -d ' ' -f 3- | rev)
if ! echo "$msg" | grep -F -q "Signed-off-by: ${committer}"
then
echo >&2 "Missing committer Signed-off-by in commit $commit"
errors=$((errors+1))
fi
# 3. A Reviewed-by or Acked-by is required.
if ! echo "$msg" | grep -q '^\(Reviewed\|Acked\)-by: '
then
echo >&2 "No Reviewed-by or Acked-by in commit $commit"
errors=$((errors+1))
fi
# 4. The commit message shall not contain a Change-Id.
if echo "$msg" | grep -q '^Change-Id:'
then
echo >&2 "Found Change-Id in commit $commit"
errors=$((errors+1))
fi
done
if [ $errors != 0 ]
then
echo >&2 "Found $errors errors in $local_ref, not pushing"
exit 1
fi
done
exit 0