git pre-push: connection closed by remote host while running tests

The answer should explain why git is trying to reach Gitlab or Bitbucket or whatever (in my case it's Gitlab) even though the pre-push script is not finished

The pre-push hook was introduced in commit ec55559, Jan. 2013, Git v1.8.2-rc0

It was part of the as/pre-push-hook patch:

See commit 87c86dd, commit ec55559, commit 5a7da2d (13 Jan 2013) by Aaron Schrab (aschrab).
(Merged by Junio C Hamano -- gitster -- in commit bb9a696, 24 Jan 2013)

The only other modification to it was made commit af65f68 (16 Nov 2015) by Clemens Buchacher (drizzd) to ignore SIGPIPE, meaning to ignore its standard input stream. (Merged by Jeff King -- peff -- in commit 40fdcc5, 01 Dec 2015)

The documentation does include:

Information about what is to be pushed is provided on the hook's standard input with lines of the form:

<local ref> SP <local sha1> SP <remote ref> SP <remote sha1> LF

For instance, if the command +git push origin master:foreign+ were run the hook would receive a line like the following:

refs/heads/master 67890 refs/heads/foreign 12345

although the full, 40-character SHA1s would be supplied.

  • If the foreign ref does not yet exist the <remote SHA1> will be 40 0.
  • If a ref is to be deleted, the <local ref> will be supplied as (delete) and the <local SHA1> will be 40 0.

In order to determine the right value for the remote SHA1, transport.c has to exchange with the remote repository (GitLab in your case)


I ended up calling git push --no-verify inside of the success case. So it effectively pushes twice.

#!/bin/sh
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )

# This script runs tests before any push to the MASTER branch and fails
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
echo "Current branch: "$current_branch
if [ $current_branch = "master" ]
then
    echo "Pushing to MASTER branch requires tests to pass..."
    ./run.sh test
    if [ $? = 0 ]
    then
        # workaround to guarantee my push goes through even if the first attempt times out
        git push --no-verify
        exit 0
    else
        echo "***ERROR> Failed to pass tests! Get tests to pass and then try again..."
        exit 1
    fi
else
    echo "Skipping tests since we're not pushing to MASTER..."
fi