mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-21 22:32:41 +01:00
In "arc land" under Git, confirm branch creation
Summary: Ref T13546. If "arc land" would create a branch, warn the user before it does. Test Plan: Ran "arc land --onto mtarse", a typo of "master". Maniphest Tasks: T13546 Differential Revision: https://secure.phabricator.com/D21354
This commit is contained in:
parent
33bb0acf97
commit
b0a9ef8351
5 changed files with 131 additions and 9 deletions
|
@ -876,6 +876,8 @@ final class ArcanistGitLandEngine
|
|||
}
|
||||
|
||||
protected function confirmOntoRefs(array $onto_refs) {
|
||||
$api = $this->getRepositoryAPI();
|
||||
|
||||
foreach ($onto_refs as $onto_ref) {
|
||||
if (!strlen($onto_ref)) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
|
@ -886,10 +888,61 @@ final class ArcanistGitLandEngine
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Check that these refs really exist in the remote? Checking the
|
||||
// remote is expensive and users probably rarely specify "--onto" manually,
|
||||
// but if "arc land" creates branches without prompting when you make typos
|
||||
// that also seems questionable.
|
||||
$markers = $api->newMarkerRefQuery()
|
||||
->withRemotes(array($this->getOntoRemoteRef()))
|
||||
->withNames($onto_refs)
|
||||
->execute();
|
||||
|
||||
$markers = mgroup($markers, 'getName');
|
||||
|
||||
$new_markers = array();
|
||||
foreach ($onto_refs as $onto_ref) {
|
||||
if (isset($markers[$onto_ref])) {
|
||||
// Remote already has a branch with this name, so we're fine: we
|
||||
// aren't creatinga new branch.
|
||||
continue;
|
||||
}
|
||||
|
||||
$new_markers[] = id(new ArcanistMarkerRef())
|
||||
->setMarkerType(ArcanistMarkerRef::TYPE_BRANCH)
|
||||
->setName($onto_ref);
|
||||
}
|
||||
|
||||
if ($new_markers) {
|
||||
echo tsprintf(
|
||||
"\n%!\n%W\n\n",
|
||||
pht('CREATE %s BRANCHE(S)', phutil_count($new_markers)),
|
||||
pht(
|
||||
'These %s symbol(s) do not exist in the remote. They will be '.
|
||||
'created as new branches:',
|
||||
phutil_count($new_markers)));
|
||||
|
||||
foreach ($new_markers as $new_marker) {
|
||||
echo tsprintf('%s', $new_marker->newRefView());
|
||||
}
|
||||
|
||||
echo tsprintf("\n");
|
||||
|
||||
$is_hold = $this->getShouldHold();
|
||||
if ($is_hold) {
|
||||
echo tsprintf(
|
||||
"%?\n",
|
||||
pht(
|
||||
'You are using "--hold", so execution will stop before the '.
|
||||
'%s branche(s) are actually created. You will be given '.
|
||||
'instructions to create the branches.',
|
||||
phutil_count($new_markers)));
|
||||
}
|
||||
|
||||
$query = pht(
|
||||
'Create %s new branche(s) in the remote?',
|
||||
phutil_count($new_markers));
|
||||
|
||||
$this->getWorkflow()
|
||||
->getPrompt('arc.land.create')
|
||||
->setQuery($query)
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
protected function selectOntoRefs(array $symbols) {
|
||||
|
@ -1238,6 +1291,7 @@ final class ArcanistGitLandEngine
|
|||
$api = $this->getRepositoryAPI();
|
||||
// Make sure that our "into" target is valid.
|
||||
$log = $this->getLogEngine();
|
||||
$api = $this->getRepositoryAPI();
|
||||
|
||||
if ($this->getIntoEmpty()) {
|
||||
// If we're running under "--into-empty", we don't have to do anything.
|
||||
|
|
|
@ -1569,4 +1569,9 @@ abstract class ArcanistLandEngine
|
|||
return $command->execute();
|
||||
}
|
||||
|
||||
final protected function getOntoRemoteRef() {
|
||||
return id(new ArcanistRemoteRef())
|
||||
->setRemoteName($this->getOntoRemote());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -270,8 +270,7 @@ final class ArcanistMercurialLandEngine
|
|||
}
|
||||
}
|
||||
|
||||
$remote_ref = id(new ArcanistRemoteRef())
|
||||
->setRemoteName($this->getOntoRemote());
|
||||
$remote_ref = $this->getOntoRemoteRef();
|
||||
|
||||
$markers = $api->newMarkerRefQuery()
|
||||
->withRemotes(array($remote_ref))
|
||||
|
@ -346,8 +345,8 @@ final class ArcanistMercurialLandEngine
|
|||
"\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:',
|
||||
'These %s symbol(s) do not exist in the remote. They will be '.
|
||||
'created as new bookmarks:',
|
||||
phutil_count($new_markers)));
|
||||
|
||||
|
||||
|
@ -357,6 +356,17 @@ final class ArcanistMercurialLandEngine
|
|||
|
||||
echo tsprintf("\n");
|
||||
|
||||
$is_hold = $this->getShouldHold();
|
||||
if ($is_hold) {
|
||||
echo tsprintf(
|
||||
"%?\n",
|
||||
pht(
|
||||
'You are using "--hold", so execution will stop before the '.
|
||||
'%s bookmark(s) are actually created. You will be given '.
|
||||
'instructions to create the bookmarks.',
|
||||
phutil_count($new_markers)));
|
||||
}
|
||||
|
||||
$query = pht(
|
||||
'Create %s new remote bookmark(s)?',
|
||||
phutil_count($new_markers));
|
||||
|
|
|
@ -122,7 +122,59 @@ final class ArcanistGitRepositoryMarkerQuery
|
|||
}
|
||||
|
||||
protected function newRemoteRefMarkers(ArcanistRemoteRef $remote) {
|
||||
throw new PhutilMethodNotImplementedException();
|
||||
$api = $this->getRepositoryAPI();
|
||||
|
||||
// NOTE: Since we only care about branches today, we only list branches.
|
||||
|
||||
$future = $api->newFuture(
|
||||
'ls-remote --refs %s %s',
|
||||
$remote->getRemoteName(),
|
||||
'refs/heads/*');
|
||||
list($stdout) = $future->resolve();
|
||||
|
||||
$branch_prefix = 'refs/heads/';
|
||||
$branch_length = strlen($branch_prefix);
|
||||
|
||||
$pattern = '(^(?P<hash>\S+)\t(?P<ref>\S+)\z)';
|
||||
$markers = array();
|
||||
|
||||
$lines = phutil_split_lines($stdout, false);
|
||||
foreach ($lines as $line) {
|
||||
$matches = null;
|
||||
$ok = preg_match($pattern, $line, $matches);
|
||||
if (!$ok) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Failed to match "ls-remote" pattern against line "%s".',
|
||||
$line));
|
||||
}
|
||||
|
||||
$hash = $matches['hash'];
|
||||
$ref = $matches['ref'];
|
||||
|
||||
if (!strncmp($ref, $branch_prefix, $branch_length)) {
|
||||
$type = ArcanistMarkerRef::TYPE_BRANCH;
|
||||
$name = substr($ref, $branch_length);
|
||||
} else {
|
||||
// For now, discard other refs.
|
||||
continue;
|
||||
}
|
||||
|
||||
$marker = id(new ArcanistMarkerRef())
|
||||
->setName($name)
|
||||
->setMarkerType($type)
|
||||
->setMarkerHash($hash)
|
||||
->setCommitHash($hash);
|
||||
|
||||
$commit_ref = $api->newCommitRef()
|
||||
->setCommitHash($hash);
|
||||
|
||||
$marker->attachCommitRef($commit_ref);
|
||||
|
||||
$markers[] = $marker;
|
||||
}
|
||||
|
||||
return $markers;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ function xsprintf_terminal($userdata, &$pattern, &$pos, &$value, &$length) {
|
|||
case '?':
|
||||
$value = tsprintf('<bg:green>** ? **</bg> %s', $value);
|
||||
$value = PhutilTerminalString::escapeStringValue($value, false);
|
||||
$value = phutil_console_wrap($value, 6, false);
|
||||
$type = 's';
|
||||
break;
|
||||
case '>':
|
||||
|
|
Loading…
Reference in a new issue