diff --git a/src/land/engine/ArcanistMercurialLandEngine.php b/src/land/engine/ArcanistMercurialLandEngine.php --- a/src/land/engine/ArcanistMercurialLandEngine.php +++ b/src/land/engine/ArcanistMercurialLandEngine.php @@ -7,9 +7,19 @@ $api = $this->getRepositoryAPI(); $log = $this->getLogEngine(); - $bookmark = $api->getActiveBookmark(); - if ($bookmark !== null) { + $markers = $api->newMarkerRefQuery() + ->withIsActive(true) + ->execute(); + + $bookmark = null; + foreach ($markers as $marker) { + if ($marker->isBookmark()) { + $bookmark = $marker->getName(); + break; + } + } + if ($bookmark !== null) { $log->writeStatus( pht('SOURCE'), pht( @@ -19,50 +29,96 @@ return array($bookmark); } - $branch = $api->getBranchName(); - if ($branch !== null) { + $branch = null; + foreach ($markers as $marker) { + if ($marker->isBranch()) { + $branch = $marker->getName(); + break; + } + } + if ($branch !== null) { $log->writeStatus( pht('SOURCE'), pht( - 'Landing the current branch, "%s".', + 'Landing the active branch, "%s".', $branch)); return array($branch); } - throw new Exception(pht('TODO: Operate on raw revision.')); + $commit = $api->getCanonicalRevisionName('.'); + + $log->writeStatus( + pht('SOURCE'), + pht( + 'Landing the active commit, "%s".', + $this->getDisplayHash($commit))); + + return array($commit); } protected function resolveSymbols(array $symbols) { assert_instances_of($symbols, 'ArcanistLandSymbol'); $api = $this->getRepositoryAPI(); - foreach ($symbols as $symbol) { - $raw_symbol = $symbol->getSymbol(); + $marker_types = array( + ArcanistMarkerRef::TYPE_BOOKMARK, + ArcanistMarkerRef::TYPE_BRANCH, + ); - if ($api->isBookmark($raw_symbol)) { - $hash = $api->getBookmarkCommitHash($raw_symbol); - $symbol->setCommit($hash); + $unresolved = $symbols; + foreach ($marker_types as $marker_type) { + $markers = $api->newMarkerRefQuery() + ->withMarkerTypes(array($marker_type)) + ->execute(); - // TODO: Set that this is a bookmark? + $markers = mgroup($markers, 'getName'); - continue; + foreach ($unresolved as $key => $symbol) { + $raw_symbol = $symbol->getSymbol(); + + $named_markers = idx($markers, $raw_symbol); + if (!$named_markers) { + continue; + } + + if (count($named_markers) > 1) { + throw new PhutilArgumentUsageException( + pht( + 'Symbol "%s" is ambiguous: it matches multiple markers '. + '(of type "%s"). Use an unambiguous identifier.', + $raw_symbol, + $marker_type)); + } + + $marker = head($named_markers); + + $symbol->setCommit($marker->getCommitHash()); + + unset($unresolved[$key]); } + } - if ($api->isBranch($raw_symbol)) { - $hash = $api->getBranchCommitHash($raw_symbol); - $symbol->setCommit($hash); + foreach ($unresolved as $symbol) { + $raw_symbol = $symbol->getSymbol(); - // TODO: Set that this is a branch? + // TODO: This doesn't have accurate error behavior if the user provides + // a revset like "x::y". + try { + $commit = $api->getCanonicalRevisionName($raw_symbol); + } catch (CommandException $ex) { + $commit = null; + } - continue; + if ($commit === null) { + throw new PhutilArgumentUsageException( + pht( + 'Symbol "%s" does not identify a bookmark, branch, or commit.', + $raw_symbol)); } - throw new PhutilArgumentUsageException( - pht( - 'Symbol "%s" is not a bookmark or branch name.', - $raw_symbol)); + $symbol->setCommit($commit); } } diff --git a/src/repository/api/ArcanistMercurialAPI.php b/src/repository/api/ArcanistMercurialAPI.php --- a/src/repository/api/ArcanistMercurialAPI.php +++ b/src/repository/api/ArcanistMercurialAPI.php @@ -59,6 +59,7 @@ 'log -l 1 --template %s -r %s --', '{node}', $string); + return $stdout; } diff --git a/src/repository/marker/ArcanistMarkerRef.php b/src/repository/marker/ArcanistMarkerRef.php --- a/src/repository/marker/ArcanistMarkerRef.php +++ b/src/repository/marker/ArcanistMarkerRef.php @@ -109,6 +109,14 @@ return $this->isActive; } + public function isBookmark() { + return ($this->getMarkerType() === self::TYPE_BOOKMARK); + } + + public function isBranch() { + return ($this->getMarkerType() === self::TYPE_BRANCH); + } + public function attachCommitRef(ArcanistCommitRef $ref) { return $this->attachHardpoint(self::HARDPOINT_COMMITREF, $ref); } diff --git a/src/repository/marker/ArcanistRepositoryMarkerQuery.php b/src/repository/marker/ArcanistRepositoryMarkerQuery.php --- a/src/repository/marker/ArcanistRepositoryMarkerQuery.php +++ b/src/repository/marker/ArcanistRepositoryMarkerQuery.php @@ -4,7 +4,8 @@ extends Phobject { private $repositoryAPI; - private $types; + private $isActive; + private $markerTypes; private $commitHashes; private $ancestorCommitHashes; @@ -17,15 +18,20 @@ return $this->repositoryAPI; } - final public function withTypes(array $types) { - $this->types = array_fuse($types); + final public function withMarkerTypes(array $types) { + $this->markerTypes = array_fuse($types); + return $this; + } + + final public function withIsActive($active) { + $this->isActive = $active; return $this; } final public function execute() { $markers = $this->newRefMarkers(); - $types = $this->types; + $types = $this->markerTypes; if ($types !== null) { foreach ($markers as $key => $marker) { if (!isset($types[$marker->getMarkerType()])) { @@ -34,6 +40,14 @@ } } + if ($this->isActive !== null) { + foreach ($markers as $key => $marker) { + if ($marker->getIsActive() !== $this->isActive) { + unset($markers[$key]); + } + } + } + return $this->sortMarkers($markers); } @@ -53,11 +67,11 @@ } final protected function shouldQueryMarkerType($marker_type) { - if ($this->types === null) { + if ($this->markerTypes === null) { return true; } - return isset($this->types[$marker_type]); + return isset($this->markerTypes[$marker_type]); } } diff --git a/src/workflow/ArcanistMarkersWorkflow.php b/src/workflow/ArcanistMarkersWorkflow.php --- a/src/workflow/ArcanistMarkersWorkflow.php +++ b/src/workflow/ArcanistMarkersWorkflow.php @@ -11,7 +11,7 @@ $marker_type = $this->getWorkflowMarkerType(); $markers = $api->newMarkerRefQuery() - ->withTypes(array($marker_type)) + ->withMarkerTypes(array($marker_type)) ->execute(); $states = array();