/**
  * PopulateProjects
  *
  * Populates the internal list of projects
  *
  * @access protected
  * @throws Exception if file cannot be read
  */
 protected function PopulateProjects()
 {
     if (!($fp = fopen($this->projectConfig, 'r'))) {
         throw new Exception(sprintf(__('Failed to open project list file %1$s'), $this->projectConfig));
     }
     $projectRoot = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('projectroot'));
     while (!feof($fp) && ($line = fgets($fp))) {
         if (preg_match('/^([^\\s]+)(\\s.+)?$/', $line, $regs)) {
             if (is_file($projectRoot . $regs[1] . '/HEAD')) {
                 try {
                     $projObj = new GitPHP_Project($projectRoot, $regs[1]);
                     if (isset($regs[2]) && !empty($regs[2])) {
                         $projOwner = trim($regs[2]);
                         if (!empty($projOwner)) {
                             $projObj->SetOwner($projOwner);
                         }
                     }
                     $this->projects[$regs[1]] = $projObj;
                 } catch (Exception $e) {
                     GitPHP_Log::GetInstance()->Log($e->getMessage());
                 }
             } else {
                 GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not a git project', $projectRoot . $regs[1]));
             }
         }
     }
     fclose($fp);
 }
 public function testLoadHead()
 {
     $strategy = new GitPHP_ProjectLoad_Raw($this->getMockBuilder('GitPHP_GitObjectLoader')->disableOriginalConstructor()->getMock());
     $project = new GitPHP_Project(GITPHP_TEST_PROJECTROOT, 'testrepo.git');
     $headlistmock = $this->getMock('GitPHP_HeadList', array('Exists', 'GetHead'), array($project, $this->getMock('GitPHP_HeadListLoadStrategy_Interface')));
     $headmock = $this->getMock('GitPHP_Head', array('GetHash'), array($project, 'master'));
     $headmock->expects($this->any())->method('GetHash')->will($this->returnValue('1234567890abcdef1234567890ABCDEF12345678'));
     $headlistmock->expects($this->any())->method('Exists')->with($this->equalTo('master'))->will($this->returnValue(true));
     $headlistmock->expects($this->any())->method('GetHead')->with($this->equalTo('master'))->will($this->returnValue($headmock));
     $project->SetHeadList($headlistmock);
     $this->assertEquals('1234567890abcdef1234567890ABCDEF12345678', $strategy->LoadHead($project));
     $project = new GitPHP_Project(GITPHP_TEST_PROJECTROOT, 'testrepoexported.git');
     $this->assertEquals('1234567890abcdef1234567890ABCDEF12345678', $strategy->LoadHead($project));
 }
 /**
  * Gets the matching object
  *
  * @return GitPHP_Tree|GitPHP_Blob|null matching object
  */
 public function GetObject()
 {
     if ($this->objectType == 'tree') {
         $tree = $this->project->GetObjectManager()->GetTree($this->objectHash);
         $tree->SetPath($this->path);
         return $tree;
     } else {
         if ($this->objectType == 'blob') {
             $blob = $this->project->GetObjectManager()->GetBlob($this->objectHash);
             $blob->SetPath($this->path);
             return $blob;
         }
     }
     return null;
 }
Exemple #4
0
 /**
  * Instantiates object
  *
  * @param GitPHP_Project $project the project
  * @param string $hash pack hash
  * @param GitPHP_GitObjectLoader object loader
  */
 public function __construct($project, $hash, $objectLoader)
 {
     if (!$project) {
         throw new Exception('Project is required');
     }
     if (!preg_match('/[0-9A-Fa-f]{40}/', $hash)) {
         throw new GitPHP_InvalidHashException($hash);
     }
     if (!$objectLoader) {
         throw new Exception('Object loader is required');
     }
     $this->hash = $hash;
     $this->packIndex = new GitPHP_PackIndex($project->GetPath() . '/objects/pack/pack-' . $hash . '.idx');
     $this->packData = new GitPHP_PackData($project->GetPath() . '/objects/pack/pack-' . $hash . '.pack', $objectLoader);
 }
