{"record":{"id":"991cdf057eaccdc0","repo":"phacility/phabricator","slug":"specify-exactly-one-commit-to-extract","errorCode":null,"errorMessage":"Specify exactly one commit to extract.","messagePattern":"Specify exactly one commit to extract\\.","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"warning","filePath":"src/applications/differential/management/PhabricatorDifferentialExtractWorkflow.php","lineNumber":32,"sourceCode":"            'name' => 'extract',\n            'wildcard' => true,\n            'help' => pht('Commit to extract.'),\n          ),\n        ));\n  }\n\n  public function execute(PhutilArgumentParser $args) {\n    $viewer = $this->getViewer();\n\n    $extract = $args->getArg('extract');\n\n    if (!$extract) {\n      throw new PhutilArgumentUsageException(\n        pht('Specify a commit to extract the diff from.'));\n    }\n\n    if (count($extract) > 1) {\n      throw new PhutilArgumentUsageException(\n        pht('Specify exactly one commit to extract.'));\n    }\n\n    $extract = head($extract);\n\n    $commit = id(new DiffusionCommitQuery())\n      ->setViewer($viewer)\n      ->withIdentifiers(array($extract))\n      ->executeOne();\n\n    if (!$commit) {\n      throw new PhutilArgumentUsageException(\n        pht(\n          'Commit \"%s\" is not valid.',\n          $extract));\n    }\n\n    $diff = id(new DifferentialDiffExtractionEngine())","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/differential/management/PhabricatorDifferentialExtractWorkflow.php#L14-L50","documentation":"./bin/differential extract accepts exactly one commit to convert into a Differential diff; if the wildcard 'extract' argument contains more than one identifier, the workflow throws this usage exception. The limit exists because each extraction creates a diff and echoes its URI, which is only meaningful for a single commit.","triggerScenarios":"Passing several commits ('./bin/differential extract a b c'); an unquoted glob that expands to multiple refs (e.g., ./bin/differential extract tags/*); a loop bug that accumulates identifiers into one command line.","commonSituations":"Shell scripts using $@ unquoted where one ref expands to many; users trying to batch-extract; CI passing a ref list instead of one SHA.","solutions":["Run one extraction per commit, or wrap in a loop: for c in $commits; do ./bin/differential extract \"$c\"; done","Quote the identifier and ensure the variable holds exactly one ref","If you need diffs for many commits, script repeated single extractions"],"exampleFix":"# before\nphabricator/ $ ./bin/differential extract rPabc1234 rPdef5678\nUsage Exception: Specify exactly one commit to extract.\n\n# after\nphabricator/ $ ./bin/differential extract rPabc1234 && \\\n  phabricator/ $ ./bin/differential extract rPdef5678","handlingStrategy":"validation","validationCode":"// If iterating commits, enforce one per invocation:\nforeach ($commits as $commit) {\n  // invoke './bin/differential extract <commit>' once per element\n}","typeGuard":"function isSingleIdentifier(array $argv) {\n  return count($argv) === 1;\n}","tryCatchPattern":"try {\n  $workflow->execute($args);\n} catch (PhutilArgumentUsageException $ex) {\n  // Too many commits: split the argument list and run one extraction each.\n}","preventionTips":["Quote single refs and avoid unquoted glob expansion (tags/*) on the command line","Wrap batch needs in a shell loop rather than passing many identifiers at once"],"tags":["phabricator","differential","cli","extract","argument-count","usage-error"],"backgroundTag":"cli-usage-error","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}