Xenology
Xenology

Reputation: 2462

Git Hook timing out connection to Github - is there a "pre-send" Git hook that I could tie into?

So I have a git hook for pre-push that runs a bunch of code linting and tests. These tests can sometimes take upwards of 2 - 3 minutes to run. Because of this my connection to Github times out, and the push to Github fails.

I don't want to have these tests run after every commit, as I tend to wait until I've made all my changes and done my own testing, then commit everything in several small commits at the end. It's expected that during development tests would break and I don't want that to stop me from committing, just from pushing broken code to Github. I also only want to run all my tests once I think they should pass right before I push my code up to GitHub.

If there a sort of "pre-send" Git hook that I could tie into? That would run all my tests both after all my commits are done and before my push, but before the connection to Github is opened so I don't have to worry about timeouts? Or am I just in a situation where I need to adjust my workflow and commit larger sections of code?

I like the idea of having small intentional commits, in order to logically break up the changes for code review later. As opposed to having all the changes grouped into one giant commit, just so I only have to run my tests once. But if I can't prevent git from opening the connection to GitHub on the pre-push hook before I run my tests this seems like a situation I may have to just bite the bullet on.

Upvotes: 1

Views: 1472

Answers (2)

bk2204
bk2204

Reputation: 76794

Until Git opens the connection to the server to read the refs, it doesn't know what the server has on its side, and so there's no way to determine what data would be pushed. As far as Git knows, the two repositories could be up to date and so there'd be nothing to push.

Usually the way people handle this case is to set up some sort of CI system and then push their code into something other than the main branch, then merge (fast-forward or otherwise) into the main branch. That is the recommended way of dealing with it, mostly because (a) it's automated and (b) it can't be bypassed. The latter doesn't matter much if you're the only one working on the project, but it very much does matter for any sort of collaboration.

If you don't want to do that, you can switch to HTTPS instead of SSH for this operation, since Git will open a new connection if the old HTTPS connection drops during the pre-push hook.

Upvotes: 1

ElpieKay
ElpieKay

Reputation: 30888

How about the idea of running the linting and tests in the post-commit hook, with a switch to run only when you intend to? For example, post-commit in bash

#!/bin/bash

is_runnable=$(git config foo.bar)
if [[ "${is_runnable}" = yes ]];then
    # linting and tests
else
    # do nothing
fi
exit 0

For git commit, the hook is invoked but goes into "do nothing" block. When you want it to run linting and tests, specify foo.bar=yes,

git -c foo.bar=yes commit

As for foo.bar, it's a valid git configuration variable. But it's better to come up with a meaningful one which does not have a conflict with other configuration variables.

Upvotes: 0

Related Questions