This post was contributed by guest author 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, bringing his work along with him as he goes.
This article is based on a few ideas, thoughts and opinions I have about Git and WordPress. There is still no de-facto standard for how these things are dealt with in WordPress and I think it is our responsibility, as a community, to have discussions about them. These are my opinions and I would love to hear yours as well.
Let’s get right to it.
I have ranted about the subject of repository structure before and I have strong opinions about it. In my opinion there is one – and only one – way to structure Git repositories in a WordPress context. That one way is the one-package / one-repository approach. Let me explain why.
While working on WP Pusher, I have seen many different approaches to structuring Git repositories. Two approaches are especially common, and, in my opinion, equally bad.
The first one is Git-it-all, where everything, including WordPress core, plugins and themes are put under version control. The other one, and more common, is
wp-content-under-version-control. I say that both of them are equally bad, because no matter what, you are going to have a lot of 3rd party code included in your Git repository, which quickly becomes a mess. Every time WordPress or one of your plugins or themes ships a new update, you will have to somehow deal with it within your version control system.
The argument for having WordPress itself under version control is most often to lock down the version of the code. This seems a bit redundant to me, since WordPress is already developed using version control (SVN) and comes with a version number for each update. Why would you need to manage that yourself when it is already managed for you? Today, installing WordPress with Composer is super easy and then you can control your version from the
composer.json file. There are no excuses. Do not include WordPress in your Git repository.
The second approach,
wp-content-under-version-control, is often chosen as an easy way of deploying multiple plugins that might depend on each other. Still, I am not buying it. Having 5, 10, or even 20 Git repositories in your
wp-content directory is really not an issue. Also, if your plugins depends on each other, take a look at must-use plugins.
So here is the deal: You need to treat each of your packages (be it a plugin or a theme) with respect. You need to give each of them their own Git repository. They are their own entities and needs to be separated. Keeping them locked up together makes it impossible to share code across projects. It is the way Git is supposed to work, it is the way Composer is supposed to work, and it is even the way WordPress itself works.
To Ignore, Or Not To Ignore
Yes, that is the question and I do not have the answer. I am, of course, talking about the
.gitignore file. The file that tells Git which files and directories to exclude from version control. Actually, the real question is: Should you precompile your dependencies before shipping your plugin, or not? (I will focus on PHP dependencies, since I do not know enough about front-end things.)
In an ideal world, you would never ship something like Composer dependencies with your package. It would be up to the user to compile and fetch those dependencies that fit their specific environment. That is the whole point of dependency management tools. However, in WordPress, there is absolutely no sane way to handle these PHP dependencies. So if you are shipping a WordPress plugin that relies on 3rd party dependencies, I would say “ship it all”, even though it feels very wrong and awkward.
This is bad, though, because what happens when Mailchimp for WordPress ships with one Composer package in v1.0.0 and WP Pusher ships with the same package but v2.0.0? Oh, the horror. The plugin that is loaded first will get to autoload its classes. The others will not (since it would result in a “class exists” fatal error). I probably do not need to explain why this is bad.
As a WordPress developer, you can try to mitigate this by making sure that the functionality you rely on is actually available at runtime, but this is not optimal. However, I really think this is WordPress’ responsibility. We cannot do PHP without using 3rd party code. That would be stupid. So as I said: No clear answer. I guess it just depends.
Exporting Repositories aka Zippin’
Recently, someone on Reddit proposed that people start to include a
.gitattributes file in their repositories, containing export instructions for Git to use when archiving repositories (zipping them). Basically, by specifying it in your
.gitattributes file, you can make Git ignore files that you only need for development.
The Reddit thread was specifically targeting authors of packages distributed with Composer, but we can use this trick as well. If you exclude files from exports, they will not appear in the zip archives that you can download from GitHub or Bitbucket. This is nifty, especially if you use a tool like my WP Pusher to move files from Git to WordPress, since it can drastically minimize the size of the archive files. No need to ship files such as assets, that are already compiled, and unit tests to end users.
Here is the
.gitattributes file for WP Pusher:
/features export-ignore /apache-ci.conf export-ignore /behat.yml export-ignore /circle.yml export-ignore /composer.json export-ignore /composer.lock export-ignore
Before I knew about this trick, I manually deleted these files before shipping the plugin. Now it is done automatically.
There you go. Just a few things I want you to think about and consider if you are a WordPress developer using Git. Thanks for reading along.