Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/controller/DiffusionBlameController.php
Show All 30 Lines | if ($identifiers) { | ||||
->execute(); | ->execute(); | ||||
$commits = mpull($commits, null, 'getCommitIdentifier'); | $commits = mpull($commits, null, 'getCommitIdentifier'); | ||||
} else { | } else { | ||||
$commits = array(); | $commits = array(); | ||||
} | } | ||||
$commit_map = mpull($commits, 'getCommitIdentifier', 'getPHID'); | $commit_map = mpull($commits, 'getCommitIdentifier', 'getPHID'); | ||||
$revisions = array(); | $revision_map = $this->loadRevisionsForCommits($commits); | ||||
$revision_map = array(); | |||||
if ($commits) { | |||||
$revision_ids = id(new DifferentialRevision()) | |||||
->loadIDsByCommitPHIDs(array_keys($commit_map)); | |||||
if ($revision_ids) { | |||||
$revisions = id(new DifferentialRevisionQuery()) | |||||
->setViewer($viewer) | |||||
->withIDs($revision_ids) | |||||
->execute(); | |||||
$revisions = mpull($revisions, null, 'getID'); | |||||
} | |||||
foreach ($revision_ids as $commit_phid => $revision_id) { | |||||
// If the viewer can't actually see this revision, skip it. | |||||
if (!isset($revisions[$revision_id])) { | |||||
continue; | |||||
} | |||||
$revision_map[$commit_map[$commit_phid]] = $revision_id; | |||||
} | |||||
} | |||||
$base_href = (string)$drequest->generateURI( | $base_href = (string)$drequest->generateURI( | ||||
array( | array( | ||||
'action' => 'browse', | 'action' => 'browse', | ||||
'stable' => true, | 'stable' => true, | ||||
)); | )); | ||||
$skip_text = pht('Skip Past This Commit'); | $skip_text = pht('Skip Past This Commit'); | ||||
$skip_icon = id(new PHUIIconView()) | $skip_icon = id(new PHUIIconView()) | ||||
->setIcon('fa-backward'); | ->setIcon('fa-backward'); | ||||
Javelin::initBehavior('phabricator-tooltips'); | Javelin::initBehavior('phabricator-tooltips'); | ||||
$handle_phids = array(); | $handle_phids = array(); | ||||
foreach ($commits as $commit) { | foreach ($commits as $commit) { | ||||
$handle_phids[] = $commit->getAuthorDisplayPHID(); | $handle_phids[] = $commit->getAuthorDisplayPHID(); | ||||
} | } | ||||
foreach ($revision_map as $revisions) { | |||||
foreach ($revisions as $revision) { | foreach ($revisions as $revision) { | ||||
$handle_phids[] = $revision->getAuthorPHID(); | $handle_phids[] = $revision->getAuthorPHID(); | ||||
} | } | ||||
} | |||||
$handles = $viewer->loadHandles($handle_phids); | $handles = $viewer->loadHandles($handle_phids); | ||||
$map = array(); | $map = array(); | ||||
$epochs = array(); | $epochs = array(); | ||||
foreach ($identifiers as $identifier) { | foreach ($identifiers as $identifier) { | ||||
$revision_id = idx($revision_map, $identifier); | |||||
if ($revision_id) { | |||||
$revision = idx($revisions, $revision_id); | |||||
} else { | |||||
$revision = null; | |||||
} | |||||
$skip_href = $base_href.'?before='.$identifier; | $skip_href = $base_href.'?before='.$identifier; | ||||
$skip_link = javelin_tag( | $skip_link = javelin_tag( | ||||
'a', | 'a', | ||||
array( | array( | ||||
'href' => $skip_href, | 'href' => $skip_href, | ||||
'sigil' => 'has-tooltip', | 'sigil' => 'has-tooltip', | ||||
'meta' => array( | 'meta' => array( | ||||
'tip' => $skip_text, | 'tip' => $skip_text, | ||||
'align' => 'E', | 'align' => 'E', | ||||
'size' => 300, | 'size' => 300, | ||||
), | ), | ||||
), | ), | ||||
$skip_icon); | $skip_icon); | ||||
// We may not have a commit object for a given identifier if the commit | // We may not have a commit object for a given identifier if the commit | ||||
// has not imported yet. | // has not imported yet. | ||||
// At time of writing, this can also happen if a line was part of the | // At time of writing, this can also happen if a line was part of the | ||||
// initial import: blame produces a "^abc123" identifier in Git, which | // initial import: blame produces a "^abc123" identifier in Git, which | ||||
// doesn't correspond to a real commit. | // doesn't correspond to a real commit. | ||||
$commit = idx($commits, $identifier); | $commit = idx($commits, $identifier); | ||||
$revision = null; | |||||
if ($commit) { | |||||
$revisions = idx($revision_map, $commit->getPHID()); | |||||
// There may be multiple edges between this commit and revisions in the | |||||
// database. If there are, just pick one arbitrarily. | |||||
if ($revisions) { | |||||
$revision = head($revisions); | |||||
} | |||||
} | |||||
$author_phid = null; | $author_phid = null; | ||||
if ($commit) { | if ($commit) { | ||||
$author_phid = $commit->getAuthorDisplayPHID(); | $author_phid = $commit->getAuthorDisplayPHID(); | ||||
} | } | ||||
if (!$author_phid) { | if (!$author_phid) { | ||||
// This means we couldn't identify an author for the commit or the | // This means we couldn't identify an author for the commit or the | ||||
▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | private function renderCommitTooltip( | ||||
if ($author_name) { | if ($author_name) { | ||||
return "{$summary}\n{$date} \xC2\xB7 {$author_name}"; | return "{$summary}\n{$date} \xC2\xB7 {$author_name}"; | ||||
} else { | } else { | ||||
return "{$summary}\n{$date}"; | return "{$summary}\n{$date}"; | ||||
} | } | ||||
} | } | ||||
private function loadRevisionsForCommits(array $commits) { | |||||
if (!$commits) { | |||||
return array(); | |||||
} | |||||
$commit_phids = mpull($commits, 'getPHID'); | |||||
$edge_query = id(new PhabricatorEdgeQuery()) | |||||
->withSourcePHIDs($commit_phids) | |||||
->withEdgeTypes( | |||||
array( | |||||
DiffusionCommitHasRevisionEdgeType::EDGECONST, | |||||
)); | |||||
$edge_query->execute(); | |||||
$revision_phids = $edge_query->getDestinationPHIDs(); | |||||
if (!$revision_phids) { | |||||
return array(); | |||||
} | |||||
$viewer = $this->getViewer(); | |||||
$revisions = id(new DifferentialRevisionQuery()) | |||||
->setViewer($viewer) | |||||
->withPHIDs($revision_phids) | |||||
->execute(); | |||||
$revisions = mpull($revisions, null, 'getPHID'); | |||||
$map = array(); | |||||
foreach ($commit_phids as $commit_phid) { | |||||
$revision_phids = $edge_query->getDestinationPHIDs( | |||||
array( | |||||
$commit_phid, | |||||
)); | |||||
$map[$commit_phid] = array_select_keys($revisions, $revision_phids); | |||||
} | |||||
return $map; | |||||
} | |||||
} | } |