Use Git Hooks to Automate WordPress Deployment and Cache Clearing

Every manual deployment step — pulling code, running Composer, flushing caches — introduces the risk of a missed command that leaves the site in an inconsistent state. Git bare repositories on the server paired with post-receive hooks automate the entire deployment sequence the moment a developer pushes to the designated branch. A bare repository contains only the version control data without a working tree, which makes it suitable for server deployments where you control the working directory separately. The post-receive hook receives the old revision, new revision, and reference name for every branch that was pushed, letting you trigger deployments selectively. Checking out with --work-tree and --git-dir flags separates the Git metadata from the live document root, keeping the .git directory outside the web root. Running composer install --no-dev --optimize-autoloader after checkout installs production dependencies and rebuilds the PSR-4 classmap in a single step. WP-CLI’s wp cache flush command clears the object cache via whatever cache driver is configured — Memcached, Redis, or the file-based default. You can extend the hook to run wp search-replace for environment-specific URL swaps, rotate log files, or send a webhook notification on success. File permissions must allow the Git hook’s executing user to write to the web root and run WP-CLI without sudo. The branching strategies post explains how to maintain a stable main branch that is safe to auto-deploy on every push. For multi-environment setups, branch naming conventions such as staging and production let a single hook script deploy to the correct target based on the pushed ref. Using --force-with-lease rather than plain --force when pushing prevents overwriting remote changes that another developer may have pushed since your last fetch.

Problem: Manual WordPress deployments via SSH — pulling code, running Composer, and flushing the cache by hand — are slow and error-prone, especially on teams with multiple developers.

Solution: Create a Git bare repository on the server and add a post-receive hook that checks out the branch, installs Composer dependencies, and flushes the WordPress object cache automatically on every push.

#!/bin/bash
# /var/repo/site.git/hooks/post-receive

TARGET="/var/www/html/wordpress"
REPO="/var/repo/site.git"
BRANCH="main"

while read oldrev newrev ref; do
    PUSHED=$(echo "$ref" | sed 's|refs/heads/||')
    if [ "$PUSHED" = "$BRANCH" ]; then
        echo "--- Deploying branch: $BRANCH ---"
        git --work-tree="$TARGET" --git-dir="$REPO" checkout -f "$BRANCH"
        cd "$TARGET" || exit 1
        composer install --no-dev --optimize-autoloader --quiet
        wp cache flush --path="$TARGET" --allow-root
        echo "--- Deploy complete: $(date) ---"
    fi
done

NOTE: Make the hook executable with chmod +x /var/repo/site.git/hooks/post-receive and verify that the deploy user has write access to $TARGET — permission errors during checkout produce no visible output and silently leave the old code in place.