Managing Your WordPress Site with Git and Composer Part 3 – Using Git Submodules to Manage Themes and Plugins


In part 2 we looked at how we might use Composer to manage our themes and plugins. In this article we’re going to look at an alternative way of managing your themes and plugins that doesn’t require any third party tools.

From the Git Submodules documentation:

Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate.

This can be very useful when you want to store a third party library in your project, for example, whilst still keeping both repositories separate in Git. In our case we want to store themes and plugins in the same Git repository as our WordPress install from part 1. Git Submodules are the equivalent to “externals” in Subversion if you are familiar with that.

Adding Git Submodules

Thankfully the entire WordPress plugins Subversion repo is mirrored over on GitHub which makes finding Git versions of any plugins super easy. Sadly there isn’t a mirror for themes so you’ll have to find those yourself.

Let’s install the GitHub mirror version of our WP Migrate DB plugin. The process of adding submodules to your Git repo is actually relatively simple. Run the following command from the root of your Git repo:

git submodule add -f ./wp-content/plugins/wp-migrate-db

This will add the submodule to your Git repo and download all of the required files. Here we are using the GitHub mirror for our repo URL but it’s worth noting that this can be any Git repo URL you like (for example a private Git repo). We use the -f here to force Git to add the submodule, otherwise it will complain about the folder being ignored (see the .gitignore in part 1). Commit these changes by running:

git commit -m "Added WP Migrate DB plugin"

Now you have WP Migrate DB installed and you can activate it and use it as you would normally. The process is identical for adding themes, just make sure to install them to your “themes” directory.

Updating Git Submodules

Unfortunately updating Git submodules isn’t quite as straightforward as you might imagine. This is one of the main drawbacks of using Git Submodules. The structure of Git Submodules does make it easy to commit changes back to your repositories as you can edit the submodule files just like any other Git repository. However, to update the submodule to the latest version (as we would want to do with our WordPress plugins) you need to navigate into the submodule folder, checkout the latest version, then commit these changes into the main repository. The commands would look like this:

cd wp-content/plugins/wp-migrate-db
git checkout master
git pull
cd ../../..
git commit -am "Updated WP Migrate DB"

That is quite a lot. However, there is a quick one-liner that might save you a lot of time, especially if you have multiple plugin submodules:

git submodule foreach git pull origin master

What if you want to use a specific version of a plugin? You can achieve this by checking out the tag that corresponds to the version you need:

cd wp-content/plugins/wp-migrate-db
git checkout tags/0.7.1
cd ../../..
git commit -am "Updated WP Migrate DB to v0.7.1"

Removing Git Submodules

Like updates, removing Git submodules isn’t as simple as you might think but admittedly not as bad as updates. To remove our plugin submodule we would run:

git submodule deinit wp-content/plugins/wp-migrate-db
git rm wp-content/plugins/wp-migrate-db
git commit -am "Removed WP Migrate DB"

The plugin folder should now be completely removed from the repo and the .gitmodules file should be updated to reflect this change.


As with Composer you will need to find a way to keep your submodules up-to-date on your production server (or whatever servers you deploy to). Deployment strategies are outside the scope of this article, but let’s assume for the minute that you have setup a post-receive Git hook on your production server. The post-receive hook is simply a script that will run after a repository has been pushed to. One way you might automatically update your submodules is by adding the following commands to the post-receive hook:

git submodule init
git submodule sync
git submodule update

These commands will make sure that your Git Submodules get updated every time you push to your production repo. The submodule sync command here just updates your local submodule config with any upstream changes.

Custom Themes & Plugins

The process to set up custom themes and plugins is almost identical to the process I described in part 2 so I’m not going to go over it again here. Suffice to say that you can simply store your custom theme/plugin alongside your submodules in the Git repo with no issues.

What to Choose?

Whether or not you should use Composer, Git Submodules, or even something else completely (e.g. WP CLI) to manage your themes and plugins will probably depend on your project requirements. Composer is great if you’re looking for something simple and don’t mind SSHing to your server. Submodules are great if you’re developing plugins in WordPress and need to commit your changes back to your repository (something you can’t do with Composer). Both have their pros and cons.

That’s it for part 3. In the next post we’ll be looking at installing and managing the WordPress Core in a subdirectory using Composer or Git Submodules.

About the Author

Gilbert Pellegrom

Gilbert loves to build software. From jQuery scripts to WordPress plugins to full blown SaaS apps, Gilbert has been creating elegant software his whole career. Probably most famous for creating the Nivo Slider.