For months I’ve been trying to plan out a good project structure for using git version control for WordPress website development that doesn’t sacrifice the ability to update core and plugins through the WP dashboard, doesn’t require an unconventional directory structure (wp-content outside of the WP parent folder) and that is easy to manage and deploy whole websites. I’ve read about submodules, subtrees, nested repos, etc, and I’m still having a hard time fitting it all together and choosing the right strategy.
Here’s what I’m thinking right now, with my thoughts for how I would handle git repos in parenthesis.
root (main project repo)
|-- wordpress (public git repo added as subtree)
| |-- wp-content
| | |-- plugins
| | | |-- my-custom-plugin (git repo added as subtree)
| | | |-- other-plugin-with-git-repo (git repo added as subtree)
| | | +-- other-plugin-without-git-repo (ignored/untracked)
| | |-- themes
| | | |-- my-custom-theme (git repo added as subtree)
| | | |-- other-theme-with-git-repo (git repo added as subtree)
| | | +-- other-theme-without-git-repo (ignored/untracked)
| | +-- uploads (ignored/untracked)
| |-- wp-admin
| +-- wp-includes
|-- wp-config.php (ignored/untracked)
+-- other-files.txt
This leaves me with several problems/questions;
-
Automatic updates; I love the new auto updates feature, it could potentially save a lot of time and effort in keeping my sites updated and secure, but it seems that it throws a wrench in tracking code changes with git. Is there any way to track my code changes while still allowing WordPress core to auto update?
-
Does having subtrees under the WordPress core repo prevent me from using git to merge in new core updates or pushing out my changes back to the WordPress core repo (if I ever decide I’d like to be a core contributor)?
-
For plugins that don’t have a public git repo, completely ignoring them creates the problem of not being able to quickly clone the entire site on a new server without manually copying files over to the server. It also causes a problem if I want to make changes to that plugin’s code those changes aren’t tracked and could easily be lost in a plugin upgrade.
So, to summarize, what is a good git+WordPress setup that avoids these problems? I would appreciate your feedback on my proposed project structure. Any way that you can help me improve this, would be much appreciated!
PS, if there is a better forum for this discussion, please point me there.
From my perspective there are two issues with your plan – Git and “conventional” structure. So basically everything. 🙂
Git (and version control in general) is a poor tool for whole site stacks. Been there, done that, it hurt a lot.
What you call an “unconventional” structure with content separated from core has been a very conventional and robust choice for any serious site for a while.
There are pretty much no turn-key ways to combine whole site stack with native updates. It just doesn’t go well together since it tries to achieve different goals in projects of different levels (developer in control vs end user in control).
If you ask me the best bet for whole site WordPress stack is currently Composer, however opinions may wary. 🙂
On your specific concerns:
As above – native updates (more so auto) don’t play well with tightly controlled stacks.
WordPress core isn’t developed in Git and doesn’t accept pull requests, all contributions are (so far) via patch files to Subversion.
You’ll likely have to commit such plugins into your repo. Or go with another approach like Composer.
You might take a look at this issue and this issue.
Also take a look at the README files in each repo as well:
Based on above repos, as another example of a Git/WP setup, I created this. I opted to use symlinks for themes (I try to cover that in my README).
I’m kinda in same boat with the auto updates though … My plan was to manually update WP submodule when updates happen. I think the alternative is, in theory (I have yet to test myself), to let the submodule update itself for minor updates (there’s a WP setting for this) and then do a
git
force/reset of the submodule when major updates come out (maybe one of the answers here could be of some help … of course, I think, one would want to target a specific WP tag when updating to next major release).One thing to note is that if WP sees
.git
in the path(s), it will automatically turn off auto updates. For more info, see:Other related links:
May, 2015 update
I created this repo which is a quick way for me to start WordPress projects. My latest approach is to only version control the theme(s). In other words, I install WP locally (using setup in aforementioned repo) and on production, then I modify the config file on each system and
git
pull my theme(s) to get a functional site.This type of development falls into the “not so easy and requires a custom workflow that might take a long time to be happy with”.
I find Subtrees, submodules or nested repos, a huge pain in the ass.
Some thoughts (track everything).
add_filter( 'auto_upgrade_ignore_checkout_status', '__return_true' );
Safe method via manual commits + email:
You can use a staging server and email update notifications to yourself, commit the updates and push to the live server which has auto updates off.
This also allows you to copy/paste folders for your own repos at will, which is often how I do it. It also makes it easy to clone/destroy multiple staging servers, git really comes into effect with this method since it is distributed.
The downside: copy/pasting folders, management.
Auto method
Set up a build script (Phing, Ant, Bash, Capistrano,etc) and some custom code that will do a git add + commit when a update is applied and send it to the live server. You can also separate plugins/theme repos and then have the script compile/move/whatever them, and/or use Composer in the mix.
Automating a workflow like this also tends to be inflexible and only worth it if you see a real need for the time invested.
The downside: inflexible, takes time to create.
Git should not be used for backups, and generally speaking there is no need for you to clone WP’s commit history.
Ok, watching Mark Jaquith’s talk here, maybe I’m on the wrong track. Here’s another stab at it that tracks everything.
I guess the main downside with this is having a custom content directory, which has caused problems for me in the past with poorly written plugins and themes not being able to find the content directory.
After some more thought, since I definitely want to take advantage of native WP updates to save myself legwork, it doesn’t make sense to track anything that WP will update using git. Here’s a revised idea.
Of course, then I lose the ability to track which plugins and themes are a part of the project from within the VCS, but I really only need that for backup purposes, and I’ll be using some sort of regular backup system anyway.
So, the only thing this really lacks that I want is the ability to easily deploy the whole stack to different servers without using FTP to manually copy the whole thing over. Anyone have any thoughts on that?