14+ years building on WordPress / Replies in under 5 hours
WordPress 3 min read · Updated July 2026

WordPress and GitHub: How to Structure the Repo

Photo of Ajay Khandal
Ajay Khandal
WordPress Developer
TL;DR

For WordPress in git: track your custom theme and plugin code only. Don't track WordPress core (it updates independently), wp-content/uploads (media, not code), or wp-config.php as-is (it holds secrets — use environment variables or a git-ignored local config instead). Manage third-party plugins via Composer rather than committing them wholesale. Getting code onto GitHub and deploying it to a live server are separate problems — WP Pusher handles simple cases, a GitHub Actions pipeline is the durable setup for anything with a real staging step.

“Integrating WordPress with GitHub” usually gets explained as a generic git tutorial — create a repo, clone it, commit, push — with no mention of what’s actually specific to a WordPress project. The real question isn’t how to use git, it’s what belongs in the repo at all, since a WordPress install has a mix of your code, third-party code, generated files, and secrets that shouldn’t all be treated the same way.

What to Actually Put Under Version Control

Track: your custom theme and plugin code — the files you actually write and review. That’s the entire point of version control: a history of changes to code you’re responsible for.

Don’t track WordPress core. Core updates through WordPress itself or Composer, and diffing thousands of core files on every WordPress version bump adds noise without adding safety — it’s not code your team is editing.

Don’t track wp-content/uploads. Media files aren’t code, they grow a repo to an unmanageable size fast, and they belong in a real backup/CDN strategy instead — not git.

Don’t track wp-config.php as-is, since it holds database credentials and secret keys. Keep a wp-config-sample.php in the repo as a template, and load the real values from environment variables or a git-ignored wp-config-local.php on each environment instead.

A Real .gitignore for WordPress

wp-config.php
wp-content/uploads/
wp-content/cache/
wp-content/upgrade/
node_modules/
vendor/
.env
.DS_Store

Whether vendor/ belongs in .gitignore depends on your deploy process: if your deployment step runs composer install on the server or in CI, ignore it; if you deploy a static built artifact with no build step on the target, you may need to commit it. Pick one and be consistent — a repo that sometimes has vendor/ committed and sometimes doesn’t is how deploys silently break.

Managing Dependencies with Composer

Third-party plugins and libraries generally shouldn’t be committed wholesale either — that’s what Composer is for, tracking exact versions in composer.json instead of thousands of vendor files in git. The Composer for WordPress dependencies guide covers setting this up in detail; it’s the piece that makes the .gitignore rules above actually work in practice.

The Local Workflow

Once the repo is scoped correctly, the actual git workflow is standard: initialize the repo in your project directory, add your tracked files, and push to GitHub.

git init
git add .
git commit -m "Initial commit"
git remote add origin <repository-url>
git push -u origin main

From there, branches and pull requests work exactly like any other git project — nothing WordPress-specific changes about how you collaborate once the repo itself is scoped correctly.

From Repo to Live Site

Getting code onto GitHub and getting it onto your live server are two different problems, and this is where a lot of “WordPress GitHub integration” content stops short. Two real options: WP Pusher is a plugin that pulls a theme or plugin directly from a GitHub repo with no CI setup required, a reasonable choice for a solo developer or a small site. For anything with a real testing/staging step, a GitHub Actions pipeline that deploys on push is the more durable setup — the CI/CD pipeline for WordPress development guide covers building that out with GitHub Actions, SSH deployment, and automated PHPCS checks in full.

If you’re starting a new themed project from scratch rather than retrofitting an existing one, building a custom WordPress theme from scratch is worth reading alongside this, since repo structure is easiest to get right from day one.

Frequently asked questions

No. WordPress core updates independently through WordPress itself or Composer, so tracking thousands of core files in git adds noise on every version bump without adding any real safety — it's not code your team edits or reviews.

At minimum: wp-config.php (holds secrets), wp-content/uploads/ (media, not code), wp-content/cache/, node_modules/, and .env files. Whether vendor/ belongs there depends on whether your deploy process runs composer install on the target — if it does, ignore vendor/; if not, you may need to commit it.

Keep a wp-config-sample.php template in the repo, and load real credentials from environment variables or a git-ignored wp-config-local.php file that exists separately on each environment. This keeps secrets out of your commit history entirely, including old commits.

Version control (git add, commit, push) just gives you history and collaboration on your code — it doesn't put anything on your live server by itself. Deployment is a separate step, handled either by a plugin like WP Pusher pulling from the repo, or a CI/CD pipeline that runs on every push.

WP Pusher is the simpler option — a plugin that pulls a theme or plugin directly from GitHub, no CI setup required, reasonable for a solo developer or small site. A GitHub Actions pipeline is worth the extra setup once you want automated tests or code-standards checks to run before anything reaches production.

Photo of Ajay Khandal

Written by Ajay Khandal

I'm a freelance WordPress developer with 14+ years of experience building, fixing, and speeding up sites for businesses, agencies, and store owners across the US, UK, Europe, and Australia. I specialize in custom themes, WooCommerce, and performance — the kind of work that shows up as faster load times and fewer support tickets. No account managers, no outsourced tickets — you work directly with me, with replies typically inside 5 hours.

Work with me →