Exemple #5
0
 /**
  * Searches file contents for matches
  */
 private function SearchFileContents()
 {
     $args = array();
     $args[] = '-I';
     $args[] = '--full-name';
     $args[] = '--ignore-case';
     $args[] = '-n';
     $args[] = '-e';
     $args[] = '"' . addslashes($this->search) . '"';
     $args[] = $this->treeHash;
     $lines = explode("\n", $this->exe->Execute($this->project->GetPath(), GIT_GREP, $args));
     foreach ($lines as $line) {
         if (preg_match('/^[^:]+:([^:]+):([0-9]+):(.+)$/', $line, $regs)) {
             if (isset($this->allResults[$regs[1]])) {
                 $result = $this->allResults[$regs[1]];
                 $matchingLines = $result->GetMatchingLines();
                 $matchingLines[(int) $regs[2]] = trim($regs[3], "\n\r\v");
                 $result->SetMatchingLines($matchingLines);
             } else {
                 $tree = $this->GetTree();
                 $hash = $tree->PathToHash($regs[1]);
                 if ($hash) {
                     $blob = $this->project->GetObjectManager()->GetBlob($hash);
                     $blob->SetPath($regs[1]);
                     $result = new GitPHP_FileSearchResult($this->project, $blob, $regs[1]);
                     $matchingLines = array();
                     $matchingLines[(int) $regs[2]] = trim($regs[3], "\n\r\v");
                     $result->SetMatchingLines($matchingLines);
                     $this->allResults[$regs[1]] = $result;
                 }
             }
         }
     }
 }
Exemple #6
0
 /**
  * Returns the current revision
  *
  * @return GitPHP_Commit
  */
 function current()
 {
     if (!$this->dataLoaded) {
         $this->LoadData();
     }
     return $this->project->GetCommit(current($this->hashList));
 }
 /**
  * Execute rev-list command
  *
  * @param GitPHP_Project $project project
  * @param string $hash hash to look back from
  * @param int $count number to return (0 for all)
  * @param int $skip number of items to skip
  * @param array $args extra arguments
  */
 public function RevList($project, $hash, $count, $skip = 0, $args = array())
 {
     if (!$project || empty($hash)) {
         return;
     }
     $canSkip = true;
     if ($skip > 0) {
         $canSkip = $this->exe->CanSkip();
     }
     $extraargs = array();
     if ($canSkip) {
         if ($count > 0) {
             $extraargs[] = '--max-count=' . $count;
         }
         if ($skip > 0) {
             $extraargs[] = '--skip=' . $skip;
         }
     } else {
         if ($count > 0) {
             $extraargs[] = '--max-count=' . ($count + $skip);
         }
     }
     $extraargs[] = $hash;
     if (count($args) > 0) {
         $endarg = array_search('--', $args);
         if ($endarg !== false) {
             array_splice($args, $endarg, 0, $extraargs);
         } else {
             $args = array_merge($args, $extraargs);
         }
     } else {
         $args = $extraargs;
     }
     $revlist = explode("\n", $this->exe->Execute($project->GetPath(), GIT_REV_LIST, $args));
     if (!$revlist[count($revlist) - 1]) {
         /* the last newline creates a null entry */
         array_splice($revlist, -1, 1);
     }
     if ($skip > 0 && !$canSkip) {
         if ($count > 0) {
             return array_slice($revlist, $skip, $count);
         } else {
             return array_slice($revlist, $skip);
         }
     }
     return $revlist;
 }
 /**
  * PopulateProjects
  *
  * Populates the internal list of projects
  *
  * @access protected
  * @throws Exception if file cannot be read
  */
 protected function PopulateProjects()
 {
     $projectRoot = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('projectroot'));
     $use_errors = libxml_use_internal_errors(true);
     $xml = simplexml_load_file($this->projectConfig);
     libxml_clear_errors();
     libxml_use_internal_errors($use_errors);
     if (!$xml) {
         throw new Exception(sprintf('Could not load SCM manager config %1$s', $this->projectConfig));
     }
     foreach ($xml->repositories->repository as $repository) {
         if ($repository->type != 'git') {
             GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not a git project', $repository->name));
             continue;
         }
         if ($repository->public != 'true') {
             GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not public', $repository->name));
             continue;
         }
         $projName = trim($repository->name);
         if (empty($projName)) {
             continue;
         }
         if (is_file($projectRoot . $projName . '/HEAD')) {
             try {
                 $projObj = new GitPHP_Project($projectRoot, $projName);
                 $projOwner = trim($repository->contact);
                 if (!empty($projOwner)) {
                     $projObj->SetOwner($projOwner);
                 }
                 $projDesc = trim($repository->description);
                 if (!empty($projDesc)) {
                     $projObj->SetDescription($projDesc);
                 }
                 $this->projects[$projName] = $projObj;
             } catch (Exception $e) {
                 GitPHP_Log::GetInstance()->Log($e->getMessage());
             }
         } else {
             GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not a git project', $projName));
         }
     }
 }
 /**
  * PopulateProjects
  *
  * Populates the internal list of projects
  *
  * @access protected
  * @throws Exception if file cannot be read
  */
 protected function PopulateProjects()
 {
     $projectRoot = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('projectroot'));
     foreach ($this->projectConfig as $cat => $plist) {
         if (is_array($plist)) {
             foreach ($plist as $pname => $ppath) {
                 try {
                     $projObj = new GitPHP_Project($projectRoot, $ppath);
                     if ($cat != GITPHP_NO_CATEGORY) {
                         $projObj->SetCategory($cat);
                     }
                     $this->projects[$ppath] = $projObj;
                 } catch (Exception $e) {
                     GitPHP_Log::GetInstance()->Log($e->getMessage());
                 }
             }
         }
     }
 }
