diff --git a/src/applications/diffusion/controller/browse/DiffusionBrowseController.php b/src/applications/diffusion/controller/browse/DiffusionBrowseController.php index 11c4abf5a1..389929a1e0 100644 --- a/src/applications/diffusion/controller/browse/DiffusionBrowseController.php +++ b/src/applications/diffusion/controller/browse/DiffusionBrowseController.php @@ -42,10 +42,43 @@ class DiffusionBrowseController extends DiffusionController { $this->commit); $results = $browse_data->loadPaths(); + $content = array(); + if (!$results) { - // TODO: useful output (path does not exist / never existed), or file - // data. - throw new Exception("No browse results."); + + switch ($browse_data->getReasonForEmptyResultSet()) { + case DiffusionBrowseQuery::REASON_IS_NONEXISTENT: + $title = 'Path Does Not Exist'; + // TODO: Under git, this error message should be more specific. It + // may exist on some other branch. + $body = "This path does not exist anywhere."; + $severity = AphrontErrorView::SEVERITY_ERROR; + break; + case DiffusionBrowseQuery::REASON_IS_DELETED: + // TODO: Format all these commits into nice VCS-agnostic links. + $commit = $this->commit; + $deleted = $browse_data->getDeletedAtCommit(); + $existed = $browse_data->getExistedAtCommit(); + + $title = 'Path Was Deleted'; + $body = "This path does not exist at {$commit}. It was deleted in ". + "{$deleted} and last existed at {$existed}."; + $severity = AphrontErrorView::SEVERITY_WARNING; + break; + case DiffusionBrowseQuery::REASON_IS_FILE: + throw new Exception("TODO: implement this"); + break; + default: + throw new Exception("Unknown failure reason!"); + } + + $error_view = new AphrontErrorView(); + $error_view->setSeverity($severity); + $error_view->setTitle($title); + $error_view->appendChild('

'.$body.'

'); + + $content[] = $error_view; + } else { $browse_table = new DiffusionBrowseTableView(); $browse_table->setRepository($repository); @@ -57,6 +90,8 @@ class DiffusionBrowseController extends DiffusionController { $browse_panel->setHeader($this->path); $browse_panel->appendChild($browse_table); + $content[] = $browse_panel; + // TODO: Branch table } @@ -64,7 +99,7 @@ class DiffusionBrowseController extends DiffusionController { // TODO: Side nav return $this->buildStandardPageResponse( - $browse_panel, + $content, array( 'title' => basename($this->path), )); diff --git a/src/applications/diffusion/controller/browse/__init__.php b/src/applications/diffusion/controller/browse/__init__.php index 1335823c1d..faac6fe040 100644 --- a/src/applications/diffusion/controller/browse/__init__.php +++ b/src/applications/diffusion/controller/browse/__init__.php @@ -9,6 +9,7 @@ phutil_require_module('phabricator', 'applications/diffusion/controller/base'); phutil_require_module('phabricator', 'applications/diffusion/query/browse/base'); phutil_require_module('phabricator', 'applications/diffusion/view/browsetable'); +phutil_require_module('phabricator', 'view/form/error'); phutil_require_module('phabricator', 'view/layout/panel'); phutil_require_module('phutil', 'utils'); diff --git a/src/applications/diffusion/query/browse/base/DiffusionBrowseQuery.php b/src/applications/diffusion/query/browse/base/DiffusionBrowseQuery.php index e94d24e2d9..0a0c4ba567 100644 --- a/src/applications/diffusion/query/browse/base/DiffusionBrowseQuery.php +++ b/src/applications/diffusion/query/browse/base/DiffusionBrowseQuery.php @@ -23,9 +23,12 @@ abstract class DiffusionBrowseQuery { private $commit; protected $reason; + protected $existedAtCommit; + protected $deletedAtCommit; - const REASON_IS_FILE = 'is-file'; - const REASON_IS_NONEXISTENT = 'nonexistent'; + const REASON_IS_FILE = 'is-file'; + const REASON_IS_DELETED = 'is-deleted'; + const REASON_IS_NONEXISTENT = 'nonexistent'; final private function __construct() { // @@ -71,6 +74,14 @@ abstract class DiffusionBrowseQuery { return $this->reason; } + final public function getExistedAtCommit() { + return $this->existedAtCommit; + } + + final public function getDeletedAtCommit() { + return $this->deletedAtCommit; + } + final public function loadPaths() { return $this->executeQuery(); } diff --git a/src/applications/diffusion/query/browse/git/DiffusionGitBrowseQuery.php b/src/applications/diffusion/query/browse/git/DiffusionGitBrowseQuery.php index de3c8455ee..c68fe6bf55 100644 --- a/src/applications/diffusion/query/browse/git/DiffusionGitBrowseQuery.php +++ b/src/applications/diffusion/query/browse/git/DiffusionGitBrowseQuery.php @@ -36,6 +36,22 @@ final class DiffusionGitBrowseQuery extends DiffusionBrowseQuery { $path); } catch (CommandException $e) { if (preg_match('/^fatal: Not a valid object name/', $e->getStderr())) { + // Grab two logs, since the first one is when the object was deleted. + list($stdout) = execx( + '(cd %s && %s log -n2 --format="%%H" %s -- %s)', + $local_path, + $git, + $commit, + $path); + $stdout = trim($stdout); + if ($stdout) { + $commits = explode("\n", $stdout); + $this->reason = self::REASON_IS_DELETED; + $this->deletedAtCommit = idx($commits, 0); + $this->existedAtCommit = idx($commits, 1); + return array(); + } + $this->reason = self::REASON_IS_NONEXISTENT; return array(); } else {