Managing WordPress Projects With Git

During the beta testing of WP Pusher, I have seen numerous examples as to how WordPress developers use Git to manage their projects. WP Pusher is opinionated in terms of how your Git setup needs to look, in order to use the service. In this post, I will try to explain why.

First of all, WP Pusher works on a package basis, meaning that one Git repository maps to one WordPress package (a theme or a plugin). We use the WordPress core installer to handle package installation and updates. The official repository works in a similar way, where each package is its own entity. Of course. If you do not honour your WordPress packages with their own Git repositories, you will not be able to user WP Pusher.

Different Approaches

The most common approach I have seen is one installation, one repository. With this approach, your whole WordPress installation, including themes and plugins, is under Git control. I think this approach is fundamentally broken, and not how Git is meant to be used. The main problem is that you will have to keep a lot of 3rd party code under version control. Every time WordPress auto updates the core, a theme or a plugin, you Git repository will be a mess. Some of the issues I see with this approach:

  • Automatic updates messes up your version control.
  • Themes and plugins can not be reused across projects, because they are not there own entities (eg. have their own repositories).

One argument for this approach is the ability to roll back code after WordPress updates. This might be a valid point, at least for larger enterprise-like setups. However, most WordPress projects should not need this feature – if so, it should be build into the auto updater. There are still ways to do this in a sane manner, such as placing the WordPress core in its own directory, that you can manage with Git or Git submodules.

Another approach is to have the wp_content folder as one repository. This approach has the same flaws as the one above. You will have to constantly commit updates for 3rd party packages and if your own packages are not their own entities, you can not reuse them across projects.

One Package, One Repository

The approach I advocate is one package, one repository. This approach respects that each package is meant to be its own entity. To me, it feels very wrong to keep 3rd party code under version control. Other frameworks and programming languages handles this with dependency management tools such as Composer. If I am using Composer, all 3rd party code will be placed in a vendor folder that I can simply have Git ignore. By default, WordPress does not allow for this, but there are various ways you can go about it if you absolutely need to have the WordPress core code under version control, as I already mentioned. The one package, one repository approach is the only approach that is not redundant to me. It is the only approach that truly allows for sharing code across projects, open sourcing packages and so on.

The way WordPress is build to work is not to support versioning control on a project level. WordPress relies heavily on the auto updater, which would make your versioning control a mess. If you do have something that is more enterprise than most WordPress setups, you should consider a custom setup that allows better for versioning control of core. Packages should still, in my opinion, each have their own repositories, since they are logically their own entities.

Comments or questions? Please post them below!


Want to read more like this?

Add your email address below to stay in the loop when new content arrives. You'll never miss a post.

Peter Suhm

Peter is a web developer from the Land of the Danes. He is the creator of WP Pusher and a huge travel addict.

  • I am already using this approach for my “packages”. Every plugin and the theme has it’s own repository in Git. I do use composer with my plugins and ignore the vendor folder. For updates, I use a tiny PHP script that triggers “git pull” and “composer install” (if necessary) on each push via a web hook. For me, this setup is ideal for a self managed project.

    Things become a little more complicated, if you are going to publish your plugin to the Plugin Directory, as you than have to include the vendor folder. Currently, I don’t need dependencies in my published plugins, but if I had to, I would most probably extend my “Git to SVN” deploy bash script, creating a stable build with the vendor folder.

    But having a stable tag in your Git repo as well, you should probably also have to include it into the tagged commit. So than again, you would have 3rd party code in your repo (but only in a tagged commit).

    How would you guys do it?

    • I would do the same thing as you. Publishing your packages including the dependencies is the only way as I see it.

      Git pull is the easy way and there are several solutions that can handle this. However, many hosts don’t have Git installed… Yet! 😉

  • Why the hell is your plugin not on anymore? Was it removed by folks on (or did you do it by yourself)? Is there any explanation?


    • Yes, there is an explanation. It was add’ed by mistake the first time. They don’t allow the auto updater to pull from anywhere else than .org. Unfortunately.