Exemple #10
0
 /**
  * Loads the history data
  */
 protected function LoadData()
 {
     $this->dataLoaded = true;
     $args = array();
     $args[] = $this->hash;
     $args[] = '--no-merges';
     $canSkip = true;
     if ($this->skip > 0) {
         $canSkip = $this->exe->CanSkip();
     }
     if ($canSkip) {
         if ($this->limit > 0) {
             $args[] = '--max-count=' . $this->limit;
         }
         if ($this->skip > 0) {
             $args[] = '--skip=' . $this->skip;
         }
     } else {
         if ($this->limit > 0) {
             $args[] = '--max-count=' . ($this->limit + $this->skip);
         }
     }
     $args[] = '--';
     $args[] = $this->path;
     $args[] = '|';
     $args[] = $this->exe->GetBinary();
     $args[] = '--git-dir=' . escapeshellarg($this->project->GetPath());
     $args[] = GIT_DIFF_TREE;
     $args[] = '-r';
     $args[] = '--stdin';
     $args[] = '--';
     $args[] = $this->path;
     $historylines = explode("\n", $this->exe->Execute($this->project->GetPath(), GIT_REV_LIST, $args));
     $commitHash = null;
     foreach ($historylines as $line) {
         if (preg_match('/^([0-9a-fA-F]{40})/', $line, $regs)) {
             $commitHash = $regs[1];
         } else {
             if ($commitHash) {
                 try {
                     $this->history[] = array('diffline' => $line, 'commithash' => $commitHash);
                 } catch (Exception $e) {
                 }
                 $commitHash = null;
             }
         }
     }
     if ($this->skip > 0 && !$canSkip) {
         if ($this->limit > 0) {
             $this->history = array_slice($this->history, $this->skip, $this->limit);
         } else {
             $this->history = array_slice($this->history, $this->skip);
         }
     }
 }
Exemple #11
0
 /**
  * Constructor
  *
  * @param GitPHP_Project $project project
  * @param GitPHP_GitExe $exe executable
  * @param string $toHash to commit hash
  * @param string $fromHash from commit hash
  * @param boolean $renames whether to detect file renames
  */
 public function __construct($project, $exe, $toHash, $fromHash = '', $renames = false)
 {
     if (!$project) {
         throw new Exception('Project is required');
     }
     $this->project = $project;
     if (!$exe) {
         throw new Exception('Git executable is required');
     }
     $this->exe = $exe;
     $toCommit = $project->GetCommit($toHash);
     $this->toHash = $toHash;
     if (empty($fromHash)) {
         $parent = $toCommit->GetParent();
         if ($parent) {
             $this->fromHash = $parent->GetHash();
         }
     } else {
         $this->fromHash = $fromHash;
     }
     $this->renames = $renames;
 }
