Home / Using git subtree to Make a Distro Your Docroot

Using git subtree to Make a Distro Your Docroot

A cornerstone of good Drupal development is deploying your site’s code from a version control system like Git or SVN. A further best practice is to put all your code in a directory in the repository, instead of at the top level of the repository. Doing this allows you to put other things into the repository that are not intended to be served publicly. For example, Acquia’s Cloud Hooks are scripts you put into the hooks directory that run when you deploy code, databases, or files, but should never be served as site content. Using Cloud Hooks, your repository looks like:

/docroot/... your site code …

/hooks/... your Cloud Hooks here …

At first glance, though, this approach has a downside. Many people want to use Git to track the Drupal distro their site is built from (Drupal core, Acquia Drupal, Pressflow, etc.) so they can easily pull in changes. However, most distro repositories keep their code directly in the top level of the repository. Simply adding the distro repository as a Git remote and running git pull puts the distro code in the top level of your repository too, which is not where you want it. In addition, you certainly cannot install contributed Drupal modules and themes into the top level of your repository.

Thus, the question for today is: How do you merge a remote repository (the distro) into a directory in your repository (the docroot), such that you preserve the remote repository's history and can easily merge in future updates? The best answer (according to stackoverflow and others) is to use the added set of git subtree commands rather than git's built-in subtree merging facility or the git submodule system.

In brief, here are the steps (assuming you already have git set up):

  1. Install the new git subtree command
  2. Clone your Acquia Cloud git repository
  3. Delete the docroot
  4. Subtree merge the distro as the new docroot so you can later run subtree pull to get updates
  5. Add any other needed modules and themes

Installing the git-subtree command onto your machine is pretty easy. The most generic instructions are:

$ git clone git://github.com/apenwarr/git-subtree.git
$ cd git-subtree
$ sudo bash install.sh

If you are using OSX and have homebrew installed you can take an even simpler path:

$  brew install git-subtree

You can verify that it's installed by typing git subtree with no arguments, which will show the usage options:

$ git subtree
usage: git subtree add   --prefix=<prefix> <commit>
or: git subtree merge --prefix=<prefix> <commit>
or: git subtree pull  --prefix=<prefix> <repository> <refspec...>
or: git subtree push  --prefix=<prefix> <repository> <refspec...>
or: git subtree split --prefix=<prefix> <commit...>

... etc

Look at your Cloud hosting dashboard on the Acquia Network, copy the git URL, clone your repository, and clean out the default docroot:

$ git clone mysite@svn-99.devcloud.hosting.acquia.com:mysite.git
$ cd mysite
$ git rm -r docroot
$ git commit -m"delete initial docroot in preparation for adding distro"

Let’s assume we want to add Pressflow 6.x as the docroot, since Pressflow will let a Drupal 6 site take advantage of HTTP acceleration from Varnish.

$ git subtree add --prefix=docroot git://github.com/pressflow/6.git master

Note that you may want to use the --squash flag so this is a single commit, rather than pulling in the whole history. However, pressflow has relatively few commits, and you may find it interesting to look at some of the specific changes.

Add the settings.php file and add to it the file include command from the “Databases” section of the Acquia Cloud UI.

$ cp docroot/sites/default/default.settings.php docroot/sites/default/settings.php
$ echo "
if (file_exists('/var/www/site-php')) {
  require('/var/www/site-php/mysite/mysite-settings.inc');
}" >> docroot/sites/default/settings.php
$ git add docroot/sites/default/settings.php
$ git commit -m “Adding settings.php”
$ git push

Now, wait a few seconds so the code has time to deploy to your dev environment. Then you can visit install.php and get started, e.g.

http://mysite.devcloud.acquia-sites.com/install.php

If you need to update to e.g. a new release of Pressflow, it’s nearly as easy. Just do this from your local clone of the repo:

$ git subtree pull --prefix=docroot git://github.com/pressflow/6.git master
$ git push

At this point you can download and add additional modules and themes, or use git subtree again if you want to pull them in from git as well.

For example to get the latest Drupal 6 version of Node Clone (using --squash):

$ git subtree add --squash --prefix=docroot/sites/all/modules/node_clone http://git.drupal.org/project/node_clone.git 6.x-1.x
$ git push

You can then later update the module by replacing “add” with “pull”, as shown above for the distro. This approach is likely most useful for modules that are in active development or that you contribute to. For stable releases of other modules, you can use drush or just directly download the module and git add it to your repository.

P.S. - The git subtree install instructions also describe how to make and install a man page. Sadly, this tends to require building a couple helper programs or installing more packages just to end up transforming the initial .txt instructions into a slightly different man page text file. You can use the attached man file and copy it into place.

P.P.S. - If you use svn to managed your code want to do something similar, you can basically use the instructions for svn_load_dirs.pl that I posted before, or make a full-blown vendor branch and track it for merges as written up on drupal.org. This svn-based vendor branch and merge technique is how we manage updates to the www.drupalgardens.com site.

Attachments: 

Comments

Posted on by Brad Czerniak (not verified).

Is version tracking Drupal core or things in contrib that you tend not to hack really a best practice?

In <a href="http:// hawidu.com/2011/12/09/drupal-and-git/">a presentation to DrupalCamp Michigan about git</a>, I tried to make the case that your version control environment should be reusable units; a custom module for one site might be appropriate for a later site, for instance. Things like core and contrib, unless they're necessary to edit, can best be controlled, deployed, and upgraded when left to their own devices.

There's an appeal to organizing site files as a cohesive whole. I just wonder whether this strategy is more manageable than a drush-and-other-stuff technique.

Posted on by Daniel Kudwien.

I'd recommend to use my (combined) fork instead, since the original is not maintained:

https://github.com/sun/git-s ubtree

I know it has been merged into git core, but dunno when that will actually be production ready. Need to check whether I can find time to contribute the improvements upstream.

Posted on by [Not Provided].

Hi Peter. Thanks for sharing this information. I will definitely try this out. We use github for all our projects and connect these repositories with Jenkins, Redmine and what not. We prefer not to switch over to your git repo's fully, so using this subtree setup might work for us.

Just wondering: how can we set-up several branches. Usually we use the master branche for production and the dev branch (or several of those) for continuous development. Can or will Acquia support several branches too?

Posted on by George Hazlewood.

git subtree is as of writing this no longer in homebrew as it has been merged into git proper. I am using 1.8.3.4 and git subtree is available without installation. Hope this saves someone else a search or two...

Posted on by Nikhil Dubbaka.

If you want to use a branch for subtree instead of master, I listed out the steps here http://nikhil.dubbaka.com/blogs/acquia/development-wo rkflow-github-acqui...

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Filtered HTML

  • Use [acphone_sales], [acphone_sales_text], [acphone_support], [acphone_international], [acphone_devcloud], [acphone_extra1] and [acphone_extra2] as placeholders for Acquia phone numbers. Add class "acquia-phones-link" to wrapper element to make number a link.
  • To post pieces of code, surround them with <code>...</code> tags. For PHP code, you can use <?php ... ?>, which will also colour it based on syntax.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <h4> <h5> <h2> <img>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.