Keeping drupal sites under control

By Erik, Tue, 08/02/2011 - 20:16
Version control is a hot topic in terms of managing and deploying sites. Now that has moved from a server-based version control system (CVS) to a distributed version control (git), some developers have been on the push to move their own development strategies into git to have one control system to manage all of their files. Keeping files "under version control" means that you're going to add an extra step to the saving and managing of your files. Git does not automatically track all changes to files that you're working on. Git does not even track files per se. It actually only tracks changes to the files which is a slightly different concept and will come up again later. The basic concept of git is that you create a repository, work on files, then stage all or some of your changes into the repository. Once a set of changes are ready to be grouped together, you can "commit" them as one single set of changes to multiple files/directories. These commits are the distinct points in time for the repository. One of git's strengths is in it's "distributed" nature. You don't need to be in contact with the mothership to do your work. While groups can set up their own hierarchies and procedures, technically, no one repository is more important than another. When you do create an "upstream" or server-based repository whether on github or on your own server, it's still simply a git repository like any other even if you consider it the shared repository from which everyone will fetch code.

Setting up git

There are many tutorials for setting up git, but the one that seems to be the most straight forward is github's tutorial Even if you're not using GitHub, the instructions are pretty easy to follow. If you're not using Github, you can skip steps like: "4. Add your SSH key to GitHub" however, having a github account is not a bad thing, so when it doubt follow all of the steps and you'll still be ready to git.

Keeping a site under git

Since I generally use Drupal multisites and don't kill kittens, I will keep each drupal_root/sites/ as a separate repository. I don't need to keep the whole Drupal install under control because the core files will never change. Plus, I typically work on sites that are/will be part of a multisite anyway.

Get git started

If you're building a site from scratch and there is no existing repository, create the basics of the site (files directory, settings.php, etc.) and then create your git repo.
cd ~/Sites/drupal/sites;
mkdir subsite.vmdev;
mkdir subsite.vmdev/files;
cp default/default.settings.php subsite.vmdev/settings.php
Depending on how you're going to be using the version control, you may or may not want to have your files directory controlled. Typically those are user uploaded files and site specific and don't need to be transferred if you're using git as part of a deployment strategy. Also, I almost never keep settings.php in the repository so that you don't ever accidentally spread your database username and password around. Luckily git provides an easy way for us to ask git to ignore certain files/folders. If you create a file named .gitignore (the leading dot is important), then you can write out file names or patterns that you would like to have excluded from the repository.
echo "settings.php" > .gitignore
echo "files/" >> .gitignore
Now that you have the files for a working Drupal site, you can initialize your git repository.
git init
That's it. Now you have a completely functional, albeit empty repository ready for action.

Using git in the building process

Once you've started downloading contrib modules, themes, and libraries, and creating your subtheme and custom modules, your directory structure will start changing. How often you update your git repository is a very personal choice. There are those who "commit early, commit often" which leads to great history and identifiability for all things and there are those who commit only when they're ready to share their code. As with most things, my preferred method is somewhere in the middle. To commit changes to your repository, you need to stage which changes you'd like to commit and then write a single commit for them. Typically, I will commit when a) adding a cohesive set of modules, b) finishing an individual task, or c) fixing a quick bug. So, one example would be when I get "calendar" set up.
mkdir modules/contrib
drush dl calendar, date, views, jquery_ui
git add modules/contrib/calendar modules/contrib/date modules/contrib/views modules/contrib/jquery_ui
git commit -m "Downloaded calendar and necessary modules (date, views, jquery_ui)"
If I had an existing custom module subsite_fixes and had finished writing the code that incorporated a custom block, I might do the following:
git add modules/custom/subsite_fixes/
git commit -m "Updated to incorporate new strategic block"
A "task" might incorporate changes to more than one file. There may be CSS changes, PHP changes and exports that need to be updated. Those can all be done in a single commit as long as they're all related. Next up: Sharing your git repositories