#!/usr/bin/env bash # some of this is from # https://lubomir.github.io/en/2016-05-04-signoff-hooks.html remote="$1" url="$2" z40=0000000000000000000000000000000000000000 while read local_ref local_sha remote_ref remote_sha; do if [ "$local_sha" = $z40 ]; then # Permit deletion of branches : elif echo "$remote_ref" | grep -Eq "^refs/heads/(wip|tmp)/"; then # wip/ branches may contain commits which are not signed off : elif echo "$remote_ref" | grep -Eq "^refs/dgit/"; then # let's not interfere with a dgit push : elif echo "$remote_ref" | grep -Eq "^refs/tags/(archive/)?debian"; then # let Debian upload tags through : elif [ $(git config --get --type=bool --default=false \ branch.${local_ref#refs/heads/}.signOffOptional) \ = "true" ]; then # some local branches may be configured not to require signing # off wherever they are pushed : else if [ "$remote_sha" = $z40 ] then # New branch, examine all commits range="$local_sha" else # Update to existing branch, examine new commits range="$remote_sha..$local_sha" fi # Check for WIP commit commit=$(git rev-list -n 1 -i --grep '^WIP' "$range") if [ -n "$commit" ] then echo >&2 "Found WIP commit in $local_ref, not pushing" exit 1 fi # Check for commits without sign-off if [ "$remote_sha" = $z40 ]; then # New branch is pushed, we only want to check commits that are not # on master. range="$(git merge-base master "$local_sha")..$local_sha" fi while read ref; do msg=$(git log -n 1 --format=%B "$ref") if ! grep -q '^Signed-off-by: ' <<<"$msg" \ && ! grep -q '^Commit Debian 3.0 (quilt) metadata$' <<<"$msg"; then # allow merge commits through if [ -z "$(git rev-list -1 --merges $ref~1..$ref)" ]; then echo >&2 "Unsigned-off non-merge commit $ref" exit 1 fi fi done < <(git rev-list "$range") # The process substitution above is a hack to make sure loop runs in # the same shell and can actually exit the whole script. fi done exit 0