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) {
|
protected function confirmOntoRefs(array $onto_refs) {
|
||||||
|
$api = $this->getRepositoryAPI();
|
||||||
|
|
||||||
foreach ($onto_refs as $onto_ref) {
|
foreach ($onto_refs as $onto_ref) {
|
||||||
if (!strlen($onto_ref)) {
|
if (!strlen($onto_ref)) {
|
||||||
throw new PhutilArgumentUsageException(
|
throw new PhutilArgumentUsageException(
|
||||||
|
@ -886,10 +888,61 @@ final class ArcanistGitLandEngine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check that these refs really exist in the remote? Checking the
|
$markers = $api->newMarkerRefQuery()
|
||||||
// remote is expensive and users probably rarely specify "--onto" manually,
|
->withRemotes(array($this->getOntoRemoteRef()))
|
||||||
// but if "arc land" creates branches without prompting when you make typos
|
->withNames($onto_refs)
|
||||||
// that also seems questionable.
|
->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) {
|
protected function selectOntoRefs(array $symbols) {
|
||||||
|
@ -1238,6 +1291,7 @@ final class ArcanistGitLandEngine
|
||||||
$api = $this->getRepositoryAPI();
|
$api = $this->getRepositoryAPI();
|
||||||
// Make sure that our "into" target is valid.
|
// Make sure that our "into" target is valid.
|
||||||
$log = $this->getLogEngine();
|
$log = $this->getLogEngine();
|
||||||
|
$api = $this->getRepositoryAPI();
|
||||||
|
|
||||||
if ($this->getIntoEmpty()) {
|
if ($this->getIntoEmpty()) {
|
||||||
// If we're running under "--into-empty", we don't have to do anything.
|
// If we're running under "--into-empty", we don't have to do anything.
|
||||||
|
|
|
@ -1569,4 +1569,9 @@ abstract class ArcanistLandEngine
|
||||||
return $command->execute();
|
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())
|
$remote_ref = $this->getOntoRemoteRef();
|
||||||
->setRemoteName($this->getOntoRemote());
|
|
||||||
|
|
||||||
$markers = $api->newMarkerRefQuery()
|
$markers = $api->newMarkerRefQuery()
|
||||||
->withRemotes(array($remote_ref))
|
->withRemotes(array($remote_ref))
|
||||||
|
@ -346,8 +345,8 @@ final class ArcanistMercurialLandEngine
|
||||||
"\n%!\n%W\n\n",
|
"\n%!\n%W\n\n",
|
||||||
pht('CREATE %s BOOKMARK(S)', phutil_count($new_markers)),
|
pht('CREATE %s BOOKMARK(S)', phutil_count($new_markers)),
|
||||||
pht(
|
pht(
|
||||||
'These %s symbol(s) do not exist in the remote. They will be created '.
|
'These %s symbol(s) do not exist in the remote. They will be '.
|
||||||
'as new bookmarks:',
|
'created as new bookmarks:',
|
||||||
phutil_count($new_markers)));
|
phutil_count($new_markers)));
|
||||||
|
|
||||||
|
|
||||||
|
@ -357,6 +356,17 @@ final class ArcanistMercurialLandEngine
|
||||||
|
|
||||||
echo tsprintf("\n");
|
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(
|
$query = pht(
|
||||||
'Create %s new remote bookmark(s)?',
|
'Create %s new remote bookmark(s)?',
|
||||||
phutil_count($new_markers));
|
phutil_count($new_markers));
|
||||||
|
|
|
@ -122,7 +122,59 @@ final class ArcanistGitRepositoryMarkerQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function newRemoteRefMarkers(ArcanistRemoteRef $remote) {
|
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 '?':
|
case '?':
|
||||||
$value = tsprintf('<bg:green>** ? **</bg> %s', $value);
|
$value = tsprintf('<bg:green>** ? **</bg> %s', $value);
|
||||||
$value = PhutilTerminalString::escapeStringValue($value, false);
|
$value = PhutilTerminalString::escapeStringValue($value, false);
|
||||||
|
$value = phutil_console_wrap($value, 6, false);
|
||||||
$type = 's';
|
$type = 's';
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
|
|
Loading…
Reference in a new issue