Exemple #12
0
 /**
  * Loads the blame data
  */
 private function LoadData()
 {
     $this->dataLoaded = true;
     $args = array();
     $args[] = '-s';
     $args[] = '-l';
     $args[] = $this->commitHash;
     $args[] = '--';
     $args[] = $this->path;
     $blamelines = explode("\n", $this->exe->Execute($this->project->GetPath(), GIT_BLAME, $args));
     $lastcommit = '';
     foreach ($blamelines as $line) {
         if (preg_match('/^([0-9a-fA-F]{40})(\\s+.+)?\\s+([0-9]+)\\)/', $line, $regs)) {
             if ($regs[1] != $lastcommit) {
                 $this->blame[(int) $regs[3]] = $regs[1];
                 $lastcommit = $regs[1];
             }
         }
     }
 }
 /**
  * Gets a file diff
  *
  * @param string $fromHash source hash, can also be a diff-tree info line
  * @param string $toHash target hash, required if $fromHash is a hash
  * @return GitPHP_FileDiff file diff object
  */
 public function GetFileDiff($fromHash, $toHash = '')
 {
     if (preg_match('/^[0-9A-Fa-f]{4,39}$/', $fromHash) && !$this->compat) {
         $fullHash = $this->project->ExpandHash($fromHash);
         if ($fullHash == $fromHash) {
             throw new GitPHP_InvalidHashException($fromHash);
         }
         $fromHash = $fullHash;
     }
     if (!empty($toHash) && preg_match('/^[0-9A-Fa-f]{4,39}$/', $toHash) && !$this->compat) {
         $fullHash = $this->project->ExpandHash($toHash);
         if ($fullHash == $toHash) {
             throw new GitPHP_InvalidHashException($toHash);
         }
         $toHash = $fullHash;
     }
     $fileDiff = new GitPHP_FileDiff($this->project, $fromHash, $toHash);
     $fileDiff->SetCache($this->cache);
     return $fileDiff;
 }
 /**
  * Finds loose hash files matching a given prefix
  *
  * @param string $prefix hash prefix
  * @return string[] array of hashes
  */
 private function FindHashObjects($prefix)
 {
     $matches = array();
     if (empty($prefix)) {
         return $matches;
     }
     $subdir = substr($prefix, 0, 2);
     $fulldir = $this->project->GetPath() . '/objects/' . $subdir;
     if (!is_dir($fulldir)) {
         return $matches;
     }
     $prefixlen = strlen($prefix);
     $dh = opendir($fulldir);
     if ($dh !== false) {
         while (($file = readdir($dh)) !== false) {
             $fullhash = $subdir . $file;
             if (substr_compare($fullhash, $prefix, 0, $prefixlen) === 0) {
                 $matches[] = $fullhash;
             }
         }
     }
     return $matches;
 }
