In general, you should not assume refs/heads/
or refs/for/
, because your hook will be run for tag pushes (refs/tags/
) and other pushes (e.g., refs/notes/, perhaps refs/stash, and so on).
Note that you (or anyone) can run, e.g., git push there refs/heads/master:refs/for/something refs/tags/v1.2:refs/tags/v1.2 refs/remotes/origin/master:refs/heads/master
to request a push of three things simultaneously, which is why you have to read all the requests in a loop in the pre-push hook.
You suggested in a comment that you are using:
remote_ref >> remote.txt
remote_ref1 = cat remote.txt | cut -d'/' -f3
rm remote.txt
which has some syntax errors.
It's wiser to check the prefix, and if it's what you expect and wish to handle, strip the prefix. Don't just extract the third word, since that will break if you are using branches named feature/tall
, for instance, or are working with references with additional structure beyond the first two components (remote-tracking branches work this way for instance, though normally you would not push them).
In sh/bash script language, you can write, e.g.:
case $local_ref in
refs/heads/*)
local_type=branch
local_short=${local_ref#refs/heads/}
;;
*)
local_type=unknown
;;
esac
case $remote_ref in
refs/heads/*)
remote_type=branch
remote_short=${remote_ref#refs/heads/}
;;
refs/for/*)
remote_type=gerrit
remote_short=${remote_ref#refs/for/}
;;
*)
remote_type=unknown
;;
esac
Now that you have decoded the reference types and found short versions for known cases, you can write your per-case logic, and later extend it as appropriate:
case $local_type,$remote_type in
branch,branch|branch,gerrit)
# push from branch to branch, or from branch to gerrit:
# require that the shortened names match exactly (for now)
if [ $local_short != $remote_short ]; then
echo "push to $remote_type requires paired names" 1>&2
echo "but you are pushing from $local_short to $remote_short" 1>&2
exit 1
fi
;;
*)
# echo "unknown reference type - allowing" 1>&2 # uncomment for debug
;;
esac
All of this would then go inside the main while read ...
loop. If you make it to the end of the loop, all the references you are pushing have been verified (since none were rejected by the echo-and-exit code).