How to update and deploy WordPress as a Git submodule

Yellow submarine docked above water.
We all live in a yellow submodule.

WordPress 3.8.2, a security release, came out yesterday. Now, if you’re already on WordPress 3.8, your WordPress installation will most likely automatically update, but if you are using Git to manage WordPress as a submodule, and have auto-update disabled, you have to do that manually.

That said, it’s still super easy to do. It definitely outweighs not having a version control system.

Let’s look at the Git commands required to update WordPress from 3.8.1 to 3.8.2. Note that this will work for updating any version.

Current State

Here is the current state of affairs:

  1. I’m in the root of the website.
  2. WordPress is installed as a submodule in the wordpress directory.
  3. The WordPress origin comes from GitHub.
  4. I have the production server setup as a remote origin.
  5. I’m currently on the develop branch.

Update WordPress Submodule

First, we have to update our WordPress submodule from GitHub. We do this by:

  • Fetching all new tags
  • Checking out the WordPress version we want
ryan@MacBook: ~/Sites/[develop]$ cd wordpress

ryan@MacBook: ~/Sites/[(detached from 3.8.1)]$ git fetch --tags
remote: Counting objects: 197, done.
remote: Compressing objects: 100% (114/114), done.
remote: Total 197 (delta 116), reused 128 (delta 77)
Receiving objects: 100% (197/197), 326.11 KiB | 0 bytes/s, done.
Resolving deltas: 100% (116/116), done.
 * [new tag]         3.7.2      -> 3.7.2
 * [new tag]         3.8.2      -> 3.8.2

ryan@MacBook: ~/Sites/[(detached from 3.8.1)]$ git checkout 3.8.2
Previous HEAD position was 22bb602... Tag 3.8.1
HEAD is now at 5577e02... Tag 3.8.2

ryan@MacBook: ~/Sites/[(detached from 3.8.2)]$ cd ..

As a side note, I wrote a blog post that shows how to add the Git branch name to your shell prompt.

Commit WordPress Update

Second, we need to commit our changes. We do this by:

  • Staging our changes on the develop branch
  • Committing those changes
  • Switching over to the master branch
  • Merging the develop branch into master

Once that’s done, we’ll push both branches back up to origin.

ryan@MacBook: ~/Sites/[develop*]$ git add wordpress

ryan@MacBook: ~/Sites/[develop*]$ git commit -m "Updated WordPress from 3.8.1 to 3.8.2"
[develop 990ea06] Updated WordPress from 3.8.1 to 3.8.2
 1 file changed, 1 insertion(+), 1 deletion(-)

ryan@MacBook: ~/Sites/[develop]$ git checkout master
M	wordpress
Switched to branch 'master'
Your branch is up-to-date with 'prd01/master'.

ryan@MacBook: ~/Sites/[master*]$ git merge develop
Updating b90e460..990ea06
 wordpress | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

ryan@MacBook: ~/Sites/[master]$ git push origin --all
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 273 bytes | 0 bytes/s, done.
Total 2 (delta 1), reused 0 (delta 0)
To /Volumes/Repositories/
   b90e460..990ea06  develop -> develop
   b90e460..990ea06  master -> master

Deploy WordPress Update

Third, we’re going to deploy our WordPress update. We do this by:

  • Pushing out the master branch to the production server

Please note that you will need a post-receive hook in place that knows how to fetch and update  submodules on the production server. You can see a complete example of such a hook in my other blog post.

ryan@MacBook: ~/Sites/[master]$ git push prd01 master
[email protected]'s password: 
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 273 bytes | 0 bytes/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: > Received master branch
remote: > Determined environment is PRODUCTION
remote: > Determined master branch is target branch
remote: > Processing master branch
remote: > Unset GIT_DIR
remote: > Moved into /var/www/domains/
remote: > Determined htdocs contains files
remote: > Determined working directory is on master branch
remote: > Determined updates affect current branch
remote: From /opt/repositories/
remote:  * branch            master     -> FETCH_HEAD
remote: Updating b90e460..990ea06
remote: Fast-forward
remote:  wordpress |    2 +-
remote:  1 files changed, 1 insertions(+), 1 deletions(-)
remote: > Pulled origin/master into master branch in htdocs
remote: > Updated .updated file in htdocs
remote: Entering 'wordpress'
remote: From
remote:  * [new tag]         3.7.2      -> 3.7.2
remote:  * [new tag]         3.8.2      -> 3.8.2
remote: Entering 'wp-content/plugins/akismet'
remote: Entering 'wp-content/plugins/contact-form-7'
remote: Entering 'wp-content/plugins/w3-total-cache'
remote: > Fetched commits and tags for each submodule
remote: From
remote:    cbb694c..1dd3b92  3.7-branch -> origin/3.7-branch
remote:    831b3ca..bf71d64  3.8-branch -> origin/3.8-branch
remote:    3533e35..a3c725f  master     -> origin/master
remote: Submodule path 'wordpress': checked out '5577e024a5d3d5fe17215a67e7791e1b3bccccd7'
remote: > Initialized and updated all submodules
remote: > Determined website runs WordPress
remote: > Determined WordPress has W3 Total Cache installed
To ssh://[email protected]/opt/repositories/
   b90e460..990ea06  master -> master


That’s it! Once you confirmed all these steps work for you, you can do all this in one swoop.

cd wordpress && git fetch --tags && git checkout 3.8.2 && cd .. && git add wordpress && git commit -m "Updated WordPress from 3.8.1 to 3.8.2" && git checkout master && git merge develop && git push origin --all && git push prd02 master

Let me know if you have any questions or problems with this!

Featured image by Sung Jin Cho.