Exemple #15
0
 /**
  * Gets a project identifier for a project
  *
  * @param string|GitPHP_Project $value string or project
  * @return string identifier
  */
 private static function GetProject($value)
 {
     if ($value instanceof GitPHP_Project) {
         return $value->GetProject();
     } else {
         if (is_string($value)) {
             return $value;
         }
     }
 }
 /**
  * AddProject
  *
  * Add project to collection
  *
  * @access private
  */
 private function AddProject($projectPath)
 {
     try {
         $proj = new GitPHP_Project($this->projectDir, $projectPath);
         $category = trim(dirname($projectPath));
         if (!(empty($category) || strpos($category, '.') === 0)) {
             $proj->SetCategory($category);
         }
         if (!GitPHP_Config::GetInstance()->GetValue('exportedonly', false) || $proj->GetDaemonEnabled()) {
             $this->projects[$projectPath] = $proj;
         }
     } catch (Exception $e) {
         GitPHP_Log::GetInstance()->Log($e->getMessage());
     }
 }
 /**
  * Applies override settings for a project
  *
  * @param GitPHP_Project $project the project object
  * @param array $projData project data array
  */
 protected function ApplyProjectSettings($project, $projData)
 {
     if (!$project) {
         return;
     }
     if (isset($projData['category']) && is_string($projData['category'])) {
         $project->SetCategory($projData['category']);
     }
     if (isset($projData['owner']) && is_string($projData['owner'])) {
         $project->SetOwner($projData['owner']);
     }
     if (isset($projData['description']) && is_string($projData['description'])) {
         $project->SetDescription($projData['description']);
     }
     if (isset($projData['cloneurl']) && is_string($projData['cloneurl'])) {
         $project->SetCloneUrl($projData['cloneurl']);
     }
     if (isset($projData['pushurl']) && is_string($projData['pushurl'])) {
         $project->SetPushUrl($projData['pushurl']);
     }
     if (isset($projData['bugpattern']) && is_string($projData['bugpattern'])) {
         $project->SetBugPattern($projData['bugpattern']);
     }
     if (isset($projData['bugurl']) && is_string($projData['bugurl'])) {
         $project->SetBugUrl($projData['bugurl']);
     }
     if (isset($projData['compat'])) {
         $project->SetCompat($projData['compat']);
     }
     if (isset($projData['website']) && is_string($projData['website'])) {
         $project->SetWebsite($projData['website']);
     }
     if (!empty($projData['allowedusers'])) {
         $project->SetAllowedUsers($projData['allowedusers']);
     }
 }
 /**
  * Loads a project
  *
  * @param string $proj project
  * @return GitPHP_Project project
  */
 protected function LoadProject($proj)
 {
     try {
         $project = new GitPHP_Project($this->projectRoot, $proj);
         $category = trim(dirname($proj));
         if (!(empty($category) || strpos($category, '.') === 0)) {
             $project->SetCategory($category);
         }
         if ($this->exportedOnly && !$project->GetDaemonEnabled()) {
             $this->Log('Project export disabled', $project->GetPath());
             return null;
         }
         $this->ApplyGlobalConfig($project);
         $this->ApplyGitConfig($project);
         if ($this->projectSettings && isset($this->projectSettings[$proj])) {
             $this->ApplyProjectSettings($project, $this->projectSettings[$proj]);
         }
         $this->InjectProjectDependencies($project);
         return $project;
     } catch (Exception $e) {
         $this->Log('Project error', $e->getMessage());
     }
     return null;
 }
Exemple #19
0
 /**
  * Compares two projects by age
  *
  * @param GitPHP_Project $a first project
  * @param GitPHP_Project $b second project
  * @return integer comparison result
  */
 public static function CompareAge($a, $b)
 {
     $catCmp = strcmp($a->GetCategory(), $b->GetCategory());
     if ($catCmp !== 0) {
         return $catCmp;
     }
     if ($a->GetAge() === $b->GetAge()) {
         return 0;
     }
     return $a->GetAge() < $b->GetAge() ? -1 : 1;
 }
Exemple #20
0
 public function testCompareAge()
 {
     $strategymock = $this->getMock('GitPHP_ProjectLoadStrategy_Interface');
     $strategymock->expects($this->once())->method('LoadEpoch')->with($this->isInstanceOf('GitPHP_Project'))->will($this->returnValue('2'));
     $project = new GitPHP_Project(GITPHP_TEST_PROJECTROOT, 'testrepoexported.git', $strategymock);
     $strategymock2 = $this->getMock('GitPHP_ProjectLoadStrategy_Interface');
     $strategymock2->expects($this->once())->method('LoadEpoch')->with($this->isInstanceOf('GitPHP_Project'))->will($this->returnValue('1'));
     $project2 = new GitPHP_Project(GITPHP_TEST_PROJECTROOT, 'testrepo.git', $strategymock2);
     $this->assertEquals(0, GitPHP_Project::CompareAge($project, $project));
     $this->assertLessThan(0, GitPHP_Project::CompareAge($project, $project2));
     $this->assertGreaterThan(0, GitPHP_Project::CompareAge($project2, $project));
     $project->SetCategory('b');
     $this->assertEquals(0, GitPHP_Project::CompareAge($project, $project));
     $this->assertGreaterThan(0, GitPHP_Project::CompareAge($project, $project2));
     $this->assertLessThan(0, GitPHP_Project::CompareAge($project2, $project));
     $project2->SetCategory('a');
     $this->assertEquals(0, GitPHP_Project::CompareAge($project, $project));
     $this->assertGreaterThan(0, GitPHP_Project::CompareAge($project, $project2));
     $this->assertLessThan(0, GitPHP_Project::CompareAge($project2, $project));
 }
