If you are new to using Version Control and WordPress be it with SVN, GIT, or another system then some of the things you used to do are going to have to change. However, the benefits do outweigh any initial inconvenience. So here are my 10 many tips for people who might be in the process of switching to using version control.
1. Disable automatic updates
One of the most important things is that the site in version control is the same as the one deployed, or at least a branch of it is. While you do want to do timely updates to WordPress core, you want to do that from a local copy, which is then managed via version control and deployed.
WordPress Core is pretty smart, and if it spots you are are using a version control system because you have a folder (.svn, .git, .hg, .bz) in either your root path (for core updates), plugins folder (For plugins) or one level up from these then it will disable automatic updates and instead email the admin user. This is fine on local and maybe staging environments but on production servers you may have deployed and these folders haven’t been carried over. To stop automatic updates all together (including the email firing) you can use the following in your wp-config.php
define( 'AUTOMATIC_UPDATER_DISABLED', true );
This has disabled all the WordPress automatic updates. Bear in mind you should only do this if you updating via version control and if for some reason you stop using version control (maybe you’re parting ways with a client) that you remove this define.
2. No File Editor please, we are British
You might not be (British that is) but the file editor is evil and with version control you have absolutely no excuse to be using the file editor to modify plugins or your themes. Hopefully this wouldn’t have been an issue as you would have not made such files writable by WordPress in the first place. Regardless as we don’t need this functionality it’s best to disable it.
define( 'DISALLOW_FILE_EDIT', true );
3. Stop users from uploading plugins/themes directly
I suspect you can see a trend, but the ability to install plugins directly from WordPress goes against using version control. Again we want to disable it, and the simplest way is to use:
define( 'DISALLOW_FILE_MODS', true );
Which also disables the File Editor and Automatic updates, so basically you can skip the last two steps and jump straight to this one. Again it’s important to emphasise that if you don’t use version control this can leave a site vulnerable and using version control only works if you do actually update WordPress!
4. Separate WordPress core from plugins and themes into different repos
example.com/ |->local-config.php |->public_html |-->index.php |-->wp-config.php |--> core |-->custom |--->plugins |--->themes
This will make updates much simpler, and WordPress feel much more logical. I have written an article on how I structure WordPress projects, and one of the big advantages of doing this is that you can load in the WordPress core as sub module (or equivalent in your version control of choice). This means you hold a separate repository for WordPress core and your sites. You then only need to have WordPress core repo once and update it once for it to be updated across all your sites. Just remember whatever deployment system you use it has to cope with sub modules and deploy the latest version on the branch specified of them too.
You can expand this to include other items in sub modules, for example if you have a default parent theme you use across multiple sites, you might want to have it’s own repo and include it as a sub module. Likewise plugins used on multiple sites are another perfect candidate to working with sub modules. Be careful, while deployment systems should be able to cope with sub modules, some might not be able to cope with sub module in sub module and things can get complex quickly sometimes it’s easier to have repetition between codebases to keep things simple.
5. Separate out a local config version
I guess this tip isn’t specifically a version control tip, but if you are deploying to multiple sites then you will probably be interacting with different databases, using different keys and generally have different config options along the way. One option is to ignore the wp-config file and simply allow each site to have its own wp-config.php, but I prefer to put the shared information (all the bits in the wp-config that will be the same) into wp-config.php then create a local-config.php an idea originally found in Mark Jaquith’s skeleton structure. I can then ignore (or put it outside of version control entirely) this local-config that includes server specific content.
6. Automate your build processes
So when people think of version control, they tend to think of it for teams. Most of my projects these days are solo affairs yet I still use version control, still branch when developing a new feature and still regularly commit. One of the reasons for this is habit, and it’s also a good backup policy, but also because of the next step after I push my changes, automated builds both on staging and production. Automated Builds (Deployments) allow you to deploy changes made in a version control branch to a specific server (staging, production) and run any associated tasks, for example compiling sass files, or tests along the way. There are dozens of tools and services out there such as Jenkins, Travis, PHPCI and services like DeployHQ, and these allow you to deploy code and run additional tasks on the server post deployment.
Deployment systems will normally allow you to run additional tasks, such as working with WP-CLI to auto-activate plugins or update WordPress database when needed, a good deployment setup is one where no one has to get involved and you have the confidence that everything will update without any interference or even need to manually check (but take a peek and check anyway). However it should also be simple enough that any member of staff can use it.
7. Run your tests before you build (aka write some tests)
Speaking of running tests, why not run them before they get on to the server? Version control systems like Git have hooks that can be used to run other tasks. For example a commonly used Git hook is pre-commit-hook which allows you to run a task prior to the commit being stored. If you have critical features you may wish to run tests of this hook to make sure your commit is not going to break anything. An alternate test suite hook location might be pre push (Only available in Git 1.8.2+), and this fires before you push your changes to others. Depending how you are using Git this might be a more appropriate time to test.
8. Never Let broken code through
Even if you are not using pre-commit-hook or its equivalent for running tests (shame on you) what you can do is make sure you don’t commit bad code. Most languages have what’s called a linter and in PHP you call it via the CLI version of PHP using:
php -l myfile.php
What it does is run through the file and spot any fatal errors, warnings etc. being picked up and displays them to the screen. It doesn’t however execute the file, just reads it and checks for errors. Most languages have a linter or one has been developed for them, so you can build a script to go through your common languages, check the files for issues and notify you when you try to commit. For PHP you can start with this simple gist or for multiple languages take a look at One commit hook to rule them all. Bear in mind that linters normally use local version of the language. If you develop using Vagrant or similar but commit on your local machine, then the pre-commit-hook will run using the local machine not the Vagrant version of the language.
9. Enforce Standards
WordPress has a coding style and standards and while sadly they have chosen to not adopt what the rest of the PHP world is doing at least it’s consistent. However, unless you work in WordPress 100% chances are you are going to have habits and style that are different. It’s up to you how much this might bother you, but if you are working on a public WordPress project you may wish to enforce the WordPress coding standards on commits. This is easy enough to do using PHP Codesniffer, a Pear/Composer package that like the linter tools reads files but instead of looking for errors looks for incorrect placing of curly brackets. You can specify what particularly to look for and how your code should be styled. You can grab a ruleset for WordPress from Github. For a generic PHP project Zumba have a good step by step guide to setting Codesniffer with Git.
10. Pick a branching strategy
This will probably be unique to your organisation but there are lots of tutorials on good branching strategies. Most involve having 1 or 2 main trunks (for dev and production) and then individual developers work on a specific feature. I use a variant on Vincent Driessen’s Branching Model.
11. (because these list never have just 10) Still backup uploads
This might seem like a bit of a weird one. If you have been used to doing “full site” backups of all your files then the good news with version control is that you don’t need to backup the files in version control as well – it’s in version control (unless you are insanely paranoid, in which case do the backup through git rather than your site). You do however still need to backup the database and your uploads folder (which won’t be in version control). When setting up a backup regime it’s easy to forget that user uploads are not in your version control repository, and if you stop doing file based backups can easily be forgotten entirely.
Finally a couple of non WordPress specific bonus tips
You don’t need to use VI
At least on a Mac, when you merge changes the wonderful vi/vim opens up and for many users the nightmare begins. But you can change the editor simply by doing:
git config --global core.editor "nano"
In that case it globally changes the core editor to the much more user friendly nano, of course you could always learn the dark art’s of working with VIM.
Searching your commit messages
Assuming you write intelligent commit messages, this command is really useful
git log --grep="message in commit"
Never let the boss have sftp access
If you are automating deployments, then no one barring system administrators should have direct access to servers. In larger organisations this means you should be revoking credentials for almost everyone in the company who perhaps in the past had ssh or worse FTP credentials, even the boss. If you don’t then the temptation to go around the build process will be high and the moment someone makes a “hot fix” the whole system is broken.
Put it all together
Version control systems only work if they are at the heart of your workflow not simply somewhere to store code, but once you start to build a workflow around them they become an incredibly powerful tool that can be tailored to almost any development environment. I would love to hear your tips and how you are using version control systems in your workflow, especially if it’s something you are just getting started with, what issues are you facing?