Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / diffusion / query / DiffusionCommitRevisionQuery.php
blob822ebfb014dce091a69369e4985e0b3357fbaa4f
1 <?php
3 final class DiffusionCommitRevisionQuery
4 extends Phobject {
6 public static function loadRevisionMapForCommits(
7 PhabricatorUser $viewer,
8 array $commits) {
9 assert_instances_of($commits, 'PhabricatorRepositoryCommit');
11 if (!$commits) {
12 return array();
15 $commit_phids = mpull($commits, 'getPHID');
17 $edge_query = id(new PhabricatorEdgeQuery())
18 ->withSourcePHIDs($commit_phids)
19 ->withEdgeTypes(
20 array(
21 DiffusionCommitHasRevisionEdgeType::EDGECONST,
22 ));
23 $edge_query->execute();
25 $revision_phids = $edge_query->getDestinationPHIDs();
26 if (!$revision_phids) {
27 return array();
30 $revisions = id(new DifferentialRevisionQuery())
31 ->setViewer($viewer)
32 ->withPHIDs($revision_phids)
33 ->execute();
34 $revisions = mpull($revisions, null, 'getPHID');
36 $map = array();
37 foreach ($commit_phids as $commit_phid) {
38 $revision_phids = $edge_query->getDestinationPHIDs(
39 array(
40 $commit_phid,
41 ));
43 $map[$commit_phid] = array_select_keys($revisions, $revision_phids);
46 return $map;
49 public static function loadRevisionForCommit(
50 PhabricatorUser $viewer,
51 PhabricatorRepositoryCommit $commit) {
53 $data = $commit->getCommitData();
55 $revision_id = $data->getCommitDetail('differential.revisionID');
56 if (!$revision_id) {
57 return null;
60 return id(new DifferentialRevisionQuery())
61 ->setViewer($viewer)
62 ->withIDs(array($revision_id))
63 ->needReviewers(true)
64 ->executeOne();
67 public static function loadRevertedObjects(
68 PhabricatorUser $viewer,
69 $source_object,
70 array $object_names,
71 PhabricatorRepository $repository_scope = null) {
73 // Fetch commits first, since we need to load data on commits in order
74 // to identify associated revisions later on.
75 $commit_query = id(new DiffusionCommitQuery())
76 ->setViewer($viewer)
77 ->withIdentifiers($object_names)
78 ->needCommitData(true);
80 // If we're acting in a specific repository, only allow commits in that
81 // repository to be affected: when commit X reverts commit Y by hash, we
82 // only want to revert commit Y in the same repository, even if other
83 // repositories have a commit with the same hash.
84 if ($repository_scope) {
85 $commit_query->withRepository($repository_scope);
88 $objects = $commit_query->execute();
90 $more_objects = id(new PhabricatorObjectQuery())
91 ->setViewer($viewer)
92 ->withNames($object_names)
93 ->withTypes(
94 array(
95 DifferentialRevisionPHIDType::TYPECONST,
97 ->execute();
98 foreach ($more_objects as $object) {
99 $objects[] = $object;
102 // See PHI1008 and T13276. If something reverts commit X, we also revert
103 // any associated revision.
105 // For now, we don't try to find associated commits if something reverts
106 // revision Y. This is less common, although we could make more of an
107 // effort in the future.
109 foreach ($objects as $object) {
110 if (!($object instanceof PhabricatorRepositoryCommit)) {
111 continue;
114 // NOTE: If our object "reverts X", where "X" is a commit hash, it is
115 // possible that "X" will not have parsed yet, so we'll fail to find
116 // a revision even though one exists.
118 // For now, do nothing. It's rare to push a commit which reverts some
119 // commit "X" before "X" has parsed, so we expect this to be unusual.
121 $revision = self::loadRevisionForCommit(
122 $viewer,
123 $object);
124 if ($revision) {
125 $objects[] = $revision;
129 $objects = mpull($objects, null, 'getPHID');
131 // Prevent an object from reverting itself, although this would be very
132 // clever in Git or Mercurial.
133 unset($objects[$source_object->getPHID()]);
135 return $objects;