Skip to content
CH SCShop classwordpress · intermediate · ~50 min · 6 steps

How to put a WordPress site under version control

Track the parts of WordPress that belong in Git — themes, custom code, config — while keeping uploads and secrets out, and deploy by push.

August 10, 2026 · by Dane Petersen

Version control gives a WordPress site a memory: what changed, when, and a way to undo it. It’s also half the answer to who actually owns your website — a repo you hold is code nobody can hold hostage. This lesson assumes you know basic Git; here we decide what parts of WordPress belong in it, because the answer is absolutely not “everything.”

Decide what’s code and what’s content

The split that makes WordPress and Git get along: code goes in Git, content stays out. Your theme, custom plugins, and any must-use plugins are code — yours, worth tracking. The database (posts, pages, orders) is content — it changes every minute and lives in backups, not commits. The uploads folder is content too: images belong in backups, not in a repo that would balloon to gigabytes. WordPress core and third-party plugins sit in the middle — versioned releases you install rather than write. The simple call, and the one we’ll make here, is to track which versions you’re running but treat the files as replaceable.

Write the WordPress .gitignore

From the site root, start the repo and tell Git what to ignore before the first commit:

git init

Then create .gitignore with this:

# Secrets — never commit credentials
wp-config.php
.env

# Content, not code
wp-content/uploads/
wp-content/cache/
wp-content/upgrade/
wp-content/backup*/

# Plugin runtime junk
wp-content/wflogs/
*.log

wp-config.php is the line that matters most — it holds your database password, and a password that’s ever been committed lives in the history forever. Commit a wp-config-sample.php-style template instead if you want the structure recorded.

Commit the baseline

git add -A
git commit -m "Baseline: site as deployed 2026-08-10"

This first commit is the “known good” photograph of the whole site — core, plugins, theme. From here on, git status after any incident tells you in seconds whether files changed that shouldn’t have, which is why a repo is also a quiet little security tool.

Handle plugin updates as commits

An update is a change; a change gets a commit. One update per commit keeps the history honest:

wp plugin update woocommerce
git add -A
git commit -m "Update WooCommerce 9.8.2 -> 9.9.1"

When an update breaks something Thursday, git log tells you what moved Wednesday, and git revert walks it back without archaeology.

Push to deploy if your host supports it

Many hosts (WP Engine, Pantheon, SpinupWP, anything with a Git deploy feature) accept a push and roll it onto the server for you. Add the host’s remote and push:

git remote add production YOUR_HOSTS_GIT_URL
git push production main

Once this works, nobody edits files on the server directly — the repo is the source of truth, and the server is just where it lands. On plain cPanel without Git deploy, the same discipline works with an extra step: push to GitHub, then pull on the server over SSH.

Verify a change travels end to end

Make one harmless, visible change — a CSS tweak in your theme:

git add wp-content/themes/YOUR_THEME/style.css
git commit -m "Test: verify deploy pipeline"
git push production main

Load the live site (hard refresh) and confirm the tweak shows. Then revert it and push again, and confirm the site returns to normal. If a change can travel repo-to-live and back, your pipeline works — and the next time it carries something that matters, it’ll be routine instead of an event.

That's the lesson. Back to the shop for more — or if this is the chore your organization never gets to,that's literally what we're for.