From 521d6f042c2bc2d64be3dcf4553048a1f3f60e12 Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Wed, 4 Feb 2009 23:41:30 -0700 Subject: [PATCH] More branching fixes. --- framework/Vcs/lib/Horde/Vcs.php | 32 +++------ framework/Vcs/lib/Horde/Vcs/Cvs.php | 35 +++++++++- framework/Vcs/lib/Horde/Vcs/Git.php | 131 +++++++++++++++++++++++++----------- 3 files changed, 135 insertions(+), 63 deletions(-) diff --git a/framework/Vcs/lib/Horde/Vcs.php b/framework/Vcs/lib/Horde/Vcs.php index 5db4dedc5..24d3b64c5 100644 --- a/framework/Vcs/lib/Horde/Vcs.php +++ b/framework/Vcs/lib/Horde/Vcs.php @@ -780,7 +780,15 @@ abstract class Horde_Vcs_Directory */ public function _fileRevSort($a, $b) { - return $this->_rep->cmp($a->queryHead(), $b->queryHead()); + return $this->_rep->cmp($a->queryRevision(), $b->queryRevision()); + } + + /** + * TODO + */ + public function getBranches() + { + return array(); } } @@ -820,11 +828,6 @@ abstract class Horde_Vcs_File /** * TODO */ - protected $_branches = array(); - - /** - * TODO - */ protected $_quicklog; /** @@ -833,11 +836,6 @@ abstract class Horde_Vcs_File protected $_branch; /** - * TODO - */ - protected $_head = null; - - /** * Create a repository file object, and give it information about * what its parent directory and repository objects are. * @@ -919,16 +917,6 @@ abstract class Horde_Vcs_File : null; } - /** - * Return the HEAD (most recent) revision number for this file. - * - * @return string HEAD revision string. - */ - public function queryHead() - { - return is_null($this->_head) ? $this->queryRevision() : $this->_head; - } - /** * Return the last Horde_Vcs_Log object in the file. * @@ -1025,7 +1013,7 @@ abstract class Horde_Vcs_File */ public function queryBranches() { - return $this->_branches; + return array(); } /** diff --git a/framework/Vcs/lib/Horde/Vcs/Cvs.php b/framework/Vcs/lib/Horde/Vcs/Cvs.php index 8a824dc6c..28d2a0db9 100644 --- a/framework/Vcs/lib/Horde/Vcs/Cvs.php +++ b/framework/Vcs/lib/Horde/Vcs/Cvs.php @@ -326,6 +326,14 @@ class Horde_Vcs_Directory_Cvs extends Horde_Vcs_Directory return true; } + /** + * TODO + */ + public function getBranches() + { + return array('HEAD'); + } + } /** @@ -339,25 +347,40 @@ class Horde_Vcs_File_Cvs extends Horde_Vcs_File { /** * TODO + * + * @var string */ protected $_accum; /** * TODO + * + * @var array */ protected $_revsym = array(); /** * TODO + * + * @var array */ protected $_symrev = array(); /** + * TODO + * * @var array */ protected $_revlist = array(); /** + * TODO + * + * @var array + */ + protected $_branches = array(); + + /** * Create a repository file object, and give it information about * what its parent directory and repository objects are. * @@ -392,8 +415,8 @@ class Horde_Vcs_File_Cvs extends Horde_Vcs_File switch ($state) { case 'init': if (strpos($line, 'head: ') === 0) { - $this->_head = $this->_branches['HEAD'] = substr($line, 6); - $this->_revlist['HEAD'] = $rep->getRevisionRange($this, '1.1', $this->_head); + $this->_branches['HEAD'] = substr($line, 6); + $this->_revlist['HEAD'] = $rep->getRevisionRange($this, '1.1', $this->_branches['HEAD']); } elseif (strpos($line, 'branch:') === 0) { $state = 'rev'; } @@ -543,6 +566,14 @@ class Horde_Vcs_File_Cvs extends Horde_Vcs_File return $this->_accum; } + /** + * TODO + */ + public function queryBranches() + { + return $this->_branches; + } + } /** diff --git a/framework/Vcs/lib/Horde/Vcs/Git.php b/framework/Vcs/lib/Horde/Vcs/Git.php index c78dbb067..eaa34c123 100644 --- a/framework/Vcs/lib/Horde/Vcs/Git.php +++ b/framework/Vcs/lib/Horde/Vcs/Git.php @@ -48,6 +48,13 @@ class Horde_Vcs_Git extends Horde_Vcs protected $_diffTypes = array('unified'); /** + * The list of branches for the repo. + * + * @var array + */ + protected $_branchlist; + + /** * TODO */ public function isValidRevision($rev) @@ -239,6 +246,21 @@ class Horde_Vcs_Git extends Horde_Vcs return substr($rev, 0, 7) . '[...]'; } + public function getBranchList() + { + if (!isset($this->_branchlist)) { + $branch_list = array(); + exec($this->getCommand() . ' show-ref --heads', $branch_list); + + foreach ($branch_list as $val) { + $line = explode(' ', trim($val), 2); + $this->_branchlist[substr($line[1], strrpos($line[1], '/') + 1)] = $line[0]; + } + } + + return $this->_branchlist; + } + } /** @@ -266,7 +288,7 @@ class Horde_Vcs_Directory_Git extends Horde_Vcs_Directory $branch = empty($opts['rev']) ? 'master' : $opts['rev']; - // @TODO can use this to see if we have a valid cache of the tree at this revision + // @TODO See if we have a valid cache of the tree at this revision $dir = $this->queryDir(); if (substr($dir, 0, 1) == '/') { @@ -286,8 +308,7 @@ class Horde_Vcs_Directory_Git extends Horde_Vcs_Directory // Create two arrays - one of all the files, and the other of // all the dirs. while (!feof($stream)) { - $line = chop(fgets($stream, 1024)); - print "$line\n"; + $line = rtrim(fgets($stream, 1024)); if (!strlen($line)) { continue; } @@ -296,13 +317,21 @@ class Horde_Vcs_Directory_Git extends Horde_Vcs_Directory if ($type == 'tree') { $this->_dirs[] = basename($file); } else { - $this->_files[] = $rep->getFileObject($file, array('quicklog' => !empty($opts['quicklog']))); + $this->_files[] = $rep->getFileObject($file, array('branch' => $branch, 'quicklog' => !empty($opts['quicklog']))); } } pclose($stream); } + /** + * TODO + */ + public function getBranches() + { + return array_keys($this->_rep->getBranchList()); + } + } /** @@ -333,52 +362,46 @@ class Horde_Vcs_File_Git extends Horde_Vcs_File { parent::__construct($rep, $fl, $opts); - $branch_list = $revs = $tmp = array(); - - /* Add branch information. */ - $cmd = $rep->getCommand() . ' show-ref --heads'; - exec($cmd, $branch_list); - - foreach ($branch_list as $val) { - $line = explode(' ', trim($val), 2); - $this->_branches[substr($line[1], strrpos($line[1], '/') + 1)] = $line[0]; - } + $log_list = null; + $revs = array(); - /* Get the list of revisions. Need to get all revisions, not just - * those on $this->_branch, for branch determination reasons. */ - $cmd = $rep->getCommand() . ' rev-list --branches --parents -- ' . escapeshellarg($this->queryModulePath()) . ' 2>&1'; + $cmd = $rep->getCommand() . ' rev-list --branches -- ' . escapeshellarg($this->queryModulePath()) . ' 2>&1'; exec($cmd, $revs); if (stripos($revs[0], 'fatal') === 0) { throw new Horde_Vcs_Exception($revs); } + $this->_revs = $revs; - /* $revs format: revision parent */ - foreach ($revs as $val) { - $line = explode(' ', trim($val), 2); - $this->_revs[] = $line[0]; - - if (isset($tmp[$line[0]])) { - foreach ($tmp[$line[0]] as $val2) { - $this->_revlist[$val2][] = $line[0]; + /* Get the list of revisions. Need to get all revisions, not just + * those on $this->_branch, for branch determination reasons. */ + foreach (array_keys($rep->getBranchList()) as $key) { + $revs = array(); + $cmd = $rep->getCommand() . ' rev-list ' . escapeshellarg($key) . ' -- ' . escapeshellarg($this->queryModulePath()) . ' 2>&1'; + exec($cmd, $revs); + + if (!empty($revs)) { + if (stripos($revs[0], 'fatal') === 0) { + throw new Horde_Vcs_Exception($revs); } - } else { - $branch = array_search($line[0], $this->_branches); - $this->_revlist[$branch] = array($line[0]); - $tmp[$line[0]] = array($branch); - } - if (isset($line[1])) { - if (!isset($tmp[$line[1]])) { - $tmp[$line[1]] = array(); + $this->_revlist[$key] = $revs; + + if (!empty($this->_branch) && ($this->_branch == $key)) { + $log_list = $this->_quicklog + ? array(reset($revs)) + : $revs; } - $tmp[$line[1]] = array_merge($tmp[$line[1]], $tmp[$line[0]]); } + } - if ((!$this->_quicklog || empty($this->_logs)) && - (empty($this->_branch) || - in_array($this->_branch, $tmp[$line[0]]))) { - $this->_logs[$line[0]] = $rep->getLogObject($this, $line[0]); - } + if (is_null($log_list)) { + $log_list = $this->_quicklog + ? array(reset($this->_revs)) + : (empty($this->_branch) ? $this->_revs : array()); + } + + foreach ($log_list as $val) { + $this->_logs[$val] = $rep->getLogObject($this, $val); } } @@ -441,6 +464,36 @@ class Horde_Vcs_File_Git extends Horde_Vcs_File return $this->queryModulePath(); } + /** + * TODO + */ + public function queryBranches() + { + return $this->_rep->getBranchList(); + } + + /** + * Return the last Horde_Vcs_Log object in the file. + * + * @return Horde_Vcs_Log Log object of the last entry in the file. + * @throws Horde_Vcs_Exception + */ + public function queryLastLog() + { + if (empty($this->_branch)) { + return parent::queryLastLog(); + } + + $rev = reset($this->_revlist[$this->_branch]); + if (!is_null($rev)) { + if (isset($this->_logs[$rev])) { + return $this->_logs[$rev]; + } + } + + throw new Horde_Vcs_Exception('No revisions'); + } + } /** -- 2.11.0