private function handleHovercardEvent($event)
 {
     $viewer = $event->getUser();
     $hovercard = $event->getValue('hovercard');
     $object_handle = $event->getValue('handle');
     $commit = $event->getValue('object');
     if (!$commit instanceof PhabricatorRepositoryCommit) {
         return;
     }
     $commit_data = $commit->loadCommitData();
     $revision = PhabricatorEdgeQuery::loadDestinationPHIDs($commit->getPHID(), PhabricatorEdgeConfig::TYPE_COMMIT_HAS_DREV);
     $revision = reset($revision);
     $author = $commit->getAuthorPHID();
     $phids = array_filter(array($revision, $author));
     $handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($phids)->execute();
     if ($author) {
         $author = $handles[$author]->renderLink();
     } else {
         $author = phutil_tag('em', array(), $commit_data->getAuthorName());
     }
     $hovercard->setTitle($object_handle->getName());
     $hovercard->setDetail($commit->getSummary());
     $hovercard->addField(pht('Author'), $author);
     $hovercard->addField(pht('Date'), phabricator_date($commit->getEpoch(), $viewer));
     if ($commit->getAuditStatus() != PhabricatorAuditCommitStatusConstants::NONE) {
         $hovercard->addField(pht('Audit Status'), PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()));
     }
     if ($revision) {
         $rev_handle = $handles[$revision];
         $hovercard->addField(pht('Revision'), $rev_handle->renderLink());
     }
     $event->setValue('hovercard', $hovercard);
 }
 public function renderHovercard(PhabricatorHovercardView $hovercard, PhabricatorObjectHandle $handle, $commit, $data)
 {
     $viewer = $this->getViewer();
     $author_phid = $commit->getAuthorPHID();
     if ($author_phid) {
         $author = $viewer->renderHandle($author_phid);
     } else {
         $commit_data = $commit->loadCommitData();
         $author = phutil_tag('em', array(), $commit_data->getAuthorName());
     }
     $hovercard->setTitle($handle->getName());
     $hovercard->setDetail($commit->getSummary());
     $hovercard->addField(pht('Author'), $author);
     $hovercard->addField(pht('Date'), phabricator_date($commit->getEpoch(), $viewer));
     if ($commit->getAuditStatus() != PhabricatorAuditCommitStatusConstants::NONE) {
         $hovercard->addField(pht('Audit Status'), PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()));
     }
 }
 public function render()
 {
     $rows = array();
     foreach ($this->commits as $commit) {
         $commit_name = $this->getHandle($commit->getPHID())->renderLink();
         $author_name = null;
         if ($commit->getAuthorPHID()) {
             $author_name = $this->getHandle($commit->getAuthorPHID())->renderLink();
         }
         $rows[] = array($commit_name, $author_name, phutil_escape_html($commit->getCommitData()->getSummary()), PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()), phabricator_datetime($commit->getEpoch(), $this->user));
     }
     $table = new AphrontTableView($rows);
     $table->setHeaders(array('Commit', 'Author', 'Summary', 'Audit Status', 'Date'));
     $table->setColumnClasses(array('n', '', 'wide', '', ''));
     if ($this->noDataString) {
         $table->setNoDataString($this->noDataString);
     }
     return $table->render();
 }
 private function loadCommitProperties(PhabricatorRepositoryCommit $commit, PhabricatorRepositoryCommitData $data, array $parents, array $audit_requests)
 {
     assert_instances_of($parents, 'PhabricatorRepositoryCommit');
     $viewer = $this->getRequest()->getUser();
     $commit_phid = $commit->getPHID();
     $drequest = $this->getDiffusionRequest();
     $repository = $drequest->getRepository();
     $edge_query = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($commit_phid))->withEdgeTypes(array(DiffusionCommitHasTaskEdgeType::EDGECONST, DiffusionCommitHasRevisionEdgeType::EDGECONST, DiffusionCommitRevertsCommitEdgeType::EDGECONST, DiffusionCommitRevertedByCommitEdgeType::EDGECONST));
     $edges = $edge_query->execute();
     $task_phids = array_keys($edges[$commit_phid][DiffusionCommitHasTaskEdgeType::EDGECONST]);
     $revision_phid = key($edges[$commit_phid][DiffusionCommitHasRevisionEdgeType::EDGECONST]);
     $reverts_phids = array_keys($edges[$commit_phid][DiffusionCommitRevertsCommitEdgeType::EDGECONST]);
     $reverted_by_phids = array_keys($edges[$commit_phid][DiffusionCommitRevertedByCommitEdgeType::EDGECONST]);
     $phids = $edge_query->getDestinationPHIDs(array($commit_phid));
     if ($data->getCommitDetail('authorPHID')) {
         $phids[] = $data->getCommitDetail('authorPHID');
     }
     if ($data->getCommitDetail('reviewerPHID')) {
         $phids[] = $data->getCommitDetail('reviewerPHID');
     }
     if ($data->getCommitDetail('committerPHID')) {
         $phids[] = $data->getCommitDetail('committerPHID');
     }
     if ($parents) {
         foreach ($parents as $parent) {
             $phids[] = $parent->getPHID();
         }
     }
     // NOTE: We should never normally have more than a single push log, but
     // it can occur naturally if a commit is pushed, then the branch it was
     // on is deleted, then the commit is pushed again (or through other similar
     // chains of events). This should be rare, but does not indicate a bug
     // or data issue.
     // NOTE: We never query push logs in SVN because the commiter is always
     // the pusher and the commit time is always the push time; the push log
     // is redundant and we save a query by skipping it.
     $push_logs = array();
     if ($repository->isHosted() && !$repository->isSVN()) {
         $push_logs = id(new PhabricatorRepositoryPushLogQuery())->setViewer($viewer)->withRepositoryPHIDs(array($repository->getPHID()))->withNewRefs(array($commit->getCommitIdentifier()))->withRefTypes(array(PhabricatorRepositoryPushLog::REFTYPE_COMMIT))->execute();
         foreach ($push_logs as $log) {
             $phids[] = $log->getPusherPHID();
         }
     }
     $handles = array();
     if ($phids) {
         $handles = $this->loadViewerHandles($phids);
     }
     $props = array();
     if ($commit->getAuditStatus()) {
         $status = PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus());
         $tag = id(new PHUITagView())->setType(PHUITagView::TYPE_STATE)->setName($status);
         switch ($commit->getAuditStatus()) {
             case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT:
                 $tag->setBackgroundColor(PHUITagView::COLOR_ORANGE);
                 break;
             case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED:
                 $tag->setBackgroundColor(PHUITagView::COLOR_RED);
                 break;
             case PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED:
                 $tag->setBackgroundColor(PHUITagView::COLOR_BLUE);
                 break;
             case PhabricatorAuditCommitStatusConstants::FULLY_AUDITED:
                 $tag->setBackgroundColor(PHUITagView::COLOR_GREEN);
                 break;
         }
         $props['Status'] = $tag;
     }
     if ($audit_requests) {
         $user_requests = array();
         $other_requests = array();
         foreach ($audit_requests as $audit_request) {
             if ($audit_request->isUser()) {
                 $user_requests[] = $audit_request;
             } else {
                 $other_requests[] = $audit_request;
             }
         }
         if ($user_requests) {
             $props['Auditors'] = $this->renderAuditStatusView($user_requests);
         }
         if ($other_requests) {
             $props['Project/Package Auditors'] = $this->renderAuditStatusView($other_requests);
         }
     }
     $author_phid = $data->getCommitDetail('authorPHID');
     $author_name = $data->getAuthorName();
     if (!$repository->isSVN()) {
         $authored_info = id(new PHUIStatusItemView());
         // TODO: In Git, a distinct authorship date is available. When present,
         // we should show it here.
         if ($author_phid) {
             $authored_info->setTarget($handles[$author_phid]->renderLink());
         } else {
             if (strlen($author_name)) {
                 $authored_info->setTarget($author_name);
             }
         }
         $props['Authored'] = id(new PHUIStatusListView())->addItem($authored_info);
     }
     $committed_info = id(new PHUIStatusItemView())->setNote(phabricator_datetime($commit->getEpoch(), $viewer));
     $committer_phid = $data->getCommitDetail('committerPHID');
     $committer_name = $data->getCommitDetail('committer');
     if ($committer_phid) {
         $committed_info->setTarget($handles[$committer_phid]->renderLink());
     } else {
         if (strlen($committer_name)) {
             $committed_info->setTarget($committer_name);
         } else {
             if ($author_phid) {
                 $committed_info->setTarget($handles[$author_phid]->renderLink());
             } else {
                 if (strlen($author_name)) {
                     $committed_info->setTarget($author_name);
                 }
             }
         }
     }
     $props['Committed'] = id(new PHUIStatusListView())->addItem($committed_info);
     if ($push_logs) {
         $pushed_list = new PHUIStatusListView();
         foreach ($push_logs as $push_log) {
             $pushed_item = id(new PHUIStatusItemView())->setTarget($handles[$push_log->getPusherPHID()]->renderLink())->setNote(phabricator_datetime($push_log->getEpoch(), $viewer));
             $pushed_list->addItem($pushed_item);
         }
         $props['Pushed'] = $pushed_list;
     }
     $reviewer_phid = $data->getCommitDetail('reviewerPHID');
     if ($reviewer_phid) {
         $props['Reviewer'] = $handles[$reviewer_phid]->renderLink();
     }
     if ($revision_phid) {
         $props['Differential Revision'] = $handles[$revision_phid]->renderLink();
     }
     if ($parents) {
         $parent_links = array();
         foreach ($parents as $parent) {
             $parent_links[] = $handles[$parent->getPHID()]->renderLink();
         }
         $props['Parents'] = phutil_implode_html(" · ", $parent_links);
     }
     $props['Branches'] = phutil_tag('span', array('id' => 'commit-branches'), pht('Unknown'));
     $props['Tags'] = phutil_tag('span', array('id' => 'commit-tags'), pht('Unknown'));
     $callsign = $repository->getCallsign();
     $root = '/diffusion/' . $callsign . '/commit/' . $commit->getCommitIdentifier();
     Javelin::initBehavior('diffusion-commit-branches', array($root . '/branches/' => 'commit-branches', $root . '/tags/' => 'commit-tags'));
     $refs = $this->buildRefs($drequest);
     if ($refs) {
         $props['References'] = $refs;
     }
     if ($reverts_phids) {
         $props[pht('Reverts')] = $viewer->renderHandleList($reverts_phids);
     }
     if ($reverted_by_phids) {
         $props[pht('Reverted By')] = $viewer->renderHandleList($reverted_by_phids);
     }
     if ($task_phids) {
         $task_list = array();
         foreach ($task_phids as $phid) {
             $task_list[] = $handles[$phid]->renderLink();
         }
         $task_list = phutil_implode_html(phutil_tag('br'), $task_list);
         $props['Tasks'] = $task_list;
     }
     return $props;
 }
 private function getCommitProperties(PhabricatorRepositoryCommit $commit, PhabricatorRepositoryCommitData $data, array $parents)
 {
     assert_instances_of($parents, 'PhabricatorRepositoryCommit');
     $user = $this->getRequest()->getUser();
     $task_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($commit->getPHID(), PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK);
     $phids = $task_phids;
     if ($data->getCommitDetail('authorPHID')) {
         $phids[] = $data->getCommitDetail('authorPHID');
     }
     if ($data->getCommitDetail('reviewerPHID')) {
         $phids[] = $data->getCommitDetail('reviewerPHID');
     }
     if ($data->getCommitDetail('differential.revisionPHID')) {
         $phids[] = $data->getCommitDetail('differential.revisionPHID');
     }
     if ($parents) {
         foreach ($parents as $parent) {
             $phids[] = $parent->getPHID();
         }
     }
     $handles = array();
     if ($phids) {
         $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
     }
     $props = array();
     if ($commit->getAuditStatus()) {
         $status = PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus());
         $props['Status'] = phutil_render_tag('strong', array(), phutil_escape_html($status));
     }
     $props['Committed'] = phabricator_datetime($commit->getEpoch(), $user);
     $author_phid = $data->getCommitDetail('authorPHID');
     if ($data->getCommitDetail('authorPHID')) {
         $props['Author'] = $handles[$author_phid]->renderLink();
     } else {
         $props['Author'] = phutil_escape_html($data->getAuthorName());
     }
     $reviewer_phid = $data->getCommitDetail('reviewerPHID');
     $reviewer_name = $data->getCommitDetail('reviewerName');
     if ($reviewer_phid) {
         $props['Reviewer'] = $handles[$reviewer_phid]->renderLink();
     } else {
         if ($reviewer_name) {
             $props['Reviewer'] = phutil_escape_html($reviewer_name);
         }
     }
     $revision_phid = $data->getCommitDetail('differential.revisionPHID');
     if ($revision_phid) {
         $props['Differential Revision'] = $handles[$revision_phid]->renderLink();
     }
     if ($parents) {
         $parent_links = array();
         foreach ($parents as $parent) {
             $parent_links[] = $handles[$parent->getPHID()]->renderLink();
         }
         $props['Parents'] = implode(' · ', $parent_links);
     }
     $request = $this->getDiffusionRequest();
     $contains = DiffusionContainsQuery::newFromDiffusionRequest($request);
     $branches = $contains->loadContainingBranches();
     if ($branches) {
         // TODO: Separate these into 'tracked' and other; link tracked branches.
         $branches = implode(', ', array_keys($branches));
         $branches = phutil_escape_html($branches);
         $props['Branches'] = $branches;
     }
     if ($task_phids) {
         $task_list = array();
         foreach ($task_phids as $phid) {
             $task_list[] = $handles[$phid]->renderLink();
         }
         $task_list = implode('<br />', $task_list);
         $props['Tasks'] = $task_list;
     }
     return $props;
 }
 public function render()
 {
     $rows = array();
     foreach ($this->commits as $commit) {
         $commit_name = $this->getHandle($commit->getPHID())->renderLink();
         $author_name = null;
         if ($commit->getAuthorPHID()) {
             $author_name = $this->getHandle($commit->getAuthorPHID())->renderLink();
         }
         $auditors = array();
         if ($commit->getAudits()) {
             foreach ($commit->getAudits() as $audit) {
                 $actor_phid = $audit->getActorPHID();
                 $auditors[$actor_phid] = $this->getHandle($actor_phid)->renderLink();
             }
         }
         $rows[] = array($commit_name, $author_name, phutil_escape_html($commit->getCommitData()->getSummary()), PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()), implode(', ', $auditors), phabricator_datetime($commit->getEpoch(), $this->user));
     }
     $table = new AphrontTableView($rows);
     $table->setHeaders(array('Commit', 'Author', 'Summary', 'Audit Status', 'Auditors', 'Date'));
     $table->setColumnClasses(array('n', '', 'wide', '', '', ''));
     if ($this->commits && reset($this->commits)->getAudits() === null) {
         $table->setColumnVisibility(array(true, true, true, true, false, true));
     }
     if ($this->noDataString) {
         $table->setNoDataString($this->noDataString);
     }
     return $table->render();
 }
 private function getCommitProperties(PhabricatorRepositoryCommit $commit, PhabricatorRepositoryCommitData $data, array $parents)
 {
     assert_instances_of($parents, 'PhabricatorRepositoryCommit');
     $user = $this->getRequest()->getUser();
     $commit_phid = $commit->getPHID();
     $edges = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($commit_phid))->withEdgeTypes(array(PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK, PhabricatorEdgeConfig::TYPE_COMMIT_HAS_PROJECT))->execute();
     $task_phids = array_keys($edges[$commit_phid][PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK]);
     $proj_phids = array_keys($edges[$commit_phid][PhabricatorEdgeConfig::TYPE_COMMIT_HAS_PROJECT]);
     $phids = array_merge($task_phids, $proj_phids);
     if ($data->getCommitDetail('authorPHID')) {
         $phids[] = $data->getCommitDetail('authorPHID');
     }
     if ($data->getCommitDetail('reviewerPHID')) {
         $phids[] = $data->getCommitDetail('reviewerPHID');
     }
     if ($data->getCommitDetail('committerPHID')) {
         $phids[] = $data->getCommitDetail('committerPHID');
     }
     if ($data->getCommitDetail('differential.revisionPHID')) {
         $phids[] = $data->getCommitDetail('differential.revisionPHID');
     }
     if ($parents) {
         foreach ($parents as $parent) {
             $phids[] = $parent->getPHID();
         }
     }
     $handles = array();
     if ($phids) {
         $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
     }
     $props = array();
     if ($commit->getAuditStatus()) {
         $status = PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus());
         $props['Status'] = phutil_render_tag('strong', array(), phutil_escape_html($status));
     }
     $props['Committed'] = phabricator_datetime($commit->getEpoch(), $user);
     $author_phid = $data->getCommitDetail('authorPHID');
     if ($data->getCommitDetail('authorPHID')) {
         $props['Author'] = $handles[$author_phid]->renderLink();
     } else {
         $props['Author'] = phutil_escape_html($data->getAuthorName());
     }
     $reviewer_phid = $data->getCommitDetail('reviewerPHID');
     $reviewer_name = $data->getCommitDetail('reviewerName');
     if ($reviewer_phid) {
         $props['Reviewer'] = $handles[$reviewer_phid]->renderLink();
     } else {
         if ($reviewer_name) {
             $props['Reviewer'] = phutil_escape_html($reviewer_name);
         }
     }
     $committer = $data->getCommitDetail('committer');
     if ($committer) {
         $committer_phid = $data->getCommitDetail('committerPHID');
         if ($data->getCommitDetail('committerPHID')) {
             $props['Committer'] = $handles[$committer_phid]->renderLink();
         } else {
             $props['Committer'] = phutil_escape_html($committer);
         }
     }
     $revision_phid = $data->getCommitDetail('differential.revisionPHID');
     if ($revision_phid) {
         $props['Differential Revision'] = $handles[$revision_phid]->renderLink();
     }
     if ($parents) {
         $parent_links = array();
         foreach ($parents as $parent) {
             $parent_links[] = $handles[$parent->getPHID()]->renderLink();
         }
         $props['Parents'] = implode(' &middot; ', $parent_links);
     }
     $request = $this->getDiffusionRequest();
     $props['Branches'] = '<span id="commit-branches">Unknown</span>';
     $props['Tags'] = '<span id="commit-tags">Unknown</span>';
     $callsign = $request->getRepository()->getCallsign();
     $root = '/diffusion/' . $callsign . '/commit/' . $commit->getCommitIdentifier();
     Javelin::initBehavior('diffusion-commit-branches', array($root . '/branches/' => 'commit-branches', $root . '/tags/' => 'commit-tags'));
     $refs = $this->buildRefs($request);
     if ($refs) {
         $props['References'] = $refs;
     }
     if ($task_phids) {
         $task_list = array();
         foreach ($task_phids as $phid) {
             $task_list[] = $handles[$phid]->renderLink();
         }
         $task_list = implode('<br />', $task_list);
         $props['Tasks'] = $task_list;
     }
     if ($proj_phids) {
         $proj_list = array();
         foreach ($proj_phids as $phid) {
             $proj_list[] = $handles[$phid]->renderLink();
         }
         $proj_list = implode('<br />', $proj_list);
         $props['Projects'] = $proj_list;
     }
     return $props;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $response = $this->loadDiffusionContext();
     if ($response) {
         return $response;
     }
     $drequest = $this->getDiffusionRequest();
     $viewer = $request->getUser();
     if ($request->getStr('diff')) {
         return $this->buildRawDiffResponse($drequest);
     }
     $repository = $drequest->getRepository();
     $commit = id(new DiffusionCommitQuery())->setViewer($viewer)->withRepository($repository)->withIdentifiers(array($drequest->getCommit()))->needCommitData(true)->needAuditRequests(true)->executeOne();
     $crumbs = $this->buildCrumbs(array('commit' => true));
     $crumbs->setBorder(true);
     if (!$commit) {
         if (!$this->getCommitExists()) {
             return new Aphront404Response();
         }
         $error = id(new PHUIInfoView())->setTitle(pht('Commit Still Parsing'))->appendChild(pht('Failed to load the commit because the commit has not been ' . 'parsed yet.'));
         $title = pht('Commit Still Parsing');
         return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($error);
     }
     $audit_requests = $commit->getAudits();
     $this->auditAuthorityPHIDs = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($viewer);
     $commit_data = $commit->getCommitData();
     $is_foreign = $commit_data->getCommitDetail('foreign-svn-stub');
     $error_panel = null;
     if ($is_foreign) {
         $subpath = $commit_data->getCommitDetail('svn-subpath');
         $error_panel = new PHUIInfoView();
         $error_panel->setTitle(pht('Commit Not Tracked'));
         $error_panel->setSeverity(PHUIInfoView::SEVERITY_WARNING);
         $error_panel->appendChild(pht("This Diffusion repository is configured to track only one " . "subdirectory of the entire Subversion repository, and this commit " . "didn't affect the tracked subdirectory ('%s'), so no " . "information is available.", $subpath));
     } else {
         $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
         $engine->setConfig('viewer', $viewer);
         $commit_tag = $this->renderCommitHashTag($drequest);
         $header = id(new PHUIHeaderView())->setHeader(nonempty($commit->getSummary(), pht('Commit Detail')))->setHeaderIcon('fa-code-fork')->addTag($commit_tag);
         if ($commit->getAuditStatus()) {
             $icon = PhabricatorAuditCommitStatusConstants::getStatusIcon($commit->getAuditStatus());
             $color = PhabricatorAuditCommitStatusConstants::getStatusColor($commit->getAuditStatus());
             $status = PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus());
             $header->setStatus($icon, $color, $status);
         }
         $curtain = $this->buildCurtain($commit, $repository);
         $subheader = $this->buildSubheaderView($commit, $commit_data);
         $details = $this->buildPropertyListView($commit, $commit_data, $audit_requests);
         $message = $commit_data->getCommitMessage();
         $revision = $commit->getCommitIdentifier();
         $message = $this->linkBugtraq($message);
         $message = $engine->markupText($message);
         $detail_list = new PHUIPropertyListView();
         $detail_list->addTextContent(phutil_tag('div', array('class' => 'diffusion-commit-message phabricator-remarkup'), $message));
         if ($this->getCommitErrors()) {
             $error_panel = id(new PHUIInfoView())->appendChild($this->getCommitErrors())->setSeverity(PHUIInfoView::SEVERITY_WARNING);
         }
     }
     $timeline = $this->buildComments($commit);
     $hard_limit = 1000;
     if ($commit->isImported()) {
         $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest($drequest);
         $change_query->setLimit($hard_limit + 1);
         $changes = $change_query->loadChanges();
     } else {
         $changes = array();
     }
     $was_limited = count($changes) > $hard_limit;
     if ($was_limited) {
         $changes = array_slice($changes, 0, $hard_limit);
     }
     $merge_table = $this->buildMergesTable($commit);
     $highlighted_audits = $commit->getAuthorityAudits($viewer, $this->auditAuthorityPHIDs);
     $count = count($changes);
     $bad_commit = null;
     if ($count == 0) {
         $bad_commit = queryfx_one(id(new PhabricatorRepository())->establishConnection('r'), 'SELECT * FROM %T WHERE fullCommitName = %s', PhabricatorRepository::TABLE_BADCOMMIT, $commit->getMonogram());
     }
     $show_changesets = false;
     $info_panel = null;
     $change_list = null;
     $change_table = null;
     if ($bad_commit) {
         $info_panel = $this->renderStatusMessage(pht('Bad Commit'), $bad_commit['description']);
     } else {
         if ($is_foreign) {
             // Don't render anything else.
         } else {
             if (!$commit->isImported()) {
                 $info_panel = $this->renderStatusMessage(pht('Still Importing...'), pht('This commit is still importing. Changes will be visible once ' . 'the import finishes.'));
             } else {
                 if (!count($changes)) {
                     $info_panel = $this->renderStatusMessage(pht('Empty Commit'), pht('This commit is empty and does not affect any paths.'));
                 } else {
                     if ($was_limited) {
                         $info_panel = $this->renderStatusMessage(pht('Enormous Commit'), pht('This commit is enormous, and affects more than %d files. ' . 'Changes are not shown.', $hard_limit));
                     } else {
                         if (!$this->getCommitExists()) {
                             $info_panel = $this->renderStatusMessage(pht('Commit No Longer Exists'), pht('This commit no longer exists in the repository.'));
                         } else {
                             $show_changesets = true;
                             // The user has clicked "Show All Changes", and we should show all the
                             // changes inline even if there are more than the soft limit.
                             $show_all_details = $request->getBool('show_all');
                             $change_header = id(new PHUIHeaderView())->setHeader(pht('Changes (%s)', new PhutilNumber($count)));
                             $warning_view = null;
                             if ($count > self::CHANGES_LIMIT && !$show_all_details) {
                                 $button = id(new PHUIButtonView())->setText(pht('Show All Changes'))->setHref('?show_all=true')->setTag('a')->setIcon('fa-files-o');
                                 $warning_view = id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_WARNING)->setTitle(pht('Very Large Commit'))->appendChild(pht('This commit is very large. Load each file individually.'));
                                 $change_header->addActionLink($button);
                             }
                             $changesets = DiffusionPathChange::convertToDifferentialChangesets($viewer, $changes);
                             // TODO: This table and panel shouldn't really be separate, but we need
                             // to clean up the "Load All Files" interaction first.
                             $change_table = $this->buildTableOfContents($changesets, $change_header, $warning_view);
                             $vcs = $repository->getVersionControlSystem();
                             switch ($vcs) {
                                 case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
                                     $vcs_supports_directory_changes = true;
                                     break;
                                 case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
                                 case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
                                     $vcs_supports_directory_changes = false;
                                     break;
                                 default:
                                     throw new Exception(pht('Unknown VCS.'));
                             }
                             $references = array();
                             foreach ($changesets as $key => $changeset) {
                                 $file_type = $changeset->getFileType();
                                 if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
                                     if (!$vcs_supports_directory_changes) {
                                         unset($changesets[$key]);
                                         continue;
                                     }
                                 }
                                 $references[$key] = $drequest->generateURI(array('action' => 'rendering-ref', 'path' => $changeset->getFilename()));
                             }
                             // TODO: Some parts of the views still rely on properties of the
                             // DifferentialChangeset. Make the objects ephemeral to make sure we don't
                             // accidentally save them, and then set their ID to the appropriate ID for
                             // this application (the path IDs).
                             $path_ids = array_flip(mpull($changes, 'getPath'));
                             foreach ($changesets as $changeset) {
                                 $changeset->makeEphemeral();
                                 $changeset->setID($path_ids[$changeset->getFilename()]);
                             }
                             if ($count <= self::CHANGES_LIMIT || $show_all_details) {
                                 $visible_changesets = $changesets;
                             } else {
                                 $visible_changesets = array();
                                 $inlines = PhabricatorAuditInlineComment::loadDraftAndPublishedComments($viewer, $commit->getPHID());
                                 $path_ids = mpull($inlines, null, 'getPathID');
                                 foreach ($changesets as $key => $changeset) {
                                     if (array_key_exists($changeset->getID(), $path_ids)) {
                                         $visible_changesets[$key] = $changeset;
                                     }
                                 }
                             }
                             $change_list_title = $commit->getDisplayName();
                             $change_list = new DifferentialChangesetListView();
                             $change_list->setTitle($change_list_title);
                             $change_list->setChangesets($changesets);
                             $change_list->setVisibleChangesets($visible_changesets);
                             $change_list->setRenderingReferences($references);
                             $change_list->setRenderURI($repository->getPathURI('diff/'));
                             $change_list->setRepository($repository);
                             $change_list->setUser($viewer);
                             $change_list->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
                             // TODO: Try to setBranch() to something reasonable here?
                             $change_list->setStandaloneURI($repository->getPathURI('diff/'));
                             $change_list->setRawFileURIs(null, $repository->getPathURI('diff/?view=r'));
                             $change_list->setInlineCommentControllerURI('/diffusion/inline/edit/' . phutil_escape_uri($commit->getPHID()) . '/');
                         }
                     }
                 }
             }
         }
     }
     $add_comment = $this->renderAddCommentPanel($commit, $audit_requests);
     $filetree_on = $viewer->compareUserSetting(PhabricatorShowFiletreeSetting::SETTINGKEY, PhabricatorShowFiletreeSetting::VALUE_ENABLE_FILETREE);
     $pref_collapse = PhabricatorFiletreeVisibleSetting::SETTINGKEY;
     $collapsed = $viewer->getUserSetting($pref_collapse);
     $nav = null;
     if ($show_changesets && $filetree_on) {
         $nav = id(new DifferentialChangesetFileTreeSideNavBuilder())->setTitle($commit->getDisplayName())->setBaseURI(new PhutilURI($commit->getURI()))->build($changesets)->setCrumbs($crumbs)->setCollapsed((bool) $collapsed);
     }
     $view = id(new PHUITwoColumnView())->setHeader($header)->setSubheader($subheader)->setMainColumn(array($error_panel, $timeline, $merge_table, $info_panel))->setFooter(array($change_table, $change_list, $add_comment))->addPropertySection(pht('Description'), $detail_list)->addPropertySection(pht('Details'), $details)->setCurtain($curtain);
     $page = $this->newPage()->setTitle($commit->getDisplayName())->setCrumbs($crumbs)->setPageObjectPHIDS(array($commit->getPHID()))->appendChild(array($view));
     if ($nav) {
         $page->setNavigation($nav);
     }
     return $page;
 }