Exemple #21
0
 /**
  * Get diff data
  *
  * @param integer $context number of context lines
  * @param boolean $header true to include file header
  * @param string $file override file name
  * @return string diff data
  */
 private function GetDiffData($context = 3, $header = true, $file = null)
 {
     $fromData = '';
     $toData = '';
     if (empty($this->status) || $this->status == 'M' || $this->status == 'D') {
         $fromBlob = $this->GetFromBlob();
         $fromData = $fromBlob->GetData(false);
     }
     if (empty($this->status) || $this->status == 'M' || $this->status == 'A') {
         $toBlob = $this->GetToBlob();
         $toData = $toBlob->GetData(false);
     }
     $output = '';
     if ($header) {
         $output = '--- ' . $this->GetFromLabel($file) . "\n" . '+++ ' . $this->GetToLabel($file) . "\n";
     }
     $diffOutput = false;
     $cacheKey = null;
     if ($this->cache) {
         $cacheKey = 'project|' . $this->project->GetProject() . '|diff|' . $context . '|' . $this->fromHash . '|' . $this->toHash;
         $diffOutput = $this->cache->Get($cacheKey);
     }
     if ($diffOutput === false) {
         if ($this->UseXDiff()) {
             $diffOutput = $this->GetXDiff($fromData, $toData, $context);
         } else {
             $diffOutput = $this->GetPhpDiff($fromData, $toData, $context);
         }
         if ($this->cache) {
             $this->cache->Set($cacheKey, $diffOutput);
         }
     }
     $output .= $diffOutput;
     return $output;
 }
 /**
  * Abbreviate a hash
  *
  * @param GitPHP_Project $project project
  * @param string $hash hash to abbreviate
  * @return string abbreviated hash
  */
 public function AbbreviateHash($project, $hash)
 {
     if (!$project) {
         return $hash;
     }
     if (!preg_match('/[0-9A-Fa-f]{40}/', $hash)) {
         return $hash;
     }
     $args = array();
     $args[] = '-1';
     $args[] = '--format=format:%h';
     $args[] = $hash;
     $abbrevData = explode("\n", $this->exe->Execute($project->GetPath(), GIT_REV_LIST, $args));
     if (empty($abbrevData[0])) {
         return $hash;
     }
     if (substr_compare(trim($abbrevData[0]), 'commit', 0, 6) !== 0) {
         return $hash;
     }
     if (empty($abbrevData[1])) {
         return $hash;
     }
     return trim($abbrevData[1]);
 }
 /**
  * Abbreviate a hash
  *
  * @param GitPHP_Project $project project
  * @param string $hash hash to abbreviate
  * @return string abbreviated hash
  */
 public function AbbreviateHash($project, $hash)
 {
     if (!$project) {
         return $hash;
     }
     if (!preg_match('/[0-9A-Fa-f]{40}/', $hash)) {
         return $hash;
     }
     $abbrevLen = GitPHP_ProjectLoad_Raw::HashAbbreviateLength;
     $projAbbrevLen = $project->GetAbbreviateLength();
     if ($projAbbrevLen > 0) {
         $abbrevLen = max(4, min($projAbbrevLen, 40));
     }
     $prefix = substr($hash, 0, $abbrevLen);
     if (!$project->GetUniqueAbbreviation()) {
         return $prefix;
     }
     return $this->objectLoader->EnsureUniqueHash($hash, $prefix);
 }