Issue 112: Missing git information for some files (final fix)
This commit is contained in:
parent
1fdddf2501
commit
3f699e0afd
29
indefero/src/IDF/Migrations/33GitCache.php
Normal file
29
indefero/src/IDF/Migrations/33GitCache.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
function IDF_Migrations_32ExternalFile_up()
|
||||
{
|
||||
$table = Pluf::factory('IDF_Scm_Cache_Git')->getSqlTable();
|
||||
|
||||
$sql = array();
|
||||
|
||||
$sql["MySQL"] = "ALTER TABLE " . $table . " CHANGE COLUMN `githash` TEXT NOT NULL DEFAULT '' AFTER `project`;";
|
||||
|
||||
$db = Pluf::db();
|
||||
$engine = Pluf::f('db_engine');
|
||||
|
||||
$db->execute($sql[$engine]);
|
||||
}
|
||||
|
||||
function IDF_Migrations_32ExternalFile_down()
|
||||
{
|
||||
$table = Pluf::factory('IDF_Scm_Cache_Git')->getSqlTable();
|
||||
|
||||
$sql = array();
|
||||
|
||||
$sql["MySQL"] = "ALTER TABLE " . $table . " CHANGE COLUMN `githash` VARCHAR(40) NOT NULL AFTER `project`;";
|
||||
|
||||
$db = Pluf::db();
|
||||
$engine = Pluf::f('db_engine');
|
||||
|
||||
$db->execute($sql[$engine]);
|
||||
}
|
@ -50,10 +50,10 @@ class IDF_Scm_Cache_Git extends Pluf_Model
|
||||
*/
|
||||
public function store($infos)
|
||||
{
|
||||
foreach ($infos as $blob) {
|
||||
foreach ($infos as $key => $blob) {
|
||||
$cache = new IDF_Scm_Cache_Git();
|
||||
$cache->project = $this->_project;
|
||||
$cache->githash = $blob->hash;
|
||||
$cache->githash = $key;
|
||||
$blob->title = IDF_Commit::toUTF8($blob->title);
|
||||
$cache->content = IDF_Commit::toUTF8($blob->date) . chr(31)
|
||||
. IDF_Commit::toUTF8($blob->author) . chr(31)
|
||||
@ -123,9 +123,8 @@ class IDF_Scm_Cache_Git extends Pluf_Model
|
||||
),
|
||||
'githash' =>
|
||||
array(
|
||||
'type' => 'Pluf_DB_Field_Varchar',
|
||||
'type' => 'Pluf_DB_Field_Text',
|
||||
'blank' => false,
|
||||
'size' => 40,
|
||||
'index' => true,
|
||||
),
|
||||
'content' =>
|
||||
|
@ -343,7 +343,7 @@ class IDF_Scm_Git extends IDF_Scm
|
||||
$res[] = $file;
|
||||
}
|
||||
// Grab the details for each blob and return the list.
|
||||
return $this->getTreeDetails($res);
|
||||
return $this->getTreeDetails($res, $commit);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -718,13 +718,13 @@ class IDF_Scm_Git extends IDF_Scm
|
||||
* @param array Tree information
|
||||
* @return array Updated tree information
|
||||
*/
|
||||
public function getTreeDetails($tree)
|
||||
public function getTreeDetails($tree, $commit)
|
||||
{
|
||||
$n = count($tree);
|
||||
$details = array();
|
||||
for ($i=0;$i<$n;$i++) {
|
||||
if ($tree[$i]->type == 'blob') {
|
||||
$details[sha1($tree[$i]->hash . $tree[$i]->fullpath)] = $i;
|
||||
$details[sha1($tree[$i]->hash . $tree[$i]->fullpath) . ":" . $tree[$i]->hash . ":" . $tree[$i]->fullpath] = $i;
|
||||
}
|
||||
}
|
||||
if (!count($details)) {
|
||||
@ -742,7 +742,7 @@ class IDF_Scm_Git extends IDF_Scm
|
||||
}
|
||||
}
|
||||
if (count($toapp)) {
|
||||
$res = $this->appendBlobInfoCache($toapp);
|
||||
$res = $this->appendBlobInfoCache($toapp, $commit);
|
||||
foreach ($details as $blob => $idx) {
|
||||
if (isset($res[$blob])) {
|
||||
$tree[$idx]->date = $res[$blob]->date;
|
||||
@ -766,62 +766,110 @@ class IDF_Scm_Git extends IDF_Scm
|
||||
* @param array The blob for which we need the information
|
||||
* @return array The information
|
||||
*/
|
||||
public function appendBlobInfoCache($blobs)
|
||||
public function appendBlobInfoCache($blobs, $commit)
|
||||
{
|
||||
$rawlog = array();
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '')
|
||||
.sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log --raw --abbrev=40 --pretty=oneline -5000 --skip=%%s',
|
||||
escapeshellarg($this->repo));
|
||||
.sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log --raw --abbrev=40 --pretty=oneline -5000 --skip=%%s %s',
|
||||
escapeshellarg($this->repo), $commit);
|
||||
$skip = 0;
|
||||
$res = array();
|
||||
self::exec('IDF_Scm_Git::appendBlobInfoCache',
|
||||
sprintf($cmd, $skip), $rawlog);
|
||||
while (count($rawlog) and count($blobs)) {
|
||||
|
||||
$fileinfoarr = [];
|
||||
$lookup = [];
|
||||
$cache = [];
|
||||
|
||||
$currentcommit = null;
|
||||
|
||||
$rawlog = implode("\n", array_reverse($rawlog));
|
||||
$tmpRes = [];
|
||||
foreach(explode("\n", $rawlog) as $line) {
|
||||
if ($line[0] != ":") { //This is the commit number line
|
||||
$commit = explode(" ", $line)[0];
|
||||
$fc = $this->getCommit($commit);
|
||||
foreach($tmpRes as $r) {
|
||||
$res[$r["hash"]] = (object) [
|
||||
"hash" => $r["hash"],
|
||||
"date" => $fc->date,
|
||||
"title" => $fc->title,
|
||||
"author" => $fc->author
|
||||
if ($line[0] == ":") {
|
||||
$matches = preg_split('/\s/', $line);
|
||||
$currentFileHash = $matches[3];
|
||||
$file = $matches[5];
|
||||
$fileinfoarr[] = [
|
||||
"filehash" => $currentFileHash,
|
||||
"file" => $file
|
||||
];
|
||||
}
|
||||
$tmpRes = [];
|
||||
} else {
|
||||
$sides = explode("\t", $line);
|
||||
$leftSide = trim($sides[0]);
|
||||
$rightSide = trim($sides[1]);
|
||||
$leftSideSplit = explode(" ", $leftSide);
|
||||
$newHash = sha1($leftSideSplit[3] . $rightSide);
|
||||
$tmpRes[$newHash] = [
|
||||
"hash" => $newHash
|
||||
$matches = preg_split('/\s/', $line);
|
||||
$currentcommit = $matches[0];
|
||||
if ($fileinfoarr) {
|
||||
$lookup[$currentcommit] = $fileinfoarr;
|
||||
$fileinfoarr = [];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$commitData = $this->getCommit($commit);
|
||||
foreach($blobs as $blobKey => $blobVal) {
|
||||
list($newhash, $hash, $file) = explode(":", $blobKey);
|
||||
if (isset($lookup[$commitData->commit])) {
|
||||
$test = $lookup[$commitData->commit];
|
||||
} else {
|
||||
if (isset($lookup[$commitData->parents[0]])) { //tag?
|
||||
$test = $lookup[$commitData->parents[0]];
|
||||
} else {
|
||||
$test = [];
|
||||
}
|
||||
}
|
||||
$found = false;
|
||||
foreach($test as $fileinfo) {
|
||||
if ($fileinfo["filehash"] == $hash && $fileinfo["file"] == $file) {
|
||||
$found = true;
|
||||
$res[$blobKey] = (object) [
|
||||
"hash" => $newhash,
|
||||
"date" => $commitData->date,
|
||||
"title" => $commitData->title,
|
||||
"author" => $commitData->author
|
||||
];
|
||||
unset($blobs[$newHash]);
|
||||
$cache[$blobKey] = $res[$blobKey];
|
||||
}
|
||||
}
|
||||
$rawlog = array();
|
||||
$skip += 5000;
|
||||
if ($skip > 20000) {
|
||||
// We are in the case of the import of a big old
|
||||
// repository, we can store as unknown the commit info
|
||||
// not to try to retrieve them each time.
|
||||
foreach ($blobs as $blob => $idx) {
|
||||
$res[$blob] = (object) array('hash' => $blob,
|
||||
'date' => '0',
|
||||
'title' => '----',
|
||||
'author' => 'Unknown');
|
||||
}
|
||||
if (!$found) {
|
||||
foreach ($lookup as $key=>$val) {
|
||||
foreach($val as $fileinfo) {
|
||||
if ($fileinfo["filehash"] == $hash && $fileinfo["file"] == $file) {
|
||||
$commitTempData = $this->getCommit($key);
|
||||
$res[$blobKey] = (object) [
|
||||
"hash" => $newhash,
|
||||
"date" => $commitTempData->date,
|
||||
"title" => $commitTempData->title,
|
||||
"author" => $commitTempData->author
|
||||
];
|
||||
$cache[$blobKey] = $res[$blobKey];
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
self::exec('IDF_Scm_Git::appendBlobInfoCache',
|
||||
sprintf($cmd, $skip), $rawlog);
|
||||
}
|
||||
$this->cacheBlobInfo($res);
|
||||
}
|
||||
}
|
||||
// If it's still not found - find the first commit where it's modified and use that
|
||||
if (!$found) {
|
||||
foreach ($lookup as $key=>$val) {
|
||||
foreach($val as $fileinfo) {
|
||||
if ($fileinfo["file"] == $file) {
|
||||
$commitTempData = $this->getCommit($key);
|
||||
$res[$blobKey] = (object) [
|
||||
"hash" => $newhash,
|
||||
"date" => $commitTempData->date,
|
||||
"title" => $commitTempData->title,
|
||||
"author" => $commitTempData->author
|
||||
];
|
||||
$cache[$blobKey] = $res[$blobKey];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->cacheBlobInfo($cache);
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user