Path: blob/master/src/applications/diffusion/query/DiffusionCommitRevisionQuery.php
12242 views
<?php12final class DiffusionCommitRevisionQuery3extends Phobject {45public static function loadRevisionMapForCommits(6PhabricatorUser $viewer,7array $commits) {8assert_instances_of($commits, 'PhabricatorRepositoryCommit');910if (!$commits) {11return array();12}1314$commit_phids = mpull($commits, 'getPHID');1516$edge_query = id(new PhabricatorEdgeQuery())17->withSourcePHIDs($commit_phids)18->withEdgeTypes(19array(20DiffusionCommitHasRevisionEdgeType::EDGECONST,21));22$edge_query->execute();2324$revision_phids = $edge_query->getDestinationPHIDs();25if (!$revision_phids) {26return array();27}2829$revisions = id(new DifferentialRevisionQuery())30->setViewer($viewer)31->withPHIDs($revision_phids)32->execute();33$revisions = mpull($revisions, null, 'getPHID');3435$map = array();36foreach ($commit_phids as $commit_phid) {37$revision_phids = $edge_query->getDestinationPHIDs(38array(39$commit_phid,40));4142$map[$commit_phid] = array_select_keys($revisions, $revision_phids);43}4445return $map;46}4748public static function loadRevisionForCommit(49PhabricatorUser $viewer,50PhabricatorRepositoryCommit $commit) {5152$data = $commit->getCommitData();5354$revision_id = $data->getCommitDetail('differential.revisionID');55if (!$revision_id) {56return null;57}5859return id(new DifferentialRevisionQuery())60->setViewer($viewer)61->withIDs(array($revision_id))62->needReviewers(true)63->executeOne();64}6566public static function loadRevertedObjects(67PhabricatorUser $viewer,68$source_object,69array $object_names,70PhabricatorRepository $repository_scope = null) {7172// Fetch commits first, since we need to load data on commits in order73// to identify associated revisions later on.74$commit_query = id(new DiffusionCommitQuery())75->setViewer($viewer)76->withIdentifiers($object_names)77->needCommitData(true);7879// If we're acting in a specific repository, only allow commits in that80// repository to be affected: when commit X reverts commit Y by hash, we81// only want to revert commit Y in the same repository, even if other82// repositories have a commit with the same hash.83if ($repository_scope) {84$commit_query->withRepository($repository_scope);85}8687$objects = $commit_query->execute();8889$more_objects = id(new PhabricatorObjectQuery())90->setViewer($viewer)91->withNames($object_names)92->withTypes(93array(94DifferentialRevisionPHIDType::TYPECONST,95))96->execute();97foreach ($more_objects as $object) {98$objects[] = $object;99}100101// See PHI1008 and T13276. If something reverts commit X, we also revert102// any associated revision.103104// For now, we don't try to find associated commits if something reverts105// revision Y. This is less common, although we could make more of an106// effort in the future.107108foreach ($objects as $object) {109if (!($object instanceof PhabricatorRepositoryCommit)) {110continue;111}112113// NOTE: If our object "reverts X", where "X" is a commit hash, it is114// possible that "X" will not have parsed yet, so we'll fail to find115// a revision even though one exists.116117// For now, do nothing. It's rare to push a commit which reverts some118// commit "X" before "X" has parsed, so we expect this to be unusual.119120$revision = self::loadRevisionForCommit(121$viewer,122$object);123if ($revision) {124$objects[] = $revision;125}126}127128$objects = mpull($objects, null, 'getPHID');129130// Prevent an object from reverting itself, although this would be very131// clever in Git or Mercurial.132unset($objects[$source_object->getPHID()]);133134return $objects;135}136137}138139140