Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diffusion/query/DiffusionCommitRevisionQuery.php
12242 views
1
<?php
2
3
final class DiffusionCommitRevisionQuery
4
extends Phobject {
5
6
public static function loadRevisionMapForCommits(
7
PhabricatorUser $viewer,
8
array $commits) {
9
assert_instances_of($commits, 'PhabricatorRepositoryCommit');
10
11
if (!$commits) {
12
return array();
13
}
14
15
$commit_phids = mpull($commits, 'getPHID');
16
17
$edge_query = id(new PhabricatorEdgeQuery())
18
->withSourcePHIDs($commit_phids)
19
->withEdgeTypes(
20
array(
21
DiffusionCommitHasRevisionEdgeType::EDGECONST,
22
));
23
$edge_query->execute();
24
25
$revision_phids = $edge_query->getDestinationPHIDs();
26
if (!$revision_phids) {
27
return array();
28
}
29
30
$revisions = id(new DifferentialRevisionQuery())
31
->setViewer($viewer)
32
->withPHIDs($revision_phids)
33
->execute();
34
$revisions = mpull($revisions, null, 'getPHID');
35
36
$map = array();
37
foreach ($commit_phids as $commit_phid) {
38
$revision_phids = $edge_query->getDestinationPHIDs(
39
array(
40
$commit_phid,
41
));
42
43
$map[$commit_phid] = array_select_keys($revisions, $revision_phids);
44
}
45
46
return $map;
47
}
48
49
public static function loadRevisionForCommit(
50
PhabricatorUser $viewer,
51
PhabricatorRepositoryCommit $commit) {
52
53
$data = $commit->getCommitData();
54
55
$revision_id = $data->getCommitDetail('differential.revisionID');
56
if (!$revision_id) {
57
return null;
58
}
59
60
return id(new DifferentialRevisionQuery())
61
->setViewer($viewer)
62
->withIDs(array($revision_id))
63
->needReviewers(true)
64
->executeOne();
65
}
66
67
public static function loadRevertedObjects(
68
PhabricatorUser $viewer,
69
$source_object,
70
array $object_names,
71
PhabricatorRepository $repository_scope = null) {
72
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);
79
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);
86
}
87
88
$objects = $commit_query->execute();
89
90
$more_objects = id(new PhabricatorObjectQuery())
91
->setViewer($viewer)
92
->withNames($object_names)
93
->withTypes(
94
array(
95
DifferentialRevisionPHIDType::TYPECONST,
96
))
97
->execute();
98
foreach ($more_objects as $object) {
99
$objects[] = $object;
100
}
101
102
// See PHI1008 and T13276. If something reverts commit X, we also revert
103
// any associated revision.
104
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.
108
109
foreach ($objects as $object) {
110
if (!($object instanceof PhabricatorRepositoryCommit)) {
111
continue;
112
}
113
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.
117
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.
120
121
$revision = self::loadRevisionForCommit(
122
$viewer,
123
$object);
124
if ($revision) {
125
$objects[] = $revision;
126
}
127
}
128
129
$objects = mpull($objects, null, 'getPHID');
130
131
// Prevent an object from reverting itself, although this would be very
132
// clever in Git or Mercurial.
133
unset($objects[$source_object->getPHID()]);
134
135
return $objects;
136
}
137
138
}
139
140