Last active
June 20, 2019 03:08
-
-
Save indrakaw/8eedd1ffce4d6046e81f5f8f72ad0370 to your computer and use it in GitHub Desktop.
A collection of function for git hash checking in PHP. Pure PHP, no command exec() required.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Git Helper | |
* | |
* This file contains set of functions that returns git's metadata. | |
* It doesn't perform git operation; read then pharse only. | |
* | |
* LIMITATION: this function only read local object (branch, tag). | |
* You have to fetch remote object first (eg. `git fetch --all`). | |
* Best use on shared web hosting and enviorment with exploitable | |
* funtions disabled: shell_exec(), exec(), eval(), system(), etc. | |
* | |
* $git_root param is relative to frontend file (index.php). | |
* eg. "is_git('.');" will check the dir of index.php. | |
* | |
* Set $git_root param to NULL, it will use APPPATH. | |
* | |
* @author Indra Kurniawan <[email protected]> | |
* @copyright 2019 Indra Kurniawan | |
* @version 1.0.0 | |
*/ | |
// This's a helper of designed for CodeIgniter. If you are having problem | |
// accesing it, you should comment out or remove a line bellow. | |
defined('BASEPATH') or exit('No direct script access allowed'); | |
/** | |
* Determinte is application is run undergit. | |
* | |
* @param string $git_root | |
* @param boolean $check_parent | |
* @return boolean|string FALSE or path to path to HEAD file | |
*/ | |
function is_git($git_root = NULL, $check_parent = FALSE) | |
{ | |
if (is_null($git_root)) { | |
if (defined(APPPATH)) { | |
// This's a helper of CodeIgniter, so... | |
$git_root = APPPATH; | |
} else { | |
$git_root = '.'; | |
} | |
} | |
if (file_exists($head_path = $git_root . '/.git/HEAD')) { | |
return $head_path; | |
} | |
if ($check_parent && (file_exists($head_path = $git_root . '/../.git/HEAD'))) { | |
return $head_path; | |
} | |
return FALSE; | |
} | |
/** | |
* Return referenced path of HEAD | |
* | |
* @param string $git_root | |
* @param boolean $check_parent | |
* @return boolean|string FALSE or ref path string | |
*/ | |
function git_ref($git_root = NULL, $check_parent = FALSE) | |
{ | |
// Is valid? | |
if (($head_path = is_git($git_root, $check_parent)) === FALSE) { | |
return FALSE; | |
} | |
// Does HEAD contain ref? | |
if (strpos($head_content = @file_get_contents($head_path), 'ref:') === 0) { | |
$head_ref = trim(str_replace('ref:', '', trim($head_content))); | |
return sprintf(dirname($head_path).'/%s', $head_ref); | |
} | |
return FALSE; | |
} | |
/** | |
* Check whatever the HEAD file refer to a branch or not. | |
* This implies git_ref(); | |
* | |
* @param string $git_root | |
* @param boolean $check_parent | |
* @return boolean|string FALSE or path to branch's name | |
*/ | |
function git_branch($git_root = NULL, $check_parent = FALSE) | |
{ | |
// Validate git then return HEAD's ref. | |
if (($ref_head = git_ref($git_root, $check_parent)) === FALSE) { | |
return FALSE; | |
} | |
// Does ref contain branch path? | |
if (strpos($ref_head, '.git/refs/heads/') !== FALSE) { | |
return $ref_head; | |
} | |
return FALSE; | |
} | |
/** | |
* Check whatever the HEAD file refer to a tag or not. | |
* This implies git_ref(); | |
* | |
* @param string $git_root | |
* @param boolean $check_parent | |
* @return boolean|string FALSE or path to tag's name | |
*/ | |
function git_tag($git_root = NULL, $check_parent = FALSE) | |
{ | |
// Validate git then return HEAD's ref. | |
if (($ref_head = git_ref($git_root, $check_parent)) === FALSE) { | |
return FALSE; | |
} | |
// Does ref contain tag path? | |
if (strpos($ref_head, '.git/refs/tags/') !== FALSE) { | |
return $ref_head; | |
} | |
return FALSE; | |
} | |
/** | |
* Return hash of HEAD file | |
* | |
* @param string $git_root | |
* @param boolean $check_parent | |
* @return boolean|string FALSE or HEAD's hash | |
*/ | |
function git_hash($git_root = NULL, $check_parent = FALSE) | |
{ | |
// Is head a ref? | |
if ($head_ref = git_ref($git_root, $check_parent)) { | |
return trim(@file_get_contents($head_ref)); | |
} | |
// Assume HEAD contains the hash. | |
if ($head_path = is_git($git_root, $check_parent)) { | |
return trim(@file_get_contents($head_path)); | |
} | |
// Maybe it isn't a git. | |
return FALSE; | |
} | |
/** | |
* Return the refferenced branch (or tag) of HEAD's hash. | |
* Best use for `git checkout <branch>` instead of ugly hash. | |
* | |
* @param string $git_root | |
* @param boolean $check_parent | |
* @return boolean|string FALSE or head's ref (branch or tag) name | |
*/ | |
function git_head($git_root = NULL, $check_parent = FALSE) | |
{ | |
// Is head a ref? | |
if ($head_ref = git_ref($git_root, $check_parent)) { | |
return basename($head_ref); | |
} | |
// Lookup for refs by HEAD's hash. | |
if (!$head_path = is_git($git_root, $check_parent)) { | |
return FALSE; | |
} | |
// Let's see which branch or tags has this hash (no pun needed)/ | |
$object_list = array(); | |
$object_list = glob(dirname($head_path) . '/refs/{heads,tags}/*', GLOB_BRACE); | |
// A repo basically has a branch, if isn't then it's an empty repo (has no commit) | |
if (empty($object_list)) { | |
return FALSE; | |
} | |
// Looping throught array of files within read its contents isn't that slow. | |
// They are branches and tags files, a popular git repo usually has around 60 of them. | |
$hash = trim(@file_get_contents(trim($head_path))); | |
foreach ($object_list as $file) { | |
if ((trim(@file_get_contents(trim($file)))) === $hash) { | |
// return only first found | |
return basename($file); | |
} | |
} | |
// Maybe it isn't a git or hash has no refs | |
return FALSE; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Example file | |
* | |
* Run this example script by command-line interface (no web-server required): | |
* $ cd path/to/this/file/ | |
* $ php ./procedural_example.php | |
*/ | |
// Define BASEPATH (required, for to prevent direct access). | |
define('BASEPATH', ''); | |
// Load the helper | |
require_once 'git_helper.php'; | |
// Set repo is on curent dir relatively to this file (procedural_example.php) | |
// You might set this to magic constants __DIR__, etc. | |
$path = '.'; | |
// No need to check the parent | |
$check_parent = FALSE; | |
var_dump($path); | |
var_dump($check_parent); | |
echo '=================' . PHP_EOL; | |
echo 'is_get: '; | |
var_dump(is_git($path, $check_parent)); | |
echo 'head\'s content: '; | |
var_dump(@file_get_contents(is_git($path, $check_parent))); | |
echo '=================' . PHP_EOL; | |
echo 'git_branch: '; | |
var_dump(git_branch($path, $check_parent)); | |
echo 'git_tag: '; | |
var_dump(git_tag($path, $check_parent)); | |
echo 'git_hash: '; | |
var_dump(git_hash($path, $check_parent)); | |
echo 'git_ref: '; | |
var_dump(git_ref($path, $check_parent)); | |
// EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment