in src/workflow/ArcanistDiffWorkflow.php [1770:1970]
private function getCommitMessageFromUser() {
$conduit = $this->getConduit();
$template = null;
if (!$this->getArgument('verbatim')) {
$saved = $this->readScratchFile('create-message');
if ($saved) {
$where = $this->getReadableScratchFilePath('create-message');
$preview = explode("\n", $saved);
$preview = array_shift($preview);
$preview = trim($preview);
$preview = id(new PhutilUTF8StringTruncator())
->setMaximumGlyphs(64)
->truncateString($preview);
if ($preview) {
$preview = pht('Message begins:')."\n\n {$preview}\n\n";
} else {
$preview = null;
}
echo pht(
"You have a saved revision message in '%s'.\n%s".
"You can use this message, or discard it.",
$where,
$preview);
$use = phutil_console_confirm(
pht('Do you want to use this message?'),
$default_no = false);
if ($use) {
$template = $saved;
} else {
$this->removeScratchFile('create-message');
}
}
}
$template_is_default = false;
$notes = array();
$included = array();
list($fields, $notes, $included_commits) = $this->getDefaultCreateFields();
if ($template) {
$fields = array();
$notes = array();
} else {
if (!$fields) {
$template_is_default = true;
}
if ($notes) {
$commit = head($this->getRepositoryAPI()->getLocalCommitInformation());
$template = $commit['message'];
} else {
$revert_plan_check_paths = $this->getRevertPlanCheckPaths();
if (!array_key_exists('revertPlan', $fields)
&& !is_null($revert_plan_check_paths)
&& $this->modifiesPath($revert_plan_check_paths)) {
$fields['revertPlan'] = $this->getRevertPlan();
}
$template = $conduit->callMethodSynchronous(
'differential.getcommitmessage',
array(
'revision_id' => null,
'edit' => 'create',
'fields' => $fields,
));
}
}
$old_message = $template;
$included = array();
if ($included_commits) {
foreach ($included_commits as $commit) {
$included[] = ' '.$commit;
}
if (!$this->isRawDiffSource()) {
$message = pht(
'Included commits in branch %s:',
$this->getRepositoryAPI()->getBranchName());
} else {
$message = pht('Included commits:');
}
$included = array_merge(
array(
'',
$message,
'',
),
$included);
}
$issues = array_merge(
array(
pht('NEW DIFFERENTIAL REVISION'),
pht('Describe the changes in this new revision.'),
),
$included,
array(
'',
pht(
'arc could not identify any existing revision in your working copy.'),
pht('If you intended to update an existing revision, use:'),
'',
' $ arc diff --update <revision>',
));
if ($notes) {
$issues = array_merge($issues, array(''), $notes);
}
$done = false;
$first = true;
while (!$done) {
$template = rtrim($template, "\r\n")."\n\n";
foreach ($issues as $issue) {
$template .= rtrim('# '.$issue)."\n";
}
$template .= "\n";
if ($first && $this->getArgument('verbatim') && !$template_is_default) {
$new_template = $template;
} else {
$new_template = $this->newInteractiveEditor($template)
->setName('new-commit')
->editInteractively();
}
$first = false;
if ($template_is_default && ($new_template == $template)) {
throw new ArcanistUsageException(pht('Template not edited.'));
}
$template = ArcanistCommentRemover::removeComments($new_template);
// With --raw-command, we may not have a repository API.
if ($this->hasRepositoryAPI()) {
$repository_api = $this->getRepositoryAPI();
// special check for whether to amend here. optimizes a common git
// workflow. we can't do this for mercurial because the mq extension
// is popular and incompatible with hg commit --amend ; see T2011.
$should_amend = (count($included_commits) == 1 &&
$repository_api instanceof ArcanistGitAPI &&
$this->shouldAmend());
} else {
$should_amend = false;
}
if ($should_amend) {
$wrote = (rtrim($old_message) != rtrim($template));
if ($wrote) {
$repository_api->amendCommit($template);
$where = pht('commit message');
}
} else {
$wrote = $this->writeScratchFile('create-message', $template);
$where = "'".$this->getReadableScratchFilePath('create-message')."'";
}
try {
$message = ArcanistDifferentialCommitMessage::newFromRawCorpus(
$template);
$message->pullDataFromConduit($conduit);
$this->validateCommitMessage($message);
$done = true;
} catch (ArcanistDifferentialCommitMessageParserException $ex) {
echo pht('Commit message has errors:')."\n\n";
$issues = array(pht('Resolve these errors:'));
foreach ($ex->getParserErrors() as $error) {
echo phutil_console_wrap("- ".$error."\n", 6);
$issues[] = ' - '.$error;
}
echo "\n";
echo pht('You must resolve these errors to continue.');
$again = phutil_console_confirm(
pht('Do you want to edit the message?'),
$default_no = false);
if ($again) {
// Keep going.
} else {
$saved = null;
if ($wrote) {
$saved = pht('A copy was saved to %s.', $where);
}
throw new ArcanistUsageException(
pht('Message has unresolved errors.')." {$saved}");
}
} catch (Exception $ex) {
if ($wrote) {
echo phutil_console_wrap(pht('(Message saved to %s.)', $where)."\n");
}
throw $ex;
}
}
return $message;
}