I’ve been using a multi-site setup for my Drupal sites for sometime now – it’s easier to configure, maintain and manage – but I’d realised that one thing I was lacking was a decent version control system. I’d been relying on backing up to daily & weekly archive files, but this was starting to become unmanageable, with several months worth of files to deal with.
I’d previously used Subversion, but decided that I needed to look at git for several reasons. Setting up a basic git system was fairly straightforward, but I wanted a system where if needed I could easily extract a fully working single site from within the multi-site setup. Storing the Drupal code in git lets you track any changes you make to the code, i.e. altering a theme or updating a module, see what changes have been made and if needed role them back and then either regenerate the entire setup (for example on a development server, or if your main server has a disk failure), or you can extract a fully working single site from the setup.
To do this, I’ve used functionality in git known as submodules – basically it allows you to integrate a number of separate git repositories (repositories are how git stores ‘chunks’ of code); one for the main configuration and one for each subsite into one large code store. With this in place, I can retrieve either a fully working multi-site setup (either to undo some changes or possibly to setup a development server) or a single working site.
A standard multi-site setup within Drupal will have a structure something like that shown below:
Any shared code will exist in the base setup, with each unique site existing in the sites folder with any unique modules, folders etc – so for example, this site lives in a folder called sites/simonhanmer.com .
Setup of Git
To create a fully working setup, you need one repository for the main code and one for each sub-site (excluding all & default). When setting this up, I follow the existing procedure:
- Create an empty repository in the base install directory
- Create a sub repository for each site and populate it
- Add the sub-repositories to the main repository
- Add the remaining core files and commit them to the master repository.
As an example, assume I’ve setup a server with the main Drupal code in /var/www and a single subsite simonhanmer.com. To create the basic repositories, you’d need to perform the following steps (I’m assuming a Linux server here, but the same basic steps would work on either Windows or a Mac).
- cd /var/www
- git init
- git commit –allow-empty -m “Commit of empty master repository”
- cd sites/simonhanmer.com
- git init
- git add .
- git commit -m “Initial commit of simonhanmer.com”
- cd /var/www
- git submodule add /var/www/sites/simonhanmer.com sites/simonhanmer.com
- git add .
- git commit -m “Initial commit of base files and subsite simonhanmer.com”
Steps 1-3 create the initial, empty repository that will eventually hold the non-site specific files from Drupal. Steps 4-7 then create another repository containing the files specifically for simonhanmer.com. Step 9 tells the master repository where the site specific repository can be found, and then finally steps 10-11 add the remaining non-specific files to the master repository.
Once these repositories have been created, git can then track any changes to the code as per normal.
For example, if we created a new file in sites/simonhanmer.com – say files/newfile.txt, and then query git, we might see something like:
# Not currently on any branch.
# Untracked files:
# (use "git add ..." to include in what will be committed)
#nothing added to commit but untracked files present (use "git add" to track)
Considerations & Warning
The only thing that must be remembered when using git in this way is that the files in the sub-repositories MUST be processed whilst in the correct directories, i.e. if the file above was added in sites/simonhanmer.com, DON’T add or commit it while in the master repository – it must be added whilst within the sites/simonhanmer.com folder.