Moving an Existing Drupal Git Repository into Acquia Dev Cloud without Losing History

Apr 10, 2012 8:49:00 AM Russell

UPDATE: Although this method works, there is a much simpler way to bring existing Git repositories into Dev Cloud without losing history. Check out the newer post about using git-subtree for more information. That post supersedes this one.

So after much investigation and deliberation, we decided as a shop to do our Drupal hosting on Acquia Dev Cloud. We’ve been working our way up the abstraction stack (first we got out of taking care of hardware, moving everything to hosted services or virtual private servers in the cloud), and luckily this takes us about as far as we can go. No more initial build-out of a new web server, and no more handling OS-level security upgrades. Woohoo! Now I can just focus on building cool sites.

One of the (many) reasons we settled on Dev Cloud was the workflow integration using Git. We’ve been using Git for a while now, so all of our existing Drupal sites already have histories in their respective repositories. Since we’ve already got everything in Git, I figured there would be a straightforward way to bring it into Dev Cloud, but it doesn’t appear to work that way. Luckily, since I knew exactly what I wanted, a lot of Googling and a little trial-and-error got us where we needed to be. Since I needed to document the process for myself, and since I didn’t find clear directions on how to do this anywhere else, I’m posting the process here, in hopes that it will help make other developers’ migration processes easier.

Getting Ready

After logging in at network.acquia.com and selecting one of your “subscriptions,” under Dev Cloud, click New site to add the site to import, then switch to the subscription for your newly added site.

Under Users and keys, add your SSH public key. Then back under Workflow, grab the “Git URL” and clone the repository on your local system.

git clone [git-url]

The new repository from Acquia seems to mostly be a series of directories that serve as placeholders. Unlike a standard Drupal installation, the actual files to run the site need to go in the docroot directory. This directory also starts out with a couple of dummy files that we won’t need, so we’ll just get rid of them.

cd [site-dir] git checkout master git rm -r docroot git commit -m "Removed default docroot." git push -u origin master

Now that we’ve got the cruft out, we need to move our existing site in, without losing the existing Git history. This is where Acquia’s fine documentation falls short, but we’ve got it covered.

We need to copy our existing codebase into the correct location in our site directory. Just make sure that you’re copying the base Drupal directory.

cp -R [old-dir] docroot

Rewriting Git’s History

Now comes the voodoo. While searching around to find how to merge in my existing Git history, I came across a question on Stack Overflow about something similar. The highest rated answer suggested using git-stitch-repo, but I gave up on getting all of the CPAN requirements working on my MacBook Pro. (It’s been a long, long time since I got started as a Perl programmer, and I don’t really want to go back.) Luckily, the next highest rated answer was right on the money, or at least reasonably close, and it seems that his answer was culled directly from the Git filter-branch man page.

In essence, what we need to do is to move our existing Drupal file structure into a subdirectory, and then rewrite the history so that it looks like it was always in that subdirectory. With a little tweaking of the example, here’s what we need to do.

cd docroot git status # This seems to avoid a caching problem after moving the repository. git filter-branch --index-filter \ 'git ls-files -s | sed "s-\t-&docroot/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ git update-index --index-info && mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD

NOTE: If you are doing this on a Mac (vs. Linux; sed isn’t going to work on Windows anyway), you need to replace the \t in the sed command with an actual tab character. Do this by hitting control-V, control-I. Don’t use the command key, and make sure that the second keystroke is the letter I, not a number 1 or a lower case L.

Now that we’ve got the files moved and the history fixed, we need to assemble everything together in our new Dev Cloud repository.

cd .. git pull docroot rm -rf docroot/docroot rm -rf docroot/.git

The Dev Cloud repo comes with its own .gitignore file in the top directory, so we don’t need or want the now redundant one that comes with Drupal.

git rm docroot/.gitignore

One of the reasons for this (oddly enough) is that we want to include the settings.php file in the repository for Dev Cloud, since Acquia has another way of dealing with the need for each site to have its own database connection definition. If you click on the Databases link under Dev Cloud, you’ll see a “require statement” that you need to add to the bottom of your settings.php file, so go ahead and copy it in, then we’ll commit everything (again).

git add docroot/sites/default/settings.php git commit -m "Import of existing repository." git push -u origin master

That, my friends, is how we get all of the workflow and performance goodness of Dev Cloud, while not having to toss out the history we’ve been so diligently keeping in Git. And in case any of you boys (or girls) over at Acquia are reading, you definitely have my permission to put this information, in any format you choose, in your Dev Cloud documentation. I don’t know how many other developers come to Dev Cloud with existing repos and history, but I imagine there are more than a few.

In my next post, I’ll go into a few of the tweaks I found to more easily sync a local development install with the Dev Cloud servers. I'll give you a hint: drush sql-sync is a beautiful thing.

Topics: Acquia Dev Cloud, Howto, git