Local executing hook after a git push?

GitGithooks

Git Problem Overview


I've looked at the githooks manpage but unless I'm missing something I don't see an option for local, post-push git hooks. I'd like to have one that updates the api docs on my web server (for which I already have a script) after I push the master branch to the GitHub repo. Of course I could just write my own script that combines the git push and the api docs run, but that feels somewhat inelegant.

Git Solutions


Solution 1 - Git

Another solution to this problem is to have a wrapper for git push that executes .git/hooks/pre-push and .git/hooks/post-push scripts before and after the git push call. A possible wrapper could look like this:

#!/bin/sh

GIT_DIR_="$(git rev-parse --git-dir)"
BRANCH="$(git rev-parse --symbolic --abbrev-ref $(git symbolic-ref HEAD))"

PRE_PUSH="$GIT_DIR_/hooks/pre-push"
POST_PUSH="$GIT_DIR_/hooks/post-push"

test -x "$PRE_PUSH" &&
    exec "$PRE_PUSH" "$BRANCH" "$@"

git push "$@"

test $? -eq 0 && test -x "$POST_PUSH" &&
    exec "$POST_PUSH" "$BRANCH" "$@"

Saved as git-push-wh somewhere in your PATH, it can then be called as git push-wh if you want to push with hooks.

Solution 2 - Git

This type of hook is not supported by Git. It falls outside the valid reasons for a Git hook as given by Git's maintainer.

The introductory remark in the above linked message speaks almost directly to your case: > I do not particularly like hooks that > act after an operation is initiated > locally and act solely on local data. > This is maybe because I still consider > git tools building blocks suitable for > higher level scripting more than other > people do.

P.S. A “Single Push” Hint
  • There are too many caveats for a full explanation, but if you can figure it all out you should be able to deal with the details.

An extra pushurl to a local repo with an “alternates” objects store could give you a low overhead way to locally execute a push hook. But really, the effort is much more than git push upstream && update-web-server (maybe in a shell alias, git alias, or script).

Solution 3 - Git

I recently came across the same issue. I wanted a hook so that a push from my git submodule would commit the new submodule reference in the 'superproject'.

As Chris mentioned, the best way is to just use a git alias, like this:

$ git config alias.xpush '!git push $1 $2 && update-server.sh'
# (remember the backslash before the ! if your shell requires it)

This adds the following to your .git/config file:

[alias]
  xpush = !git push $1 $2 && update-server.sh

And so now, if you type:

$ git xpush

your changes will be pushed, and then update-server.sh will be executed.

Solution 4 - Git

From Git 1.8.2 there is a new hook invoked before the push operation: pre-push If the script returns other than 0 the push operation will be cancelled.

Mention in the release notes: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt#L167

Sample: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample

Solution 5 - Git

I'm using a function for this:

current_branch() {
    local ref=$(git symbolic-ref HEAD 2> /dev/null) || return
    echo ${ref#refs/heads/}
}

gp() {
    local post_push="$(git rev-parse --git-dir)/hooks/post-push"
    git push "$@" && {
        [[ -x "$post_push" ]] && "$post_push" "$(current_branch)" "$@"
    }
}
compdef _git gp=git-push

The compdef part is for ZSH.

Solution 6 - Git

Just create a pre-push hook with a sleep at the top. Ensure sleep is long enough for the commits to be uploaded to upstream server based on your network connection speed. Ideally add a & to run your script in the background:

(sleep 30 && .git/hooks/post-push) &

Solution 7 - Git

Implementing a post-push hook is in fact possible by using the reference-transaction hook. After a push is done, git will locally update the remote tracking branch, triggering a reference transaction on refs/remotes/REMOTE/BRANCH.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionscotchiView Question on Stackoverflow
Solution 1 - GitFrank S. ThomasView Answer on Stackoverflow
Solution 2 - GitChris JohnsenView Answer on Stackoverflow
Solution 3 - GitndbroadbentView Answer on Stackoverflow
Solution 4 - GitAdrián DeccicoView Answer on Stackoverflow
Solution 5 - GitpschmittView Answer on Stackoverflow
Solution 6 - GitSoheilView Answer on Stackoverflow
Solution 7 - GitVictor MataréView Answer on Stackoverflow