Last updated November 26, 2011. Created by lordgilman on January 18, 2011.
Edited by danmuzyka, eliza411, webchick, Tor Arne Thune. Log in to edit this page.

//Let's see if we can roll this together with its parent.

Suppose you want to have your web server's document root and your Drupal core or contributed module's working tree be separate directories. This could be because you have your development and production sites or multiple, separate Drupal sites on the same server. For Drupal core all you need is git checkout-index -a -f --prefix=../path/to/site/ (don't forget the final slash!) to checkout the current index to your site's document root. However, this method breaks the update status for contributed modules: Drupal.org's packaging scripts normally add in version information for the update status module. A simple git checkout won't add this in and the Git deploy module won't work because the .git folder is not present in the document root[1].

Here's a Python script that will git checkout-index a module and add the proper version information. This script makes a few assumptions. If your setup does not match these assumptions you will need to modify the script.

  1. Your directory structure follows this pattern:
    .
    |-- drupal-site-1/
    |   |-- files/
    |   |-- includes/
    |   |-- misc/
    |   |-- modules/
    |   |-- ...
    |-- drupal-site-2/
    |   |-- files/
    |   |-- ...
    |-- drupal_repos/
    |   |-- cool_module_1/
    |   |-- cool_module_2/
    |   |-- ...
  2. The current working directory (pwd) is the module's Git repo and you've git checkout to the version you want to deploy.
  3. The name of the current working directory is the Drupal.org project name for the module. This is only invalid if you ran git clone with an extra argument (which you probably didn't).

#!/usr/bin/python
import subprocess
import os
import sys
import re
try:
   sitename = sys.argv[1]
except IndexError:
   print "I need the site's directory name as an argument."
   sys.exit()
# get all the info files in all subdirectories.
# they all need version info (and all use the same project name!)
module_regex = re.compile('(.*)\.info$')
info_files = []
dir_walker = os.walk(".")
for directory in dir_walker:
   for filename in directory[2]:
      match_object = module_regex.search(filename)
      if match_object:
         info_files.append([match_object.group(1), directory[0] + "/" + match_object.group(0)])
ps = subprocess.Popen(["git", "describe", "--tags"], stdout=subprocess.PIPE)
raw_tag = ps.communicate()[0].strip()
fields = raw_tag.split("-")
tag = fields[0] + "-" + fields[1]
ps = subprocess.Popen(["git", "remote", "show", "-n", "origin"], stdout=subprocess.PIPE)
remote_info = ps.communicate()[0]
project_name = re.search('.*Fetch URL:(.*).git\n.*', remote_info).group(1).split('/')[-1]
module_dir = os.path.basename(os.getcwd())
ps = subprocess.Popen(["git", "checkout-index", "-a", "-f", "--prefix=../../" + sitename + "/modules/" + module_dir + "/"])
ps.wait()
print "Git checkout completed!"
for info_file in info_files:
   ver_string = """
; added by post-checkout python script
version = "%s"
project = "%s" """ % (tag, project_name)
   fd = open("../../" + sitename + "/modules/" + module_dir + "/" + info_file[1], "a")
   fd.write(ver_string)
   fd.close()
   print "Checked out %s at version %s to %s." % (info_file[0], tag, sitename)

[1]: You can get the Git deploy module to work in a similar setup by using git clone --local /path/to/local/repo in your document root and using git pull to deploy new changes.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.