filename); $git_dir = $module_dir . DIRECTORY_SEPARATOR . '.git'; /* short-circuit if this module/theme needs no help */ if (!empty($info['version']) && !empty($info['project'])) { return; } /* this module/theme is not our type */ if (!file_exists($git_dir)) { return; } if (empty($info['version'])) { $git_hash = git_deploy_hash_find($git_dir, 'HEAD'); $git_refs = git_deploy_refs_find($git_dir, $git_hash, array('tags')); if (count($git_refs)) { foreach ($git_refs as $git_ref) { $ref_components = split('/', $git_ref, 3); if (count($ref_components) == 3) { $git_tag = $ref_components[2]; break; } } } if (!empty($git_tag)) { $version = $git_tag; } else { /* support master users */ $version = 'HEAD'; } $info['version'] = $version; } if (empty($info['project'])) { $git_config_file = $git_dir . DIRECTORY_SEPARATOR . 'config'; if (file_exists($git_config_file)) { $git_config = file_get_contents($git_config_file); if (preg_match(';^\s*url\s*=\s*.*?([^/.]+?)(\.git)?\s*$;m', $git_config, $matches)) { $project = $matches[1]; } } if (!empty($project)) { $info['project'] = $project; } } } /** * Turn a git ref into a git commit hash. * * @param $git_dir * The path to the .git/ directory * @param $ref * The ref to parse * @return * NULL on error or the referenced hash. */ function git_deploy_hash_find($git_dir, $ref) { /* check if we have the hash */ if (strpos($ref, ':') === FALSE) { /* found the hash? maybe not, but we'll still return it */ if (strlen($ref) == 40) { return $ref; } /* perhaps we're dealing with a $ref like HEAD */ if (file_exists($git_dir . DIRECTORY_SEPARATOR . $ref)) { return git_deploy_hash_find($git_dir, trim(file_get_contents($git_dir . DIRECTORY_SEPARATOR . $ref))); } } list($type, $name) = explode(':', $ref, 2); $name = trim($name); switch ($type) { case 'ref': return git_deploy_hash_find($git_dir, trim(file_get_contents($git_dir . DIRECTORY_SEPARATOR . $name))); /* I have yet to find other derefernce methods/schemes */ } return NULL; } /** * Map a GIT commit hash onto a ref. * * @param $git_dir * The path to the .git/ diretory. * @param $hash * The hash whose ref to find. * @param $types * The types of ref to find. For example: array('tags'), array('heads'), or array('heads', 'tags') * * @return * An array of the fully-qualified refs. For example: array('refs/tags/6.x-2.1', 'refs/tags/DRUPAL-6--2-1'); */ function git_deploy_refs_find($git_dir, $hash, $types = NULL) { $fetch_all_types = FALSE; $refs = array(); $refs_dir = $git_dir . DIRECTORY_SEPARATOR . 'refs'; $hash = trim($hash); if (empty($types)) { $types = scandir($refs_dir); $fetch_all_types = TRUE; } foreach ($types as $subdir) { $type = $subdir; $subdir = $refs_dir . DIRECTORY_SEPARATOR . $subdir; if (!is_dir($subdir)) { continue; } foreach (scandir($subdir) as $ref) { $ref_hash = trim(file_get_contents($subdir . DIRECTORY_SEPARATOR . $ref)); if ($ref_hash == $hash) { /* reconstruct fully-qualified ref */ $refs[] = 'refs/' . $type . '/' . $ref; } } } $git_packed_refs_file = $git_dir . DIRECTORY_SEPARATOR . 'packed-refs'; if (file_exists($git_packed_refs_file)) { $packed_refs = explode("\n", file_get_contents($git_packed_refs_file)); foreach ($packed_refs as $packed_ref) { $packed_ref = trim($packed_ref); if (empty($packed_ref) || $packed_ref[0] == '#') { continue; } list($packed_hash, $ref) = explode(' ', $packed_ref, 2); if (trim($packed_hash) != $hash) { continue; } /* * if $types was set by the caller, ensure that we only unpack * the right types of refs. */ if (!$fetch_all_types) { $ref_components = explode('/', $ref); if (count($ref_components > 1) && !in_array($ref_components[1], $types)) { /* bad type of ref, try the next one */ continue; } } $refs[] = $ref; } } return $refs; }