After the Gate: Side Effects
Once a push passes pre-receive and update, the refs are updated and post-receive fires. This hook cannot reject anything — its job is to react to what just happened.
post-receive reads the same stdin format as pre-receive (old SHA, new SHA, ref name), but exiting non-zero has no effect on the push outcome. The push is already done.
Common uses:
Triggering CI/CD: Before webhooks became universal, teams used post-receive to kick off builds directly — reading the same old-SHA/new-SHA/ref-name stdin format as pre-receive, filtering for pushes to main, and firing an HTTP request at the CI server with the new commit's SHA to trigger a build.
Deploying static sites: A classic pattern for simple deployments is a post-receive hook that, on a push to main, checks out the new code directly into a web server's document root — turning git push itself into the deployment mechanism, with no separate deploy step at all.
Writing audit logs: For compliance environments, post-receive can write a structured record of every push — who pushed, what SHA, which branch, at what time — to a centralized log store.
Today, most CI/CD platforms (GitHub Actions, GitLab CI, Jenkins) use webhooks instead of post-receive hooks, because webhooks work with hosted Git services where you don't have filesystem access to the server. But understanding post-receive explains exactly what webhooks replaced and why the pattern works.