MediaWiki
REL1_23
|
00001 <?php 00026 class GitInfo { 00027 00031 protected static $repo = null; 00032 00036 protected $basedir; 00037 00041 private static $viewers = false; 00042 00046 public function __construct( $dir ) { 00047 $this->basedir = $dir . DIRECTORY_SEPARATOR . '.git'; 00048 if ( is_readable( $this->basedir ) && !is_dir( $this->basedir ) ) { 00049 $GITfile = file_get_contents( $this->basedir ); 00050 if ( strlen( $GITfile ) > 8 && substr( $GITfile, 0, 8 ) === 'gitdir: ' ) { 00051 $path = rtrim( substr( $GITfile, 8 ), "\r\n" ); 00052 $isAbsolute = $path[0] === '/' || substr( $path, 1, 1 ) === ':'; 00053 $this->basedir = $isAbsolute ? $path : $dir . DIRECTORY_SEPARATOR . $path; 00054 } 00055 } 00056 } 00057 00062 public static function repo() { 00063 global $IP; 00064 if ( is_null( self::$repo ) ) { 00065 self::$repo = new self( $IP ); 00066 } 00067 return self::$repo; 00068 } 00069 00076 public static function isSHA1( $str ) { 00077 return !!preg_match( '/^[0-9A-F]{40}$/i', $str ); 00078 } 00079 00084 public function getHead() { 00085 $headFile = "{$this->basedir}/HEAD"; 00086 00087 if ( !is_readable( $headFile ) ) { 00088 return false; 00089 } 00090 00091 $head = file_get_contents( $headFile ); 00092 00093 if ( preg_match( "/ref: (.*)/", $head, $m ) ) { 00094 return rtrim( $m[1] ); 00095 } else { 00096 return rtrim( $head ); 00097 } 00098 } 00099 00104 public function getHeadSHA1() { 00105 $head = $this->getHead(); 00106 00107 // If detached HEAD may be a SHA1 00108 if ( self::isSHA1( $head ) ) { 00109 return $head; 00110 } 00111 00112 // If not a SHA1 it may be a ref: 00113 $refFile = "{$this->basedir}/{$head}"; 00114 if ( !is_readable( $refFile ) ) { 00115 return false; 00116 } 00117 00118 $sha1 = rtrim( file_get_contents( $refFile ) ); 00119 00120 return $sha1; 00121 } 00122 00129 public function getHeadCommitDate() { 00130 global $wgGitBin; 00131 00132 if ( !is_file( $wgGitBin ) || !is_executable( $wgGitBin ) ) { 00133 return false; 00134 } 00135 00136 $environment = array( "GIT_DIR" => $this->basedir ); 00137 $cmd = wfEscapeShellArg( $wgGitBin ) . " show -s --format=format:%ct HEAD"; 00138 $retc = false; 00139 $commitDate = wfShellExec( $cmd, $retc, $environment ); 00140 00141 if ( $retc !== 0 ) { 00142 return false; 00143 } else { 00144 return (int)$commitDate; 00145 } 00146 } 00147 00152 public function getCurrentBranch() { 00153 $head = $this->getHead(); 00154 if ( $head && preg_match( "#^refs/heads/(.*)$#", $head, $m ) ) { 00155 return $m[1]; 00156 } else { 00157 return $head; 00158 } 00159 } 00160 00166 public function getHeadViewUrl() { 00167 $config = "{$this->basedir}/config"; 00168 if ( !is_readable( $config ) ) { 00169 return false; 00170 } 00171 00172 wfSuppressWarnings(); 00173 $configArray = parse_ini_file( $config, true ); 00174 wfRestoreWarnings(); 00175 $remote = false; 00176 00177 // Use the "origin" remote repo if available or any other repo if not. 00178 if ( isset( $configArray['remote origin'] ) ) { 00179 $remote = $configArray['remote origin']; 00180 } elseif ( is_array( $configArray ) ) { 00181 foreach ( $configArray as $sectionName => $sectionConf ) { 00182 if ( substr( $sectionName, 0, 6 ) == 'remote' ) { 00183 $remote = $sectionConf; 00184 } 00185 } 00186 } 00187 00188 if ( $remote === false || !isset( $remote['url'] ) ) { 00189 return false; 00190 } 00191 00192 $url = $remote['url']; 00193 if ( substr( $url, -4 ) !== '.git' ) { 00194 $url .= '.git'; 00195 } 00196 foreach ( self::getViewers() as $repo => $viewer ) { 00197 $pattern = '#^' . $repo . '$#'; 00198 if ( preg_match( $pattern, $url, $matches ) ) { 00199 $viewerUrl = preg_replace( $pattern, $viewer, $url ); 00200 $headSHA1 = $this->getHeadSHA1(); 00201 $replacements = array( 00202 '%h' => substr( $headSHA1, 0, 7 ), 00203 '%H' => $headSHA1, 00204 '%r' => urlencode( $matches[1] ), 00205 ); 00206 return strtr( $viewerUrl, $replacements ); 00207 } 00208 } 00209 return false; 00210 } 00211 00216 public static function headSHA1() { 00217 return self::repo()->getHeadSHA1(); 00218 } 00219 00224 public static function currentBranch() { 00225 return self::repo()->getCurrentBranch(); 00226 } 00227 00232 public static function headViewUrl() { 00233 return self::repo()->getHeadViewUrl(); 00234 } 00235 00240 protected static function getViewers() { 00241 global $wgGitRepositoryViewers; 00242 00243 if ( self::$viewers === false ) { 00244 self::$viewers = $wgGitRepositoryViewers; 00245 wfRunHooks( 'GitViewers', array( &self::$viewers ) ); 00246 } 00247 00248 return self::$viewers; 00249 } 00250 }