I will never forget the cold sweat that broke out on my neck back in 2018. I was tweaking a custom theme directly over FTP at 11:30 PM on a Friday. One accidental drag-and-drop later, I replaced functions.php with a zero-byte blank file. The entire client store dropped instantly into a white screen of death.
I had no backup, no history, and no quick way to undo the damage except manually retyping code from memory. That night was my breaking point. I decided right then to master proper wordpress version control, and it completely transformed how I build, deploy, and maintain sites today.
If you are still managing code via direct server edits or manual zips, learning to use git for wordpress development is the single best upgrade you can give your workflow. In this guide, I will walk you through setting up Git correctly, deciding what files to track, handling database headaches, and avoiding the painful mistakes I made along the way.
Why Traditional WordPress Workflow Breaks Down
When most developers start out with WordPress, their workflow looks pretty simple. You edit files on a local environment or server, upload them using an FTP client like FileZilla, and hope nothing crashes. But as soon as your projects grow—or you start working with a client or team—this manual approach fails in predictable ways.
Direct edits leave zero audit trail. If a feature breaks three weeks after launch, you have no easy way of knowing who changed what line of code or why. Undoing a mistake usually means restoring a massive server backup, which wipes out any recent content or sales updates that happened in the meantime.
Using wordpress version control solves this by turning your project into a chronological timeline. Every commit acts as a snapshot of your codebase. If something breaks, rolling back to a known working state takes seconds rather than hours of stressful firefighting.
- No more FTP overwrites: You never have to worry about accidentally replacing a newer server file with an outdated local copy.
- Seamless team collaboration: Multiple developers can work on separate features at the same time without stepping on each other’s toes.
- Instant rollbacks: Break something in production? You can revert to the previous commit with a single command.
- Clear history: Detailed commit messages explain why code changes were made months or even years down the road.
Deciding What to Track in Your Git Repository
The single biggest confusion beginners have when adopting git for wordpress development is figuring out what actually belongs in the repository. A default WordPress installation contains thousands of core files, user uploads, cache files, and database exports. Tracking all of that will turn your repository into a bloated, slow mess.
As a rule of thumb, you should only track code that you write or actively maintain. WordPress core core files, third-party plugins installed from the repository, and user-uploaded media inside wp-content/uploads do not belong in your Git repository.
Instead of tracking the entire root directory of WordPress, most modern developers set up their repository inside the custom theme or plugin folder. Alternatively, if you are building a completely bespoke site, you can place Git at the root level but strictly manage what gets tracked using a well-structured .gitignore file.
Structuring Your .gitignore File
Here is a basic example of what your root-level .gitignore file should exclude to keep your repo lean and clean:
- wp-config.php: Never commit your database credentials or secret keys to version control.
- wp-content/uploads/: Media files take up massive amounts of storage space and should be managed via cloud storage or server backups.
- wp-content/cache/: Dynamic cache files change constantly and create endless merge conflicts.
- WordPress Core: Exclude core directories like /wp-admin/ and /wp-includes/ if you manage core updates separately through composer or server scripts.
Setting Up Your First WordPress Git Repository
Let us walk through setting up a repository for a custom project. For this example, we will assume you are working locally on a custom theme or plugin where you might create a custom shortcode or build bespoke page layouts.
First, open your terminal and navigate directly to your custom theme directory inside your local WordPress installation. Initializing Git inside the specific theme folder is often the cleanest approach for freelance work.
Run the following command to initialize your repository:
git init
Next, create a .gitignore file inside that folder to prevent editor junk like .DS_Store or node_modules from sneaking in. Once your ignore file is saved, make your initial commit:
git add .git commit -m 'Initial commit of custom theme'
From here, create a remote repository on GitHub, GitLab, or Bitbucket. Link your local project to your remote repo using git remote add origin YOUR_URL and push your code. Now your custom work is backed up safely off-site.
This workflow becomes especially valuable when you are integrating complex plugins or custom fields. For instance, when using Advanced Custom Fields (ACF), tracking your JSON sync files inside Git allows your field group definitions to sync across environments automatically whenever you pull new commits.
How Do You Handle Database Changes with Git?
This is where every WordPress developer hits a wall at some point. Git is designed to track text files, not relational MySQL databases. Your posts, pages, plugin settings, and custom options all live in the database, which means running git commit will not save your database state.
So how do you keep your staging and production databases synced while using wordpress version control for code? The short answer is: you separate code deployment from database management.
Never push a local database straight to production on a live site. Doing so will overwrite new customer orders, post revisions, and user registrations that happened on the live server while you were working locally.
- Keep content flow one-way: Always pull production data down to local environments for testing, never push local databases up to production.
- Use WP-CLI for migrations: Command line tools allow you to search and replace domain URLs cleanly without breaking serialized data.
- Leverage migration plugins: Tools like WP Migrate DB Pro or WP Stagecoach make syncing databases between local and live servers manageable.
- Define structures in code: Use code to register post types, taxonomies, and options rather than relying manually on the admin dashboard. Following a solid custom post types guide ensures your content structures are locked into version control.
Automating Deployment with CI/CD Pipelines
Once your repository is running smoothly, manually pulling code onto your server via SSH gets tedious. Automated deployment—using Continuous Integration and Continuous Deployment (CI/CD)—is where the real magic happens in modern git for wordpress development.
With automated deployment, you never log into your production server to upload files. Instead, you push your tested code to your main branch on GitHub or GitLab, and an automated script handles building asset files, running tests, and transferring updated code to your server.
GitHub Actions is my tool of choice for this. You can set up a simple workflow file that triggers on every push to the main branch. The action connects to your host via SSH or SFTP and syncs only the modified files.
Before running automated scripts on live production sites, make sure your code builds cleanly and doesn’t introduce performance bottlenecks. It is always smart practice to run a WordPress speed self-audit on staging before pushing your build to live servers.
Costly Mistakes I Made with Git (And How to Avoid Them)
I have made almost every version control mistake imaginable over the years. Some cost me an hour of troubleshooting; others cost me half a weekend. Here are three major mistakes you can avoid right now.
First, I once committed a wp-config.php file containing live database passwords into a public GitHub repository. Within 15 minutes, automated bots scraped the keys and compromised the staging server. Always keep environment-specific credentials out of Git. Use environment variables (.env files) or keep wp-config.php managed outside your repository on the server itself.
Second, I tried tracking the uploads folder in a git repo early in my career. Within six months, the repo size exploded to over 12 gigabytes. Cloning the repository took almost 45 minutes, and local operations ground to a painful crawl. Keep media files out of Git entirely.
Third, I pushed code directly to production without testing API endpoints on staging. If your site relies on external APIs or custom endpoints, test them thoroughly in isolated environments. When working on WordPress REST API custom integrations, always test your endpoints locally and measure response times with a free website speed test tool before going live.
Final Thoughts on Modernizing Your WordPress Workflow
Switching to a version-controlled workflow might feel like extra overhead when you first start. Writing terminal commands, configuring ignore files, and setting up remote repositories takes a little time upfront. But the peace of mind it gives you is worth every single second.
You stop worrying about breaking live sites, you regain full control over your project history, and you can collaborate effortlessly with other developers. Start small: pick one single custom theme or plugin you are working on right now, open your terminal, and run git init. Once you experience the security of instant rollbacks, you will never go back to direct FTP edits again.

Should I put the entire WordPress core installation in Git?
Generally no. Tracking WordPress core creates bloated repositories and unnecessary noise. It is best to track only your custom theme or plugin, or track the wp-content directory while ignoring uploads and core files via .gitignore.
How do I handle database changes between local and production?
Git tracks code files, not databases. Move content one-way from production to local for testing. Use plugins like WP Migrate DB Pro or WP-CLI search-replace commands to handle database transfers without breaking serialized data.
How do I keep my wp-config.php credentials safe in Git?
Never commit wp-config.php containing live credentials to public or private repos. Add wp-config.php to your .gitignore file, or use environment variables to load sensitive database keys securely on each specific server.