Page MenuHomePhabricator

The "arc amend" workflow does not work on Mercurial repositories
Closed, ResolvedPublic

Description

Running arc amend on a Mercurial repository results in an exception.

[2021-09-03 14:04:19] EXCEPTION: (ArcanistCapabilityNotSupportedException) This repository API ('hg') does not support the requested capability. at [<arcanist>/src/repository/api/ArcanistRepositoryAPI.php:733]
arcanist(head=master, ref.master=76a2976fd9a4)
  #0 ArcanistRepositoryAPI::newCurrentCommitSymbol() called at [<arcanist>/src/repository/api/ArcanistRepositoryAPI.php:727]
  #1 ArcanistRepositoryAPI::newCurrentCommitRef() called at [<arcanist>/src/repository/api/ArcanistRepositoryAPI.php:719]
  #2 ArcanistRepositoryAPI::getCurrentCommitRef() called at [<arcanist>/src/repository/api/ArcanistRepositoryAPI.php:707]
  #3 ArcanistRepositoryAPI::newCurrentWorkingCopyStateRef() called at [<arcanist>/src/repository/api/ArcanistRepositoryAPI.php:699]
  #4 ArcanistRepositoryAPI::getCurrentWorkingCopyStateRef() called at [<arcanist>/src/workflow/ArcanistAmendWorkflow.php:85]
  #5 ArcanistAmendWorkflow::runWorkflow(PhutilArgumentParser) called at [<arcanist>/src/workflow/ArcanistWorkflow.php:227]
  #6 ArcanistWorkflow::executeWorkflow(PhutilArgumentParser) called at [<arcanist>/src/toolset/ArcanistPhutilWorkflow.php:21]
  #7 ArcanistPhutilWorkflow::execute(PhutilArgumentParser) called at [<arcanist>/src/parser/argument/PhutilArgumentParser.php:492]
  #8 PhutilArgumentParser::parseWorkflowsFull(array) called at [<arcanist>/src/runtime/ArcanistRuntime.php:171]
  #9 ArcanistRuntime::executeCore(array) called at [<arcanist>/src/runtime/ArcanistRuntime.php:37]
  #10 ArcanistRuntime::execute(array) called at [<arcanist>/support/init/init-arcanist.php:6]
  #11 require_once(string) called at [<arcanist>/bin/arc:10]

The cause appears to be that the workflow is determining that working copy state info is needed and then calls ArcanistRepositoryAPI::getCurrentWorkingCopyRefState() which eventually calls ArcanistRepositoryAPI::newCurrentCommitSymbol() which is not implemented in ArcanistMercurialAPI.

ArcanistAmendWorkflow.php
$need_state =
  ($revision_symbol === null) ||
  (!$is_show);

if ($need_state) {
  $state_ref = $repository_api->getCurrentWorkingCopyStateRef();

  $this->loadHardpoints(
    $state_ref,
    ArcanistWorkingCopyStateRef::HARDPOINT_REVISIONREFS);

  $revision_refs = $state_ref->getRevisionRefs();
}

It's not clear whether there's an appropriate implementation of newCurrentCommitSymbol() for Mercurial. In Git this returns HEAD however to my knowledge the only way to refer to the current working commit in Mercurial is . which I don't think will be appropriate with how these symbols end up being resolved.


Additionally there looks to be a typo in the requireAmendSupport() function causing it to return early before checking for uncommitted changes

ArcanistAmendWorkflow.php
private function requireAmendSupport(ArcanistRepositoryAPI $api) {
  if (!$api->supportsAmend()) { /* ... */ }

  if ($this->isHistoryImmutable()) { /* ... */ }

  return;

  if ($api->getUncommittedChanges()) {
    // TODO: Make this class of error show the uncommitted changes.

    // TODO: This only needs to check for staged-but-uncommitted changes.
    // We can safely amend with untracked and unstaged changes.

    throw new PhutilArgumentUsageException(
      pht(
        'You have uncommitted changes in this working copy. Commit or '.
        'revert them before proceeding.'));
  }
}