3 final class DiffusionLowLevelCommitFieldsQuery
4 extends DiffusionLowLevelQuery
{
7 private $revisionMatchData = array(
10 'validDomain' => null,
11 'matchHashType' => null,
12 'matchHashValue' => null,
15 public function withCommitRef(DiffusionCommitRef
$ref) {
20 public function getRevisionMatchData() {
21 return $this->revisionMatchData
;
24 private function setRevisionMatchData($key, $value) {
25 $this->revisionMatchData
[$key] = $value;
29 protected function executeQuery() {
31 $message = $ref->getMessage();
32 $hashes = $ref->getHashes();
39 $result = id(new ConduitCall('differential.parsecommitmessage', $params))
40 ->setUser(PhabricatorUser
::getOmnipotentUser())
42 $fields = $result['fields'];
44 $revision_id = idx($fields, 'revisionID');
46 $this->setRevisionMatchData('usedURI', true);
48 $this->setRevisionMatchData('usedURI', false);
50 $revision_id_info = $result['revisionIDFieldInfo'];
51 $this->setRevisionMatchData('foundURI', $revision_id_info['value']);
52 $this->setRevisionMatchData(
54 $revision_id_info['validDomain']);
56 // If there is no "Differential Revision:" field in the message, try to
57 // identify the revision by doing a hash lookup.
59 if (!$revision_id && $hashes) {
61 foreach ($hashes as $hash) {
62 $hash_list[] = array($hash->getHashType(), $hash->getHashValue());
64 $revisions = id(new DifferentialRevisionQuery())
65 ->setViewer(PhabricatorUser
::getOmnipotentUser())
67 ->withCommitHashes($hash_list)
71 $revision = $this->pickBestRevision($revisions);
73 $fields['revisionID'] = $revision->getID();
74 $revision_hashes = $revision->getHashes();
76 $revision_hashes = DiffusionCommitHash
::convertArrayToObjects(
78 $revision_hashes = mpull($revision_hashes, null, 'getHashType');
80 // sort the hashes in the order the mighty
81 // @{class:ArcanstDifferentialRevisionHash} does; probably unnecessary
82 // but should future proof things nicely.
83 $revision_hashes = array_select_keys(
85 ArcanistDifferentialRevisionHash
::getTypes());
87 foreach ($hashes as $hash) {
88 $revision_hash = idx($revision_hashes, $hash->getHashType());
89 if (!$revision_hash) {
92 if ($revision_hash->getHashValue() == $hash->getHashValue()) {
93 $this->setRevisionMatchData(
95 $hash->getHashType());
96 $this->setRevisionMatchData(
98 $hash->getHashValue());
110 * When querying for revisions by hash, more than one revision may be found.
111 * This function identifies the "best" revision from such a set. Typically,
112 * there is only one revision found. Otherwise, we try to pick an accepted
113 * revision first, followed by an open revision, and otherwise we go with a
114 * closed or abandoned revision as a last resort.
116 private function pickBestRevision(array $revisions) {
117 assert_instances_of($revisions, 'DifferentialRevision');
119 // If we have more than one revision of a given status, choose the most
120 // recently updated one.
121 $revisions = msort($revisions, 'getDateModified');
122 $revisions = array_reverse($revisions);
124 // Try to find an accepted revision first.
125 foreach ($revisions as $revision) {
126 if ($revision->isAccepted()) {
131 // Try to find an open revision.
132 foreach ($revisions as $revision) {
133 if (!$revision->isClosed()) {
138 // Settle for whatever's left.
139 return head($revisions);