Page MenuHomePhabricator

D21351.id50823.diff
No OneTemporary

D21351.id50823.diff

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
@@ -89,7 +89,7 @@
$markers = mgroup($markers, 'getName');
- foreach ($unresolved as $key => $symbol) {
+ foreach ($unresolved as $key => $symbol) {
$raw_symbol = $symbol->getSymbol();
$named_markers = idx($markers, $raw_symbol);
@@ -98,12 +98,25 @@
}
if (count($named_markers) > 1) {
- throw new PhutilArgumentUsageException(
+ echo tsprintf(
+ "\n%!\n%W\n\n",
+ pht('AMBIGUOUS SYMBOL'),
pht(
'Symbol "%s" is ambiguous: it matches multiple markers '.
'(of type "%s"). Use an unambiguous identifier.',
$raw_symbol,
$marker_type));
+
+ foreach ($named_markers as $named_marker) {
+ echo tsprintf('%s', $named_marker->newDisplayRef());
+ }
+
+ echo tsprintf("\n");
+
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Symbol "%s" is ambiguous.',
+ $symbol));
}
$marker = head($named_markers);
@@ -300,16 +313,58 @@
$branch_count = count($branches);
if ($branch_count > 1) {
+ echo tsprintf(
+ "\n%!\n%W\n\n%W\n\n%W\n\n",
+ pht('MULTIPLE "ONTO" BRANCHES'),
+ pht(
+ 'You have selected multiple branches to push changes onto. '.
+ 'Pushing to multiple branches is not supported by "arc land" '.
+ 'in Mercurial: Mercurial commits may only belong to one '.
+ 'branch, so this operation can not be executed atomically.'),
+ pht(
+ 'You may land one branches and any number of bookmarks in a '.
+ 'single operation.'),
+ pht('These branches were selected:'));
+
+ foreach ($branches as $branch) {
+ echo tsprintf('%s', $branch->newDisplayRef());
+ }
+
+ echo tsprintf("\n");
+
throw new PhutilArgumentUsageException(
pht(
- 'TODO: You can not push onto multiple branches in Mercurial.'));
+ 'Landing onto multiple branches at once is not supported in '.
+ 'Mercurial.'));
} else if ($branch_count) {
$this->ontoBranchMarker = head($branches);
}
}
if ($new_markers) {
- // TODO: If we're creating bookmarks, ask the user to confirm.
+ echo tsprintf(
+ "\n%!\n%W\n\n",
+ pht('CREATE %s BOOKMARK(S)', phutil_count($new_markers)),
+ pht(
+ 'These %s symbol(s) do not exist in the remote. They will be created '.
+ 'as new bookmarks:',
+ phutil_count($new_markers)));
+
+
+ foreach ($new_markers as $new_marker) {
+ echo tsprintf('%s', $new_marker->newDisplayRef());
+ }
+
+ echo tsprintf("\n");
+
+ $query = pht(
+ 'Create %s new remote bookmark(s)?',
+ phutil_count($new_markers));
+
+ $this->getWorkflow()
+ ->getPrompt('arc.land.create')
+ ->setQuery($query)
+ ->execute();
}
$this->ontoMarkers = $onto_markers;
@@ -761,6 +816,30 @@
protected function pushChange($into_commit) {
$api = $this->getRepositoryAPI();
+ list($head, $body, $tail) = $this->newPushCommands($into_commit);
+
+ foreach ($head as $command) {
+ $api->execxLocal('%Ls', $command);
+ }
+
+ try {
+ foreach ($body as $command) {
+ $this->newPasthru('%Ls', $command);
+ }
+ } finally {
+ foreach ($tail as $command) {
+ $api->execxLocal('%Ls', $command);
+ }
+ }
+ }
+
+ private function newPushCommands($into_commit) {
+ $api = $this->getRepositoryAPI();
+
+ $head_commands = array();
+ $body_commands = array();
+ $tail_commands = array();
+
$bookmarks = array();
foreach ($this->ontoMarkers as $onto_marker) {
if (!$onto_marker->isBookmark()) {
@@ -776,8 +855,8 @@
$restore = array();
if ($bookmarks) {
$markers = $api->newMarkerRefQuery()
- ->withNames(array(mpull($bookmarks, 'getName')))
- ->withTypes(array(ArcanistMarkerRef::TYPE_BOOKMARK))
+ ->withNames(mpull($bookmarks, 'getName'))
+ ->withMarkerTypes(array(ArcanistMarkerRef::TYPE_BOOKMARK))
->execute();
$markers = mpull($markers, 'getCommitHash', 'getName');
@@ -791,6 +870,15 @@
continue;
}
+ $head_commands[] = array(
+ 'bookmark',
+ '--force',
+ '--rev',
+ hgsprintf('%s', $this->getDisplayHash($new_position)),
+ '--',
+ $bookmark_name,
+ );
+
$api->execxLocal(
'bookmark --force --rev %s -- %s',
hgsprintf('%s', $new_position),
@@ -800,7 +888,7 @@
}
}
- // Now, do the actual push.
+ // Now, prepare the actual push.
$argv = array();
$argv[] = 'push';
@@ -821,23 +909,33 @@
$argv[] = '--';
$argv[] = $this->getOntoRemote();
- try {
- $this->newPassthru('%Ls', $argv);
- } finally {
- foreach ($restore as $bookmark_name => $old_position) {
- if ($old_position === null) {
- $api->execxLocal(
- 'bookmark --delete -- %s',
- $bookmark_name);
- } else {
- $api->execxLocal(
- 'bookmark --force --rev %s -- %s',
- hgsprintf('%s', $old_position),
- $bookmark_name);
- }
+ $body_commands[] = $argv;
+
+ // Finally, restore the bookmarks.
+
+ foreach ($restore as $bookmark_name => $old_position) {
+ $tail = array();
+ $tail[] = 'bookmark';
+
+ if ($old_position === null) {
+ $tail[] = '--delete';
+ } else {
+ $tail[] = '--force';
+ $tail[] = '--rev';
+ $tail[] = hgsprintf('%s', $this->getDisplayHash($old_position));
}
+
+ $tail[] = '--';
+ $tail[] = $bookmark_name;
+
+ $tail_commands[] = $tail;
}
+ return array(
+ $head_commands,
+ $body_commands,
+ $tail_commands,
+ );
}
protected function cascadeState(ArcanistLandCommitSet $set, $into_commit) {
@@ -940,12 +1038,8 @@
$message = pht(
'Holding changes locally, they have not been pushed.');
- // TODO: This is only vaguely correct.
-
- $push_command = csprintf(
- '$ hg push --rev %s -- %s',
- hgsprintf('%s', $this->getDisplayHash($into_commit)),
- $this->getOntoRemote());
+ list($head, $body, $tail) = $this->newPushCommands($into_commit);
+ $commands = array_merge($head, $body, $tail);
echo tsprintf(
"\n%!\n%s\n\n",
@@ -953,9 +1047,15 @@
$message);
echo tsprintf(
- "%s\n\n **%s**\n\n",
- pht('To push changes manually, run this command:'),
- $push_command);
+ "%s\n\n",
+ pht('To push changes manually, run these %s command(s):',
+ phutil_count($commands)));
+
+ foreach ($commands as $command) {
+ echo tsprintf('%>', csprintf('hg %Ls', $command));
+ }
+
+ echo tsprintf("\n");
$restore_commands = $local_state->getRestoreCommandsForDisplay();
if ($restore_commands) {
@@ -967,7 +1067,7 @@
phutil_count($restore_commands)));
foreach ($restore_commands as $restore_command) {
- echo tsprintf(" **%s**\n", $restore_command);
+ echo tsprintf('%>', $restore_command);
}
echo tsprintf("\n");
@@ -980,12 +1080,4 @@
'in the same state as before.'));
}
-
- private function newRemoteMarkers($remote) {
- // See T9948. If the user specified "--into X" or "--onto X", we don't know
- // if it's a branch, a bookmark, or a symbol which doesn't exist yet.
-
-
- }
-
}
diff --git a/src/repository/state/ArcanistGitLocalState.php b/src/repository/state/ArcanistGitLocalState.php
--- a/src/repository/state/ArcanistGitLocalState.php
+++ b/src/repository/state/ArcanistGitLocalState.php
@@ -47,7 +47,6 @@
protected function executeRestoreLocalState() {
$api = $this->getRepositoryAPI();
-
$log = $this->getWorkflow()->getLogEngine();
$ref = $this->localRef;
@@ -163,8 +162,4 @@
return substr($stash_ref, 0, 12);
}
- private function getDisplayHash($hash) {
- return substr($hash, 0, 12);
- }
-
}
diff --git a/src/repository/state/ArcanistMercurialLocalState.php b/src/repository/state/ArcanistMercurialLocalState.php
--- a/src/repository/state/ArcanistMercurialLocalState.php
+++ b/src/repository/state/ArcanistMercurialLocalState.php
@@ -4,37 +4,45 @@
extends ArcanistRepositoryLocalState {
private $localCommit;
- private $localRef;
-
- public function getLocalRef() {
- return $this->localRef;
- }
-
- public function getLocalPath() {
- return $this->localPath;
- }
+ private $localBranch;
protected function executeSaveLocalState() {
$api = $this->getRepositoryAPI();
+ $log = $this->getWorkflow()->getLogEngine();
+
+ // TODO: Both of these can be pulled from "hg arc-ls-markers" more
+ // efficiently.
+
+ $this->localCommit = $api->getCanonicalRevisionName('.');
- // TODO: We need to save the position of "." and the current active
- // branch, which may be any symbol at all. Both of these can be pulled
- // from "hg arc-ls-markers".
+ list($branch) = $api->execxLocal('branch');
+ $this->localBranch = trim($branch);
+ $log->writeTrace(
+ pht('SAVE STATE'),
+ pht(
+ 'Saving local state (at "%s" on branch "%s").',
+ $this->getDisplayHash($this->localCommit),
+ $this->localBranch));
}
protected function executeRestoreLocalState() {
$api = $this->getRepositoryAPI();
+ $log = $this->getWorkflow()->getLogEngine();
- // TODO: In Mercurial, we may want to discard commits we've created.
- // $repository_api->execxLocal(
- // '--config extensions.mq= strip %s',
- // $this->onto);
+ $log->writeStatus(
+ pht('LOAD STATE'),
+ pht(
+ 'Restoring local state (at "%s" on branch "%s").',
+ $this->getDisplayHash($this->localCommit),
+ $this->localBranch));
+ $api->execxLocal('update -- %s', $this->localCommit);
+ $api->execxLocal('branch --force -- %s', $this->localBranch);
}
protected function executeDiscardLocalState() {
- // TODO: Fix this.
+ return;
}
protected function canStashChanges() {
@@ -51,8 +59,17 @@
}
protected function newRestoreCommandsForDisplay() {
- // TODO: Provide this.
- return array();
+ $commands = array();
+
+ $commands[] = csprintf(
+ 'hg update -- %s',
+ $this->getDisplayHash($this->localCommit));
+
+ $commands[] = csprintf(
+ 'hg branch --force -- %s',
+ $this->localBranch);
+
+ return $commands;
}
protected function saveStash() {
diff --git a/src/repository/state/ArcanistRepositoryLocalState.php b/src/repository/state/ArcanistRepositoryLocalState.php
--- a/src/repository/state/ArcanistRepositoryLocalState.php
+++ b/src/repository/state/ArcanistRepositoryLocalState.php
@@ -256,4 +256,8 @@
echo tsprintf("\n");
}
+ final protected function getDisplayHash($hash) {
+ return substr($hash, 0, 12);
+ }
+
}
diff --git a/src/workflow/ArcanistLandWorkflow.php b/src/workflow/ArcanistLandWorkflow.php
--- a/src/workflow/ArcanistLandWorkflow.php
+++ b/src/workflow/ArcanistLandWorkflow.php
@@ -280,6 +280,11 @@
->setDescription(
pht(
'Confirms that revisions with ongoing builds should land.')),
+ $this->newPrompt('arc.land.create')
+ ->setDescription(
+ pht(
+ 'Confirms that new branches or bookmarks should be created '.
+ 'in the remote.')),
);
}

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 20, 11:48 AM (22 h, 20 m ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7223542
Default Alt Text
D21351.id50823.diff (11 KB)

Event Timeline