From 860ff0c9db3009826ab395da0189c66859ac9ea5 Mon Sep 17 00:00:00 2001
From: Marcel Partap <mpartap@gmx.net>
Date: Mon, 28 Nov 2011 15:55:09 +0100
Subject: [PATCH 2/2] Add caching so costly git parsing is not executed on
 every page load

---
 git_deploy.module |  118 ++++++++++++++++++++++++++++++----------------------
 1 files changed, 68 insertions(+), 50 deletions(-)

diff --git a/git_deploy.module b/git_deploy.module
index e35ff7c..4bfb7a6 100644
--- a/git_deploy.module
+++ b/git_deploy.module
@@ -19,68 +19,86 @@
  *   Can be module or theme.
  */
 function git_deploy_system_info_alter(&$info, $file, $type = NULL) {
+  $versiontag_cache = &drupal_static(__FUNCTION__);
+
   if (empty($info['version'])) {
     $directory = dirname($file->uri);
     // Check whether this belongs to core. Speed optimization.
     if (substr($directory, 0, strlen($type)) != $type) {
+      if (!isset($versiontag_cache)) {
+        if (($versiontag_cache = cache_get('git_deploy_versiontag_cache')) && $versiontag_cache->expire > REQUEST_TIME) {
+          $versiontag_cache = $versiontag_cache->data;
+        }
+        else {
+          $versiontag_cache = array();
+        }
+      }
       while ($directory && !file_exists("$directory/.git")) {
         $directory = substr($directory, 0,  strrpos($directory, '/'));
       }
-      $git_dir = "$directory/.git";
-      // Theoretically /.git could exist.
-      if ($directory && file_exists($git_dir)) {
-        $git = "git --git-dir $git_dir";
-        // Find first the project name based on fetch URL.
-        // Eat error messages. >& is valid on Windows, too. Also, $output does
-        // not need initialization because it's taken by reference.
-        exec("$git remote show -n origin 2>&1", $output);
-        if ($fetch_url = preg_grep('/^\s*Fetch URL:/', $output)) {
-          $fetch_url = current($fetch_url);
-          $project_name = substr($fetch_url, strrpos($fetch_url, '/') + 1);
-          if (substr($project_name, -4) == '.git') {
-            $project_name = substr($project_name, 0, -4);
-          }
-          $info['project'] = $project_name;
-        }
-        // Try to fill in branch and tag.
-        exec("$git rev-parse --abbrev-ref HEAD 2>&1", $branch);
-        $tag_found = FALSE;
-        if ($branch) {
-          $branch = $branch[0];
-          // Any Drupal-formatted branch.
-          $branch_preg =  '\d+\.x-\d+\.';
-          if (preg_match('/^' . $branch_preg . 'x$/', $branch)) {
-            $info['version'] = $branch . '-dev';
-            // Nail down the core and the major version now that we know
-            // what they are.
-            $branch_preg = preg_quote(substr($branch, 0, -1));
+      if (!isset($versiontag_cache[$directory])) {
+        $git_dir = "$directory/.git";
+        // Theoretically /.git could exist.
+        if ($directory && file_exists($git_dir)) {
+          $git_info = array();
+          $git = "git --git-dir $git_dir";
+          // Find first the project name based on fetch URL.
+          // Eat error messages. >& is valid on Windows, too. Also, $output does
+          // not need initialization because it's taken by reference.
+          exec("$git remote show -n origin 2>&1", $output);
+          if ($fetch_url = preg_grep('/^\s*Fetch URL:/', $output)) {
+            $fetch_url = current($fetch_url);
+            $project_name = substr($fetch_url, strrpos($fetch_url, '/') + 1);
+            if (substr($project_name, -4) == '.git') {
+              $project_name = substr($project_name, 0, -4);
+            }
+            $git_info['project'] = $project_name;
           }
-          // Now try to find a tag.
-          exec("$git rev-list --topo-order --max-count=1 HEAD 2>&1", $last_tag_hash);
-          if ($last_tag_hash) {
-            exec("$git describe  --tags $last_tag_hash[0] 2>&1", $last_tag);
-            if ($last_tag) {
-              $last_tag = $last_tag[0];
-              // Make sure the tag starts as Drupal formatted (for eg.
-              // 7.x-1.0-alpha1) and if we are on a proper branch (ie. not
-              // master) then it's on that branch.
-              if (preg_match('/^(' . $branch_preg . '\d+(?:-[^-]+)?)(-(\d+-)g[0-9a-f]{7})?$/', $last_tag, $matches)) {
-                $tag_found = TRUE;
-                $info['version'] = isset($matches[2]) ? $matches[1] . '.' . $matches[3] . 'dev' : $last_tag;
+          // Try to fill in branch and tag.
+          exec("$git rev-parse --abbrev-ref HEAD 2>&1", $branch);
+          $tag_found = FALSE;
+          if ($branch) {
+            $branch = $branch[0];
+            // Any Drupal-formatted branch.
+            $branch_preg =  '\d+\.x-\d+\.';
+            if (preg_match('/^' . $branch_preg . 'x$/', $branch)) {
+              $git_info['version'] = $branch . '-dev';
+              // Nail down the core and the major version now that we know
+              // what they are.
+              $branch_preg = preg_quote(substr($branch, 0, -1));
+            }
+            // Now try to find a tag.
+            exec("$git rev-list --topo-order --max-count=1 HEAD 2>&1", $last_tag_hash);
+            if ($last_tag_hash) {
+              exec("$git describe  --tags $last_tag_hash[0] 2>&1", $last_tag);
+              if ($last_tag) {
+                $last_tag = $last_tag[0];
+                // Make sure the tag starts as Drupal formatted (for eg.
+                // 7.x-1.0-alpha1) and if we are on a proper branch (ie. not
+                // master) then it's on that branch.
+                if (preg_match('/^(' . $branch_preg . '\d+(?:-[^-]+)?)(-(\d+-)g[0-9a-f]{7})?$/', $last_tag, $matches)) {
+                  $tag_found = TRUE;
+                  $git_info['version'] = isset($matches[2]) ? $matches[1] . '.' . $matches[3] . 'dev' : $last_tag;
+                }
               }
             }
           }
+          if (!$tag_found) {
+            $last_tag = '';
+          }
+          // The git log -1 command always succeeds and if we are not on a
+          // tag this will happen to return the time of the last commit which
+          // is exactly what we wanted.
+          exec("$git log -1 --pretty=format:%at $last_tag 2>&1", $datestamp);
+          if ($datestamp && is_numeric($datestamp[0])) {
+            $git_info['datestamp'] = $datestamp[0];
+          }
+          $versiontag_cache[$directory] = $git_info;
+          cache_set('git_deploy_versiontag_cache', $versiontag_cache, 'cache', REQUEST_TIME + 6*3600);
         }
-        if (!$tag_found) {
-          $last_tag = '';
-        }
-        // The git log -1 command always succeeds and if we are not on a
-        // tag this will happen to return the time of the last commit which
-        // is exactly what we wanted.
-        exec("$git log -1 --pretty=format:%at $last_tag 2>&1", $datestamp);
-        if ($datestamp && is_numeric($datestamp[0])) {
-          $info['datestamp'] = $datestamp[0];
-        }
+      }
+      foreach ($versiontag_cache[$directory] as $key => $value) {
+        $info[$key] = $value;
       }
     }
   }
-- 
1.7.8.rc3

