Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2894656
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
9 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/applications/diffusion/controller/DiffusionBlameController.php b/src/applications/diffusion/controller/DiffusionBlameController.php
index 591462590f..775b61c124 100644
--- a/src/applications/diffusion/controller/DiffusionBlameController.php
+++ b/src/applications/diffusion/controller/DiffusionBlameController.php
@@ -1,284 +1,311 @@
<?php
final class DiffusionBlameController extends DiffusionController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$response = $this->loadDiffusionContext();
if ($response) {
return $response;
}
$viewer = $this->getViewer();
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
$blame = $this->loadBlame();
$identifiers = array_fuse($blame);
if ($identifiers) {
$commits = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withRepository($repository)
->withIdentifiers($identifiers)
->needIdentities(true)
// See PHI1014. If identities haven't been built yet, we may need to
// fall back to raw commit data.
->needCommitData(true)
->execute();
$commits = mpull($commits, null, 'getCommitIdentifier');
} else {
$commits = array();
}
$commit_map = mpull($commits, 'getCommitIdentifier', 'getPHID');
- $revisions = array();
- $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;
- }
- }
+ $revision_map = $this->loadRevisionsForCommits($commits);
$base_href = (string)$drequest->generateURI(
array(
'action' => 'browse',
'stable' => true,
));
$skip_text = pht('Skip Past This Commit');
$skip_icon = id(new PHUIIconView())
->setIcon('fa-backward');
Javelin::initBehavior('phabricator-tooltips');
$handle_phids = array();
foreach ($commits as $commit) {
$handle_phids[] = $commit->getAuthorDisplayPHID();
}
- foreach ($revisions as $revision) {
- $handle_phids[] = $revision->getAuthorPHID();
+ foreach ($revision_map as $revisions) {
+ foreach ($revisions as $revision) {
+ $handle_phids[] = $revision->getAuthorPHID();
+ }
}
$handles = $viewer->loadHandles($handle_phids);
$map = array();
$epochs = array();
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_link = javelin_tag(
'a',
array(
'href' => $skip_href,
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $skip_text,
'align' => 'E',
'size' => 300,
),
),
$skip_icon);
// We may not have a commit object for a given identifier if the commit
// has not imported yet.
// 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
// doesn't correspond to a real commit.
$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;
if ($commit) {
$author_phid = $commit->getAuthorDisplayPHID();
}
if (!$author_phid) {
// This means we couldn't identify an author for the commit or the
// revision. We just render a blank for alignment.
$author_style = null;
$author_href = null;
$author_sigil = null;
$author_meta = null;
} else {
$author_src = $handles[$author_phid]->getImageURI();
$author_style = 'background-image: url('.$author_src.');';
$author_href = $handles[$author_phid]->getURI();
$author_sigil = 'has-tooltip';
$author_meta = array(
'tip' => $handles[$author_phid]->getName(),
'align' => 'E',
'size' => 'auto',
);
}
$author_link = javelin_tag(
$author_href ? 'a' : 'span',
array(
'class' => 'phabricator-source-blame-author',
'style' => $author_style,
'href' => $author_href,
'sigil' => $author_sigil,
'meta' => $author_meta,
));
if ($commit) {
$commit_link = javelin_tag(
'a',
array(
'href' => $commit->getURI(),
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $this->renderCommitTooltip($commit, $handles),
'align' => 'E',
'size' => 600,
),
),
$commit->getLocalName());
} else {
$commit_link = null;
}
$info = array(
$author_link,
$commit_link,
);
if ($revision) {
$revision_link = javelin_tag(
'a',
array(
'href' => $revision->getURI(),
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $this->renderRevisionTooltip($revision, $handles),
'align' => 'E',
'size' => 600,
),
),
$revision->getMonogram());
$info = array(
$info,
" \xC2\xB7 ",
$revision_link,
);
}
if ($commit) {
$epoch = $commit->getEpoch();
} else {
$epoch = 0;
}
$epochs[] = $epoch;
$data = array(
'skip' => $skip_link,
'info' => hsprintf('%s', $info),
'epoch' => $epoch,
);
$map[$identifier] = $data;
}
$epoch_min = min($epochs);
$epoch_max = max($epochs);
return id(new AphrontAjaxResponse())->setContent(
array(
'blame' => $blame,
'map' => $map,
'epoch' => array(
'min' => $epoch_min,
'max' => $epoch_max,
),
));
}
private function loadBlame() {
$drequest = $this->getDiffusionRequest();
$commit = $drequest->getCommit();
$path = $drequest->getPath();
$blame_timeout = 15;
$blame = $this->callConduitWithDiffusionRequest(
'diffusion.blame',
array(
'commit' => $commit,
'paths' => array($path),
'timeout' => $blame_timeout,
));
return idx($blame, $path, array());
}
private function renderRevisionTooltip(
DifferentialRevision $revision,
$handles) {
$viewer = $this->getViewer();
$date = phabricator_date($revision->getDateModified(), $viewer);
$monogram = $revision->getMonogram();
$title = $revision->getTitle();
$header = "{$monogram} {$title}";
$author = $handles[$revision->getAuthorPHID()]->getName();
return "{$header}\n{$date} \xC2\xB7 {$author}";
}
private function renderCommitTooltip(
PhabricatorRepositoryCommit $commit,
$handles) {
$viewer = $this->getViewer();
$date = phabricator_date($commit->getEpoch(), $viewer);
$summary = trim($commit->getSummary());
$author_phid = $commit->getAuthorPHID();
if ($author_phid && isset($handles[$author_phid])) {
$author_name = $handles[$author_phid]->getName();
} else {
$author_name = null;
}
if ($author_name) {
return "{$summary}\n{$date} \xC2\xB7 {$author_name}";
} else {
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;
+ }
+
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Jan 19 2025, 20:13 (6 w, 1 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1128346
Default Alt Text
(9 KB)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment