#!/bin/sh # Refuse to push a release tag that disagrees with the VERSION file it points # at. Tags are cut by contrib/release, which makes the two agree by # construction -- so a mismatch reaching this hook means a tag made by hand, # and pushing it would publish a version string the source itself contradicts. # (VERSION is the floor contrib/version falls back to without git; v0.1.1 # shipped with the floor still saying 0.1.0, which is why this hook exists.) # # Install with `make hooks`. Skip with `git push --no-verify` when you mean to. set -eu # stdin: per ref being pushed. status=0 while read -r _ sha remote _; do case "$remote" in refs/tags/v[0-9]*) ;; *) continue ;; esac tagged="${remote#refs/tags/v}" commit="$(git rev-parse -q --verify "$sha^{commit}" 2>/dev/null)" || continue floor="$(git show "$commit:VERSION" 2>/dev/null)" || floor="(no VERSION file)" if [ "$floor" != "$tagged" ]; then echo "pre-push: refusing v$tagged -- the commit it tags has VERSION=$floor." >&2 echo " cut releases with contrib/release, which bumps and tags together;" >&2 echo " delete this tag (git tag -d v$tagged) and re-cut, or --no-verify." >&2 status=1 fi done exit $status