Differential D21658 Diff 51535 src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php
Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | final class DiffusionLowLevelResolveRefsQuery | ||||
} | } | ||||
private function resolveGitRefs() { | private function resolveGitRefs() { | ||||
$repository = $this->getRepository(); | $repository = $this->getRepository(); | ||||
$unresolved = array_fuse($this->refs); | $unresolved = array_fuse($this->refs); | ||||
$results = array(); | $results = array(); | ||||
$possible_symbols = array(); | |||||
foreach ($unresolved as $ref) { | |||||
// See T13647. If this symbol is exactly 40 hex characters long, it may | |||||
// never resolve as a branch or tag name. Filter these symbols out for | |||||
// consistency with Git behavior -- and to avoid an expensive | |||||
// "git for-each-ref" when resolving only commit hashes, which happens | |||||
// during repository updates. | |||||
if (preg_match('(^[a-f0-9]{40}\z)', $ref)) { | |||||
continue; | |||||
} | |||||
$possible_symbols[$ref] = $ref; | |||||
} | |||||
// First, resolve branches and tags. | // First, resolve branches and tags. | ||||
if ($possible_symbols) { | |||||
$ref_map = id(new DiffusionLowLevelGitRefQuery()) | $ref_map = id(new DiffusionLowLevelGitRefQuery()) | ||||
->setRepository($repository) | ->setRepository($repository) | ||||
->withRefTypes( | ->withRefTypes( | ||||
array( | array( | ||||
PhabricatorRepositoryRefCursor::TYPE_BRANCH, | PhabricatorRepositoryRefCursor::TYPE_BRANCH, | ||||
PhabricatorRepositoryRefCursor::TYPE_TAG, | PhabricatorRepositoryRefCursor::TYPE_TAG, | ||||
)) | )) | ||||
->execute(); | ->execute(); | ||||
$ref_map = mgroup($ref_map, 'getShortName'); | $ref_map = mgroup($ref_map, 'getShortName'); | ||||
$tag_prefix = 'refs/tags/'; | $tag_prefix = 'refs/tags/'; | ||||
foreach ($unresolved as $ref) { | foreach ($possible_symbols as $ref) { | ||||
if (empty($ref_map[$ref])) { | if (empty($ref_map[$ref])) { | ||||
continue; | continue; | ||||
} | } | ||||
foreach ($ref_map[$ref] as $result) { | foreach ($ref_map[$ref] as $result) { | ||||
$fields = $result->getRawFields(); | $fields = $result->getRawFields(); | ||||
$objectname = idx($fields, 'refname'); | $objectname = idx($fields, 'refname'); | ||||
if (!strncmp($objectname, $tag_prefix, strlen($tag_prefix))) { | if (!strncmp($objectname, $tag_prefix, strlen($tag_prefix))) { | ||||
$type = 'tag'; | $type = 'tag'; | ||||
} else { | } else { | ||||
$type = 'branch'; | $type = 'branch'; | ||||
} | } | ||||
$info = array( | $info = array( | ||||
'type' => $type, | 'type' => $type, | ||||
'identifier' => $result->getCommitIdentifier(), | 'identifier' => $result->getCommitIdentifier(), | ||||
); | ); | ||||
if ($type == 'tag') { | if ($type == 'tag') { | ||||
$alternate = idx($fields, 'objectname'); | $alternate = idx($fields, 'objectname'); | ||||
if ($alternate) { | if ($alternate) { | ||||
$info['alternate'] = $alternate; | $info['alternate'] = $alternate; | ||||
} | } | ||||
} | } | ||||
$results[$ref][] = $info; | $results[$ref][] = $info; | ||||
} | } | ||||
unset($unresolved[$ref]); | unset($unresolved[$ref]); | ||||
} | } | ||||
} | |||||
// If we resolved everything, we're done. | // If we resolved everything, we're done. | ||||
if (!$unresolved) { | if (!$unresolved) { | ||||
return $results; | return $results; | ||||
} | } | ||||
// Try to resolve anything else. This stuff either doesn't exist or is | // Try to resolve anything else. This stuff either doesn't exist or is | ||||
// some ref like "HEAD^^^". | // some ref like "HEAD^^^". | ||||
▲ Show 20 Lines • Show All 255 Lines • Show Last 20 Lines |