Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a pre-push script in my git repo that runs tests. If tests pass, the push carries on. If tests fail, it aborts the push.

The script worked great for a while until tests started to exceed 3 mins. stdout show a "Connection to bitbucket closed by remote host" in the middle of the test output. Then all the tests pass and the push doesn't actually go through.

Here's the pre-push script

#!/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
        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
like image 607
saada Avatar asked Oct 13 '15 18:10

saada


2 Answers

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
like image 125
saada Avatar answered Sep 22 '22 16:09

saada


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)

like image 21
VonC Avatar answered Sep 18 '22 16:09

VonC