Page MenuHomePhabricator

D7484.diff
No OneTemporary

D7484.diff

Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -151,7 +151,6 @@
'ConduitAPI_diffusion_createcomment_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_createcomment_Method.php',
'ConduitAPI_diffusion_diffquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_diffquery_Method.php',
'ConduitAPI_diffusion_existsquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_existsquery_Method.php',
- 'ConduitAPI_diffusion_expandshortcommitquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_expandshortcommitquery_Method.php',
'ConduitAPI_diffusion_filecontentquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_filecontentquery_Method.php',
'ConduitAPI_diffusion_findsymbols_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_findsymbols_Method.php',
'ConduitAPI_diffusion_getcommits_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_getcommits_Method.php',
@@ -164,8 +163,8 @@
'ConduitAPI_diffusion_rawdiffquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_rawdiffquery_Method.php',
'ConduitAPI_diffusion_readmequery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_readmequery_Method.php',
'ConduitAPI_diffusion_refsquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_refsquery_Method.php',
+ 'ConduitAPI_diffusion_resolverefs_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_resolverefs_Method.php',
'ConduitAPI_diffusion_searchquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_searchquery_Method.php',
- 'ConduitAPI_diffusion_stablecommitnamequery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_stablecommitnamequery_Method.php',
'ConduitAPI_diffusion_tagsquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_tagsquery_Method.php',
'ConduitAPI_feed_Method' => 'applications/feed/conduit/ConduitAPI_feed_Method.php',
'ConduitAPI_feed_publish_Method' => 'applications/feed/conduit/ConduitAPI_feed_publish_Method.php',
@@ -472,20 +471,16 @@
'DiffusionDiffController' => 'applications/diffusion/controller/DiffusionDiffController.php',
'DiffusionDoorkeeperCommitFeedStoryPublisher' => 'applications/diffusion/doorkeeper/DiffusionDoorkeeperCommitFeedStoryPublisher.php',
'DiffusionEmptyResultView' => 'applications/diffusion/view/DiffusionEmptyResultView.php',
- 'DiffusionExpandCommitQueryException' => 'applications/diffusion/exception/DiffusionExpandCommitQueryException.php',
- 'DiffusionExpandShortNameQuery' => 'applications/diffusion/query/expandshortname/DiffusionExpandShortNameQuery.php',
'DiffusionExternalController' => 'applications/diffusion/controller/DiffusionExternalController.php',
'DiffusionFileContent' => 'applications/diffusion/data/DiffusionFileContent.php',
'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionFileContentQuery.php',
'DiffusionGitBranch' => 'applications/diffusion/data/DiffusionGitBranch.php',
'DiffusionGitBranchTestCase' => 'applications/diffusion/data/__tests__/DiffusionGitBranchTestCase.php',
'DiffusionGitCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionGitCommitParentsQuery.php',
- 'DiffusionGitExpandShortNameQuery' => 'applications/diffusion/query/expandshortname/DiffusionGitExpandShortNameQuery.php',
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php',
'DiffusionGitRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php',
'DiffusionGitRequest' => 'applications/diffusion/request/DiffusionGitRequest.php',
'DiffusionGitResponse' => 'applications/diffusion/response/DiffusionGitResponse.php',
- 'DiffusionGitStableCommitNameQuery' => 'applications/diffusion/query/stablecommitname/DiffusionGitStableCommitNameQuery.php',
'DiffusionHistoryController' => 'applications/diffusion/controller/DiffusionHistoryController.php',
'DiffusionHistoryTableView' => 'applications/diffusion/view/DiffusionHistoryTableView.php',
'DiffusionHovercardEventListener' => 'applications/diffusion/events/DiffusionHovercardEventListener.php',
@@ -498,12 +493,11 @@
'DiffusionLowLevelGitRefQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php',
'DiffusionLowLevelMercurialBranchesQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialBranchesQuery.php',
'DiffusionLowLevelQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelQuery.php',
+ 'DiffusionLowLevelResolveRefsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php',
'DiffusionMercurialCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionMercurialCommitParentsQuery.php',
- 'DiffusionMercurialExpandShortNameQuery' => 'applications/diffusion/query/expandshortname/DiffusionMercurialExpandShortNameQuery.php',
'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php',
'DiffusionMercurialRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php',
'DiffusionMercurialRequest' => 'applications/diffusion/request/DiffusionMercurialRequest.php',
- 'DiffusionMercurialStableCommitNameQuery' => 'applications/diffusion/query/stablecommitname/DiffusionMercurialStableCommitNameQuery.php',
'DiffusionPathChange' => 'applications/diffusion/data/DiffusionPathChange.php',
'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/DiffusionPathChangeQuery.php',
'DiffusionPathCompleteController' => 'applications/diffusion/controller/DiffusionPathCompleteController.php',
@@ -542,12 +536,10 @@
'DiffusionSSHWorkflow' => 'applications/diffusion/ssh/DiffusionSSHWorkflow.php',
'DiffusionSetPasswordPanel' => 'applications/diffusion/panel/DiffusionSetPasswordPanel.php',
'DiffusionSetupException' => 'applications/diffusion/exception/DiffusionSetupException.php',
- 'DiffusionStableCommitNameQuery' => 'applications/diffusion/query/stablecommitname/DiffusionStableCommitNameQuery.php',
'DiffusionSvnCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionSvnCommitParentsQuery.php',
'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php',
'DiffusionSvnRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionSvnRawDiffQuery.php',
'DiffusionSvnRequest' => 'applications/diffusion/request/DiffusionSvnRequest.php',
- 'DiffusionSvnStableCommitNameQuery' => 'applications/diffusion/query/stablecommitname/DiffusionSvnStableCommitNameQuery.php',
'DiffusionSymbolController' => 'applications/diffusion/controller/DiffusionSymbolController.php',
'DiffusionSymbolQuery' => 'applications/diffusion/query/DiffusionSymbolQuery.php',
'DiffusionTagListController' => 'applications/diffusion/controller/DiffusionTagListController.php',
@@ -2366,7 +2358,6 @@
'ConduitAPI_diffusion_createcomment_Method' => 'ConduitAPI_diffusion_Method',
'ConduitAPI_diffusion_diffquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
'ConduitAPI_diffusion_existsquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
- 'ConduitAPI_diffusion_expandshortcommitquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
'ConduitAPI_diffusion_filecontentquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
'ConduitAPI_diffusion_findsymbols_Method' => 'ConduitAPI_diffusion_Method',
'ConduitAPI_diffusion_getcommits_Method' => 'ConduitAPI_diffusion_Method',
@@ -2379,8 +2370,8 @@
'ConduitAPI_diffusion_rawdiffquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
'ConduitAPI_diffusion_readmequery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
'ConduitAPI_diffusion_refsquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
+ 'ConduitAPI_diffusion_resolverefs_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
'ConduitAPI_diffusion_searchquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
- 'ConduitAPI_diffusion_stablecommitnamequery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
'ConduitAPI_diffusion_tagsquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
'ConduitAPI_feed_Method' => 'ConduitAPIMethod',
'ConduitAPI_feed_publish_Method' => 'ConduitAPI_feed_Method',
@@ -2681,18 +2672,14 @@
'DiffusionDiffController' => 'DiffusionController',
'DiffusionDoorkeeperCommitFeedStoryPublisher' => 'DoorkeeperFeedStoryPublisher',
'DiffusionEmptyResultView' => 'DiffusionView',
- 'DiffusionExpandCommitQueryException' => 'Exception',
- 'DiffusionExpandShortNameQuery' => 'DiffusionQuery',
'DiffusionExternalController' => 'DiffusionController',
'DiffusionFileContentQuery' => 'DiffusionQuery',
'DiffusionGitBranchTestCase' => 'PhabricatorTestCase',
'DiffusionGitCommitParentsQuery' => 'DiffusionCommitParentsQuery',
- 'DiffusionGitExpandShortNameQuery' => 'DiffusionExpandShortNameQuery',
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionGitRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionGitRequest' => 'DiffusionRequest',
'DiffusionGitResponse' => 'AphrontResponse',
- 'DiffusionGitStableCommitNameQuery' => 'DiffusionStableCommitNameQuery',
'DiffusionHistoryController' => 'DiffusionController',
'DiffusionHistoryTableView' => 'DiffusionView',
'DiffusionHovercardEventListener' => 'PhabricatorEventListener',
@@ -2704,12 +2691,11 @@
'DiffusionLowLevelGitRefQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelMercurialBranchesQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelQuery' => 'Phobject',
+ 'DiffusionLowLevelResolveRefsQuery' => 'DiffusionLowLevelQuery',
'DiffusionMercurialCommitParentsQuery' => 'DiffusionCommitParentsQuery',
- 'DiffusionMercurialExpandShortNameQuery' => 'DiffusionExpandShortNameQuery',
'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionMercurialRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionMercurialRequest' => 'DiffusionRequest',
- 'DiffusionMercurialStableCommitNameQuery' => 'DiffusionStableCommitNameQuery',
'DiffusionPathCompleteController' => 'DiffusionController',
'DiffusionPathQueryTestCase' => 'PhabricatorTestCase',
'DiffusionPathValidateController' => 'DiffusionController',
@@ -2743,12 +2729,10 @@
'DiffusionSSHWorkflow' => 'PhabricatorSSHWorkflow',
'DiffusionSetPasswordPanel' => 'PhabricatorSettingsPanel',
'DiffusionSetupException' => 'AphrontUsageException',
- 'DiffusionStableCommitNameQuery' => 'DiffusionQuery',
'DiffusionSvnCommitParentsQuery' => 'DiffusionCommitParentsQuery',
'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionSvnRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionSvnRequest' => 'DiffusionRequest',
- 'DiffusionSvnStableCommitNameQuery' => 'DiffusionStableCommitNameQuery',
'DiffusionSymbolController' => 'DiffusionController',
'DiffusionSymbolQuery' => 'PhabricatorOffsetPagedQuery',
'DiffusionTagListController' => 'DiffusionController',
Index: src/applications/diffusion/conduit/ConduitAPI_diffusion_browsequery_Method.php
===================================================================
--- src/applications/diffusion/conduit/ConduitAPI_diffusion_browsequery_Method.php
+++ src/applications/diffusion/conduit/ConduitAPI_diffusion_browsequery_Method.php
@@ -198,7 +198,7 @@
list($entire_manifest) = $repository->execxLocalCommand(
'manifest --rev %s',
- $commit);
+ hgsprintf('%s', $commit));
$entire_manifest = explode("\n", $entire_manifest);
$results = array();
Index: src/applications/diffusion/conduit/ConduitAPI_diffusion_expandshortcommitquery_Method.php
===================================================================
--- src/applications/diffusion/conduit/ConduitAPI_diffusion_expandshortcommitquery_Method.php
+++ /dev/null
@@ -1,70 +0,0 @@
-<?php
-
-/**
- * @group conduit
- */
-final class ConduitAPI_diffusion_expandshortcommitquery_Method
- extends ConduitAPI_diffusion_abstractquery_Method {
-
- public function __construct() {
- $this->setShouldCreateDiffusionRequest(false);
- }
-
- public function getMethodDescription() {
- return
- 'Expands a short commit name to its full glory.';
- }
-
- public function defineReturnType() {
- return 'array';
- }
-
- protected function defineCustomParamTypes() {
- return array(
- 'commit' => 'required string',
- );
- }
-
- protected function defineCustomErrorTypes() {
- return array(
- 'ERR-MISSING-COMMIT' => pht(
- 'Bad commit.'),
- 'ERR-INVALID-COMMIT' => pht(
- 'Invalid object name.'),
- 'ERR-UNPARSEABLE-OUTPUT' => pht(
- 'Unparseable output from cat-file.')
- );
- }
-
- protected function getGitResult(ConduitAPIRequest $request) {
- return $this->getGitOrMercurialResult($request);
- }
- protected function getMercurialResult(ConduitAPIRequest $request) {
- return $this->getGitOrMercurialResult($request);
- }
-
- private function getGitOrMercurialResult(ConduitAPIRequest $request) {
- $repository = $this->getRepository($request);
- $query = DiffusionExpandShortNameQuery::newFromRepository($repository);
- $query->setCommit($request->getValue('commit'));
- try {
- $result = $query->expand();
- return $result;
- } catch (DiffusionExpandCommitQueryException $e) {
- switch ($e->getStatusCode()) {
- case DiffusionExpandCommitQueryException::CODE_INVALID:
- throw id(new ConduitException('ERR-INVALID-COMMIT'))
- ->setErrorDescription($e->getMessage());
- break;
- case DiffusionExpandCommitQueryException::CODE_MISSING:
- throw id(new ConduitException('ERR-MISSING-COMMIT'))
- ->setErrorDescription($e->getMessage());
- break;
- case DiffusionExpandCommitQueryException::CODE_UNPARSEABLE:
- throw id(new ConduitException('ERR-UNPARSEABLE-OUTPUT'))
- ->setErrorDescription($e->getMessage());
- break;
- }
- }
- }
-}
Index: src/applications/diffusion/conduit/ConduitAPI_diffusion_resolverefs_Method.php
===================================================================
--- /dev/null
+++ src/applications/diffusion/conduit/ConduitAPI_diffusion_resolverefs_Method.php
@@ -0,0 +1,29 @@
+<?php
+
+final class ConduitAPI_diffusion_resolverefs_Method
+ extends ConduitAPI_diffusion_abstractquery_Method {
+
+ public function getMethodDescription() {
+ return pht('Resolve references into stable, canonical identifiers.');
+ }
+
+ public function defineReturnType() {
+ return 'dict<string, list<dict<string, wild>>>';
+ }
+
+ protected function defineCustomParamTypes() {
+ return array(
+ 'refs' => 'required list<string>',
+ );
+ }
+
+ protected function getResult(ConduitAPIRequest $request) {
+ $refs = $request->getValue('refs');
+
+ return id(new DiffusionLowLevelResolveRefsQuery())
+ ->setRepository($this->getDiffusionRequest()->getRepository())
+ ->withRefs($refs)
+ ->execute();
+ }
+
+}
Index: src/applications/diffusion/conduit/ConduitAPI_diffusion_stablecommitnamequery_Method.php
===================================================================
--- src/applications/diffusion/conduit/ConduitAPI_diffusion_stablecommitnamequery_Method.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-/**
- * @group conduit
- */
-final class ConduitAPI_diffusion_stablecommitnamequery_Method
- extends ConduitAPI_diffusion_abstractquery_Method {
-
- public function __construct() {
- $this->setShouldCreateDiffusionRequest(false);
- }
-
- public function getMethodDescription() {
- return
- 'Identifies the latest commit in a repository. Repositories with '.
- 'branch support must specify which branch to look at.';
- }
-
- public function defineReturnType() {
- return 'string';
- }
-
- protected function defineCustomParamTypes() {
- return array(
- 'branch' => 'required string',
- );
- }
-
- protected function getResult(ConduitAPIRequest $request) {
- $repository = $this->getRepository($request);
- $query = DiffusionStableCommitNameQuery::newFromRepository($repository);
- $query->setBranch($request->getValue('branch'));
- return $query->load();
- }
-}
Index: src/applications/diffusion/exception/DiffusionExpandCommitQueryException.php
===================================================================
--- src/applications/diffusion/exception/DiffusionExpandCommitQueryException.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-final class DiffusionExpandCommitQueryException extends Exception {
- const CODE_UNPARSEABLE = 'unparseable';
- const CODE_MISSING = 'missing';
- const CODE_INVALID = 'invalid';
-
- private $statusCode;
- public function getStatusCode() {
- return $this->statusCode;
- }
-
- public function __construct($status_code /* ... */) {
- $args = func_get_args();
- $this->statusCode = $args[0];
-
- $args = array_slice($args, 1);
- call_user_func_array(array('parent', '__construct'), $args);
- }
-
-}
Index: src/applications/diffusion/query/expandshortname/DiffusionExpandShortNameQuery.php
===================================================================
--- src/applications/diffusion/query/expandshortname/DiffusionExpandShortNameQuery.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-abstract class DiffusionExpandShortNameQuery extends DiffusionQuery {
-
- private $commit;
- private $commitType = 'commit';
- private $tagContent;
- private $repository;
-
- public function setCommit($commit) {
- $this->commit = $commit;
- }
- public function getCommit() {
- return $this->commit;
- }
-
- public function setRepository(PhabricatorRepository $repository) {
- $this->repository = $repository;
- return $this;
- }
- public function getRepository() {
- return $this->repository;
- }
-
- protected function setCommitType($type) {
- $this->commitType = $type;
- return $this;
- }
- protected function setTagContent($content) {
- $this->tagContent = $content;
- return $this;
- }
-
- final public static function newFromRepository(
- PhabricatorRepository $repository) {
-
- $obj = parent::initQueryObject(__CLASS__, $repository);
- $obj->setRepository($repository);
- return $obj;
- }
-
- final public function expand() {
- $this->executeQuery();
-
- return array(
- 'commit' => $this->commit,
- 'commitType' => $this->commitType,
- 'tagContent' => $this->tagContent);
- }
-
-}
Index: src/applications/diffusion/query/expandshortname/DiffusionGitExpandShortNameQuery.php
===================================================================
--- src/applications/diffusion/query/expandshortname/DiffusionGitExpandShortNameQuery.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-final class DiffusionGitExpandShortNameQuery
-extends DiffusionExpandShortNameQuery {
-
- protected function executeQuery() {
- $repository = $this->getRepository();
- $commit = $this->getCommit();
-
- $future = $repository->getLocalCommandFuture(
- 'cat-file --batch');
- $future->write($commit);
- list($stdout) = $future->resolvex();
-
- list($hash, $type) = explode(' ', $stdout);
- if ($type == 'missing') {
- throw new DiffusionExpandCommitQueryException(
- DiffusionExpandCommitQueryException::CODE_MISSING,
- "Bad commit '{$commit}'.");
- }
-
- switch ($type) {
- case 'tag':
- $this->setCommitType('tag');
-
- $matches = null;
- $ok = preg_match(
- '/^object ([a-f0-9]+)$.*?\n\n(.*)$/sm',
- $stdout,
- $matches);
- if (!$ok) {
- throw new DiffusionExpandCommitQueryException(
- DiffusionExpandCommitQueryException::CODE_UNPARSEABLE,
- "Unparseable output from cat-file: {$stdout}");
- }
-
- $hash = $matches[1];
- $this->setTagContent(trim($matches[2]));
- break;
- case 'commit':
- break;
- default:
- throw new DiffusionExpandCommitQueryException(
- DiffusionExpandCommitQueryException::CODE_INVALID,
- "The reference '{$commit}' does not name a valid ".
- 'commit or a tag in this repository.');
- break;
- }
-
- $this->setCommit($hash);
- }
-}
Index: src/applications/diffusion/query/expandshortname/DiffusionMercurialExpandShortNameQuery.php
===================================================================
--- src/applications/diffusion/query/expandshortname/DiffusionMercurialExpandShortNameQuery.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-final class DiffusionMercurialExpandShortNameQuery
-extends DiffusionExpandShortNameQuery {
-
- protected function executeQuery() {
- $repository = $this->getRepository();
- $commit = $this->getCommit();
-
- list($full_hash) = $repository->execxLocalCommand(
- 'log --template=%s --rev %s',
- '{node}',
- $commit);
-
- $full_hash = explode("\n", trim($full_hash));
-
- // TODO: Show "multiple matching commits" if count is larger than 1. For
- // now, pick the first one.
-
- $this->setCommit(head($full_hash));
- }
-
-}
Index: src/applications/diffusion/query/lowlevel/DiffusionLowLevelQuery.php
===================================================================
--- src/applications/diffusion/query/lowlevel/DiffusionLowLevelQuery.php
+++ src/applications/diffusion/query/lowlevel/DiffusionLowLevelQuery.php
@@ -16,6 +16,10 @@
}
public function execute() {
+ if (!$this->getRepository()) {
+ throw new Exception("Call setRepository() before execute()!");
+ }
+
return $this->executeQuery();
}
Index: src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php
===================================================================
--- /dev/null
+++ src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php
@@ -0,0 +1,225 @@
+<?php
+
+/**
+ * Resolves references (like short commit names, branch names, tag names, etc.)
+ * into canonical, stable commit identifiers. This query works for all
+ * repository types.
+ */
+final class DiffusionLowLevelResolveRefsQuery
+ extends DiffusionLowLevelQuery {
+
+ private $refs;
+
+ public function withRefs(array $refs) {
+ $this->refs = $refs;
+ return $this;
+ }
+
+ public function executeQuery() {
+ if (!$this->refs) {
+ return array();
+ }
+
+ switch ($this->getRepository()->getVersionControlSystem()) {
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
+ $result = $this->resolveGitRefs();
+ break;
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
+ $result = $this->resolveMercurialRefs();
+ break;
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
+ $result = $this->resolveSubversionRefs();
+ break;
+ default:
+ throw new Exception("Unsupported repository type!");
+ }
+
+ return $result;
+ }
+
+ private function resolveGitRefs() {
+ $repository = $this->getRepository();
+
+ $future = $repository->getLocalCommandFuture('cat-file --batch-check');
+ $future->write(implode("\n", $this->refs));
+ list($stdout) = $future->resolvex();
+
+ $lines = explode("\n", rtrim($stdout, "\n"));
+ if (count($lines) !== count($this->refs)) {
+ throw new Exception("Unexpected line count from `git cat-file`!");
+ }
+
+ $hits = array();
+ $tags = array();
+
+ $lines = array_combine($this->refs, $lines);
+ foreach ($lines as $ref => $line) {
+ $parts = explode(' ', $line);
+ if (count($parts) < 2) {
+ throw new Exception("Failed to parse `git cat-file` output: {$line}");
+ }
+ list($identifier, $type) = $parts;
+
+ if ($type == 'missing') {
+ // This is either an ambiguous reference which resolves to several
+ // objects, or an invalid reference. For now, always treat it as
+ // invalid. It would be nice to resolve all possibilities for
+ // ambiguous references at some point, although the strategy for doing
+ // so isn't clear to me.
+ continue;
+ }
+
+ switch ($type) {
+ case 'commit':
+ break;
+ case 'tag':
+ $tags[] = $identifier;
+ break;
+ default:
+ throw new Exception(
+ "Unexpected object type from `git cat-file`: {$line}");
+ }
+
+ $hits[] = array(
+ 'ref' => $ref,
+ 'type' => $type,
+ 'identifier' => $identifier,
+ );
+ }
+
+ $tag_map = array();
+ if ($tags) {
+ // If some of the refs were tags, just load every tag in order to figure
+ // out which commits they map to. This might be somewhat inefficient in
+ // repositories with a huge number of tags.
+ $tag_refs = id(new DiffusionLowLevelGitRefQuery())
+ ->setRepository($repository)
+ ->withIsTag(true)
+ ->executeQuery();
+ foreach ($tag_refs as $tag_ref) {
+ $tag_map[$tag_ref->getShortName()] = $tag_ref->getCommitIdentifier();
+ }
+ }
+
+ $results = array();
+ foreach ($hits as $hit) {
+ $type = $hit['type'];
+ $ref = $hit['ref'];
+
+ $alternate = null;
+ if ($type == 'tag') {
+ $alternate = $identifier;
+ $identifier = idx($tag_map, $ref);
+ if (!$identifier) {
+ throw new Exception("Failed to look up tag '{$ref}'!");
+ }
+ }
+
+ $result = array(
+ 'type' => $type,
+ 'identifier' => $identifier,
+ );
+
+ if ($alternate !== null) {
+ $result['alternate'] = $alternate;
+ }
+
+ $results[$ref][] = $result;
+ }
+
+ return $results;
+ }
+
+ private function resolveMercurialRefs() {
+ $repository = $this->getRepository();
+
+ $futures = array();
+ foreach ($this->refs as $ref) {
+ // TODO: There was a note about `--rev 'a b'` not working for branches
+ // with spaces in their names in older code, but I suspect this was
+ // misidentified and resulted from the branch name being interpeted as
+ // a revset. Use hgsprintf() to avoid that. If this doesn't break for a
+ // bit, remove this comment. Otherwise, consider `-b %s --limit 1`.
+
+ $futures[$ref] = $repository->getLocalCommandFuture(
+ 'log --template=%s --rev %s',
+ '{node}',
+ hgsprintf('%s', $ref));
+ }
+
+ $results = array();
+ foreach (Futures($futures) as $ref => $future) {
+ try {
+ list($stdout) = $future->resolvex();
+ } catch (CommandException $ex) {
+ if (preg_match('/ambiguous identifier/', $ex->getStdErr())) {
+ // This indicates that the ref ambiguously matched several things.
+ // Eventually, it would be nice to return all of them, but it is
+ // unclear how to best do that. For now, treat it as a miss instead.
+ continue;
+ }
+ throw $ex;
+ }
+
+ // It doesn't look like we can figure out the type (commit/branch/rev)
+ // from this output very easily. For now, just call everything a commit.
+ $type = 'commit';
+
+ $results[$ref][] = array(
+ 'type' => $type,
+ 'identifier' => trim($stdout),
+ );
+ }
+
+ return $results;
+ }
+
+ private function resolveSubversionRefs() {
+ $repository = $this->getRepository();
+
+ $max_commit = id(new PhabricatorRepositoryCommit())
+ ->loadOneWhere(
+ 'repositoryID = %d ORDER BY epoch DESC, id DESC LIMIT 1',
+ $repository->getID());
+ if (!$max_commit) {
+ // This repository is empty or hasn't parsed yet, so none of the refs are
+ // going to resolve.
+ return array();
+ }
+
+ $max_commit_id = (int)$max_commit->getCommitIdentifier();
+
+ $results = array();
+ foreach ($this->refs as $ref) {
+ if ($ref == 'HEAD') {
+ // Resolve "HEAD" to mean "the most recent commit".
+ $results[$ref][] = array(
+ 'type' => 'commit',
+ 'identifier' => $max_commit_id,
+ );
+ continue;
+ }
+
+ if (!preg_match('/^\d+$/', $ref)) {
+ // This ref is non-numeric, so it doesn't resolve to anything.
+ continue;
+ }
+
+ // Resolve other commits if we can deduce their existence.
+
+ // TODO: When we import only part of a repository, we won't necessarily
+ // have all of the smaller commits. Should we fail to resolve them here
+ // for repositories with a subpath? It might let us simplify other things
+ // elsewhere.
+ if ((int)$ref <= $max_commit_id) {
+ $results[$ref][] = array(
+ 'type' => 'commit',
+ 'identifier' => (int)$ref,
+ );
+ }
+ }
+
+ return $results;
+ }
+
+}
Index: src/applications/diffusion/query/stablecommitname/DiffusionGitStableCommitNameQuery.php
===================================================================
--- src/applications/diffusion/query/stablecommitname/DiffusionGitStableCommitNameQuery.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-final class DiffusionGitStableCommitNameQuery
-extends DiffusionStableCommitNameQuery {
-
- protected function executeQuery() {
- $repository = $this->getRepository();
- $branch = $this->getBranch();
-
- if ($repository->isWorkingCopyBare()) {
- list($stdout) = $repository->execxLocalCommand(
- 'rev-parse --verify %s',
- $branch);
- } else {
- list($stdout) = $repository->execxLocalCommand(
- 'rev-parse --verify %s/%s',
- DiffusionBranchInformation::DEFAULT_GIT_REMOTE,
- $branch);
- }
-
- $commit = trim($stdout);
- return substr($commit, 0, 16);
- }
-}
Index: src/applications/diffusion/query/stablecommitname/DiffusionMercurialStableCommitNameQuery.php
===================================================================
--- src/applications/diffusion/query/stablecommitname/DiffusionMercurialStableCommitNameQuery.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-final class DiffusionMercurialStableCommitNameQuery
-extends DiffusionStableCommitNameQuery {
-
- protected function executeQuery() {
- $repository = $this->getRepository();
-
- // NOTE: For branches with spaces in their name like "a b", this
- // does not work properly:
- //
- // $ hg log --rev 'a b'
- //
- // We can use revsets instead:
- //
- // $ hg log --rev branch('a b')
- //
- // ...but they require a somewhat newer version of Mercurial. Instead,
- // use "-b" flag with limit 1 for greatest compatibility across
- // versions.
-
- list($stable_commit_name) = $repository->execxLocalCommand(
- 'log --template=%s -b %s --limit 1',
- '{node}',
- $this->getBranch());
-
- return $stable_commit_name;
- }
-
-}
Index: src/applications/diffusion/query/stablecommitname/DiffusionStableCommitNameQuery.php
===================================================================
--- src/applications/diffusion/query/stablecommitname/DiffusionStableCommitNameQuery.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-abstract class DiffusionStableCommitNameQuery extends DiffusionQuery {
-
- private $branch;
- private $repository;
-
- public function setBranch($branch) {
- $this->branch = $branch;
- return $this;
- }
- public function getBranch() {
- return $this->branch;
- }
-
- public function setRepository(PhabricatorRepository $repository) {
- $this->repository = $repository;
- return $this;
- }
- public function getRepository() {
- return $this->repository;
- }
-
- final public static function newFromRepository(
- PhabricatorRepository $repository) {
-
- $obj = parent::initQueryObject(__CLASS__, $repository);
- $obj->setRepository($repository);
- return $obj;
- }
-
- final public function load() {
- return $this->executeQuery();
- }
-}
Index: src/applications/diffusion/query/stablecommitname/DiffusionSvnStableCommitNameQuery.php
===================================================================
--- src/applications/diffusion/query/stablecommitname/DiffusionSvnStableCommitNameQuery.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-final class DiffusionSvnStableCommitNameQuery
-extends DiffusionStableCommitNameQuery {
-
- protected function executeQuery() {
- $repository = $this->getRepository();
-
- $commit = id(new PhabricatorRepositoryCommit())
- ->loadOneWhere(
- 'repositoryID = %d ORDER BY epoch DESC LIMIT 1',
- $repository->getID());
- if ($commit) {
- $stable_commit_name = $commit->getCommitIdentifier();
- } else {
- // For new repositories, we may not have parsed any commits yet. Call
- // the stable commit "1" and avoid fataling.
- $stable_commit_name = 1;
- }
-
- return $stable_commit_name;
- }
-}
Index: src/applications/diffusion/request/DiffusionRequest.php
===================================================================
--- src/applications/diffusion/request/DiffusionRequest.php
+++ src/applications/diffusion/request/DiffusionRequest.php
@@ -18,7 +18,6 @@
protected $symbolicCommit;
protected $commit;
protected $commitType = 'commit';
- protected $tagContent;
protected $branch;
protected $lint;
@@ -263,10 +262,6 @@
$this->getArcanistBranch());
}
- public function getTagContent() {
- return $this->tagContent;
- }
-
public function loadCommit() {
if (empty($this->repositoryCommit)) {
$repository = $this->getRepository();
@@ -624,26 +619,17 @@
}
final protected function expandCommitName() {
- if ($this->shouldInitFromConduit()) {
- $commit_data = DiffusionQuery::callConduitWithDiffusionRequest(
- $this->getUser(),
- $this,
- 'diffusion.expandshortcommitquery',
- array(
- 'commit' => $this->commit
- ));
- } else {
- $repository = $this->getRepository();
- $this->validateWorkingCopy($repository->getLocalPath());
- $query = DiffusionExpandShortNameQuery::newFromRepository(
- $repository);
- $query->setCommit($this->commit);
- $commit_data = $query->expand();
+ $results = $this->resolveRefs(array($this->commit));
+ $matches = idx($results, $this->commit, array());
+ if (count($results) !== 1) {
+ throw new Exception(
+ pht('Ref "%s" is ambiguous or does not exist.', $this->commit));
}
- $this->commit = $commit_data['commit'];
- $this->commitType = $commit_data['commitType'];
- $this->tagContent = $commit_data['tagContent'];
+ $match = head($matches);
+
+ $this->commit = $match['identifier'];
+ $this->commitType = $match['type'];
}
public function getCommitType() {
@@ -653,20 +639,43 @@
private function queryStableCommitName() {
if ($this->commit) {
$this->stableCommitName = $this->commit;
- } else if ($this->shouldInitFromConduit()) {
- $this->stableCommitName = DiffusionQuery::callConduitWithDiffusionRequest(
+ return $this->stableCommitName;
+ }
+
+ if ($this->getSupportsBranches()) {
+ $branch = $this->getBranch();
+ } else {
+ $branch = 'HEAD';
+ }
+
+ $results = $this->resolveRefs(array($branch));
+
+ $matches = idx($results, $branch, array());
+ if (count($matches) !== 1) {
+ throw new Exception(
+ pht('Ref "%s" is ambiguous or does not exist.', $branch));
+ }
+
+ $this->stableCommitName = idx(head($matches), 'identifier');
+ return $this->stableCommitName;
+ }
+
+ private function resolveRefs(array $refs) {
+ if ($this->shouldInitFromConduit()) {
+ return DiffusionQuery::callConduitWithDiffusionRequest(
$this->getUser(),
$this,
- 'diffusion.stablecommitnamequery',
+ 'diffusion.resolverefs',
array(
- 'branch' => $this->getBranch()
+ 'refs' => $refs,
));
} else {
- $query = DiffusionStableCommitNameQuery::newFromRepository(
- $this->getRepository());
- $query->setBranch($this->getBranch());
- $this->stableCommitName = $query->load();
+ return id(new DiffusionLowLevelResolveRefsQuery())
+ ->setRepository($this->getRepository())
+ ->withRefs($refs)
+ ->execute();
}
- return $this->stableCommitName;
}
+
+
}

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 19, 10:39 PM (15 h, 59 m ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/7f/k7/24jzoncpx3gdymqv
Default Alt Text
D7484.diff (36 KB)

Event Timeline