Git Submodule init

Hi everyone, I’ve been working with trellis/bedrock/sage for a little while now, and I keep coming up with problems using submodules. More specifically, I can’t use submodules with my wordpress sites, since Trellis won’t initialise and install them as part of a deployment.

There’s a lot of discussion out there on how to add (for example), plugins or themes as submodules in your repo, which is Chris Jean’s approach. The answer is usually that the theme or requirement should be handled as a dependency via composer, or should be cloned into your repo (without being initialised as a submodule).

This isn’t always possible, and in any case, submodules represent a way to better structure your repositories and handle their development. I don’t think Trellis should be demanding you abandon those workflows. I’d have more sympathy if Trellis treated your entire site(s) as a composer package(s), but since it’s using git repos, it should be able to initialise the whole thing :sweat_smile:

Am I misunderstanding how Trellis handles submodules? If I’m not, it seems as if the ‘build before’ hooks could be expanded to include initialising submodules (all power to ansible). If there are reason why this would be inappropriate?

I use git submodules with trellis, though I had to fork it to get it to work.

Ben seems opposed to submodules for some reason I can’t quite grok.

Anyways, my fork is here:

It’s a bit behind roots:master though.

The relevant change here is :


Clever, though this looks like it doesn’t actually pull your repo at all any more, instead copying the development files in roles/deploy/tasks/prepare.yml line:26-29?

- name: Copy files to new build dir
  shell: cp -pr {{ project_source_path }}/* {{ deploy_helper.new_release_path }}
  when: deploy_using_git_archive==false and project.repo_subtree_path is not defined

I’m not fluent in ansible yet, so excuse me if that’s wrong.

It checks out your repo and sub modules to a “build” directory and then copies that to a deploy directory, skipping .git directories because you don’t want those deployed on a web server. That’s how trellis does it when you deploy sub modules or not.

The current version of trellis use git-archive to do this but git-archive doesn’t do submodules, so I added a flag to skip it and use the old behavior of trellis before the switch to git-archive.

1 Like

Why is this not possible? Running composer install --prefer-source should get your packages as git repositories. From there you can commit, push, pull, just like normal. I’ve worked on a couple projects like that where the plugin and/or theme are separate git repo’s.

I don’t think anyone that works on Trellis is opposed to adding helpful features, but there needs to be a compelling reason. So what’s the advantage of using submodules over Composer?

I don’t know if “not built in” is the same as “demanding you abandon”.

Again, I’m not sure I follow the reasoning. Are you suggesting you have Trellis in a repository and your site in another repo? I don’t think this is impossible if you wanted to set up your project that way…

I’m interested in hearing the reason that git submodules are a feature that’s in demand.

Even with one site, this seems sensible. Specifically, it makes your codebase modular, and I can install the same site in different Trellis’, or outside of trellis, all using one repo - Trellis is a way to deploy my sites, it is not my site. In other words, my site is a subcomponent of a trellis project, a fact which in general Trellis seems to be built around.

Practically speaking, lumping things together becomes altogether painful when you have multiple sites installed, and when trying to keep pace with the frequent updates to Trellis.

However, this isn’t the issue- what I meant to do was to highlight the disparity between requesting git repos from the user, instead of loading sites as composer dependencies, and treating the repo as if it were a composer dependency by leaving the submodules out.

Yes that will work, but I think you’re slightly misinterpreting me. It is a core part of how repos interact that one can use submodules, even the bedrock repo uses sage as a submodule. By omitting support for repos which contain submodules, Trellis is requiring non-standard git configuration. This is not noted anywhere outside the forums, and produces the unexpected behaviour that submodules are not initialised on remote deployments.

You could say it’s not unexpected, that Trellis doesn’t specify it will fully install and initialise the repo you ask it to use when deploying, however

  • This means that a local directory, with all commits pushed to the source, will behave differently between development and remote deployments, since in only one will your submodules be initialised. This violates Trellis’ mission to provide identical deployments.

  • You are having to manually add specific sources in composer to access your git repo, instead of simply using github’s native tools.

  • Changes to which branch you’re using won’t be reflected in the composer file unless manually updated, making it comparatively brittle.

Ultimately it’s not the end of the world, and if I’m honest I think git submodules a bit of a fiddle, but I do think the lack of submodule support should be more clearly noted (possibly a comment by the ‘repo’ variable in the example configs).

I’d have to disagree. Perhaps not with how this is stated, but I’ve personally found that having the provisioner as part of the project to be quite beneficial. Working with someone means you don’t have to give them multiple repositories. It also hasn’t been too difficult updating Trellis by using git cherry pick, I’ve found…

Again I’m not following. Composer dependencies replace git submodules, from what I can tell. They’re not being left out, they’re being replaced. There’s been a whole lot of articles posted on the web why git submodules for themes/plugins/packages isn’t a great idea. It’s why package managers have been developed.

I’ve never seen this. Do you have a link?

What is non standard about this? Adding the --recursive flag when cloning is not standard practice. Unless of course you’re using git submodules. Which isn’t assumed in Trellis…

Am I correct in assuming that you mean that Trellis is violating it’s mission, because a feature it doesn’t claim to support is unsupported?

Just submodules… because Composer is being used…

I’m sorry, but don’t you still need to commit any changes in your submodule, as well as commit in the main project the updated git pointer? How is updating your main project’s git pointers of submodules less brittle than updating a composer lock file?

I don’t know of many projects which list things they don’t support. And if I’m being honest, this hasn’t been a majorly requested feature. Most people use Composer or another package manager to manage their projects now…

1 Like

Okay yes, I see your point, I think you’re right.

What I was trying to say though is that you can easily assume a repo will be recursively installed with a deployment tool which works directly with git repos. The docs have changed a bit since I first read them, and I can’t find any evidence of a roots using submodules in its repos- I was wrong.

So we have a plugin that we use on every project, and it’s also available on the WordPress plugin registry.

It’s under active development when we use it on a project, so we need a dev setup where we can easily make and commit changes to the plugin AND be able to deploy at a moment’s notice. Composer doesn’t allow this very easily, --prefer-source isn’t the answer. This problem is further compounded by nested vcs repo’s in composer.json’s for some of our dependencies. Composer doesn’t handle that at all without copying and pasting those vcs repo’s all the way up the chain.

There’s the local symlink option, but that f-cks with deploys.

Lastly, composer is slow af. Submodules are fast and easy.

1 Like

I was trying to use a submodule for a package requirement (CMB2) in my Sage theme but got it to work using the Bedrock composer instead:

in site/composer.json:

  "repositories": [
      "type": "vcs",
      "url": ""
  "require": {
    "cmb2/cmb2": "^2.3"
  "extra": {
    "installer-paths": {
      "web/app/themes/sage/lib/vendor/{$name}/": ["cmb2/cmb2"],

Note: the order of installer-paths matters, if the web/app/plugins/{$name}/ path comes ahead of your custom path it will be installed in the plugin directory instead.

Now i can include the files using dirname( __FILE__ ) . '/vendor/cmb2/init.php' from within /sage/lib/extras.php.