/** * Test GitHelper::branchExists(). */ public function testBranchExists() { $repository = $this->getRepositoryDir(); chdir($repository); // Create a branch. shell_exec('git checkout -q -b new'); // Add required Git config before committing. shell_exec('git config user.email test@example.com'); shell_exec('git config user.name "Platform.sh CLI Test"'); // Make a dummy commit so that there is a HEAD. touch($repository . '/README.txt'); shell_exec('git add -A && git commit -qm "Initial commit"'); $this->assertTrue($this->gitHelper->branchExists('new', $repository)); }
/** * Check whether a branch exists, locally in Git or on the remote. * * @param string $branch * @param Project $project * @param GitHelper $gitHelper * * @return string|false */ protected function branchExists($branch, Project $project, GitHelper $gitHelper) { // Check if the Git branch exists locally. $candidates = array_unique(array(Environment::sanitizeId($branch), $branch)); foreach ($candidates as $candidate) { if ($gitHelper->branchExists($candidate)) { return $candidate; } } // Check if the environment exists by title or ID. This is usually faster // than running 'git ls-remote'. $environments = $this->getEnvironments($project); foreach ($environments as $environment) { if ($environment['title'] == $branch || $environment['id'] == $branch) { return $environment['id']; } } return false; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->envArgName = 'parent'; $this->validateInput($input, true); $selectedProject = $this->getSelectedProject(); $branchName = $input->getArgument('name'); if (empty($branchName)) { if ($input->isInteractive()) { // List environments. return $this->runOtherCommand('environments', array('--project' => $selectedProject->id)); } $this->stdErr->writeln("<error>You must specify the name of the new branch.</error>"); return 1; } $machineName = Environment::sanitizeId($branchName); $environmentId = $this->getSelectedEnvironment()['id']; if ($machineName == $environmentId) { $this->stdErr->writeln("<comment>Already on {$machineName}</comment>"); return 1; } if ($environment = $this->getEnvironment($machineName, $selectedProject)) { $checkout = $this->getHelper('question')->confirm("The environment <comment>{$machineName}</comment> already exists. Check out?", $input, $this->stdErr); if ($checkout) { return $this->runOtherCommand('environment:checkout', array('id' => $environment->id)); } return 1; } if (!$this->getSelectedEnvironment()->operationAvailable('branch')) { $this->stdErr->writeln("Operation not available: The environment <error>{$environmentId}</error> can't be branched."); return 1; } $force = $input->getOption('force'); $projectRoot = $this->getProjectRoot(); if (!$projectRoot && $force) { $this->stdErr->writeln("<comment>This command was run from outside your local project root, the new Platform.sh branch cannot be checked out in your local Git repository." . " Make sure to run 'platform checkout' or 'git checkout' in your repository directory to switch to the branch you are expecting.</comment>"); $local_error = true; } elseif (!$projectRoot) { $this->stdErr->writeln("<error>You must run this command inside the project root, or specify --force.</error>"); return 1; } $selectedEnvironment = $this->getSelectedEnvironment(); $this->stdErr->writeln("Creating a new environment <info>{$branchName}</info>, branched from <info>{$selectedEnvironment['title']}</info>"); $activity = $selectedEnvironment->branch($branchName, $machineName); // Clear the environments cache, as branching has started. $this->clearEnvironmentsCache($selectedProject); if ($projectRoot) { $gitHelper = new GitHelper(new ShellHelper($this->stdErr)); $gitHelper->setDefaultRepositoryDir($projectRoot . '/' . LocalProject::REPOSITORY_DIR); // If the Git branch already exists locally, just check it out. $existsLocally = $gitHelper->branchExists($machineName); if ($existsLocally) { $this->stdErr->writeln("Checking out <info>{$machineName}</info> locally"); if (!$gitHelper->checkOut($machineName)) { $this->stdErr->writeln('<error>Failed to check out branch locally: ' . $machineName . '</error>'); $local_error = true; if (!$force) { return 1; } } } else { // Create a new branch, using the current or specified environment as the parent if it exists locally. $parent = $this->getSelectedEnvironment()['id']; if (!$gitHelper->branchExists($parent)) { $parent = null; } $this->stdErr->writeln("Creating local branch <info>{$machineName}</info>"); if (!$gitHelper->checkOutNew($machineName, $parent)) { $this->stdErr->writeln('<error>Failed to create branch locally: ' . $machineName . '</error>'); $local_error = true; if (!$force) { return 1; } } } } $remoteSuccess = true; if (!$input->getOption('no-wait')) { $remoteSuccess = ActivityUtil::waitAndLog($activity, $this->stdErr, "The environment <info>{$branchName}</info> has been branched.", '<error>Branching failed</error>'); // Clear the environments cache again. $this->clearEnvironmentsCache($selectedProject); } $build = $input->getOption('build'); if (empty($local_error) && $build && $projectRoot) { // Build the new branch. try { $buildSettings = array('environmentId' => $machineName, 'verbosity' => $output->getVerbosity()); $builder = new LocalBuild($buildSettings, $output); $builder->buildProject($projectRoot); } catch (\Exception $e) { $this->stdErr->writeln("<comment>The new branch could not be built: \n" . $e->getMessage() . "</comment>"); return 1; } } $this->clearEnvironmentsCache(); return $remoteSuccess ? 0 : 1; }
/** * Test GitHelper::branchExists() with unicode branch names. */ public function testBranchExistsUnicode() { $this->gitHelper->checkOutNew('b®åñçh-wî†h-üní¢ø∂é'); $this->assertTrue($this->gitHelper->branchExists('b®åñçh-wî†h-üní¢ø∂é')); }
protected function execute(InputInterface $input, OutputInterface $output) { $project = $this->getCurrentProject(); if (!$project) { throw new RootNotFoundException(); } $projectRoot = $this->getProjectRoot(); $repositoryDir = $projectRoot . '/' . LocalProject::REPOSITORY_DIR; $gitHelper = new GitHelper(new ShellHelper($output)); $gitHelper->setDefaultRepositoryDir($repositoryDir); $specifiedEnvironmentId = $input->getArgument('environment'); if ($specifiedEnvironmentId != '0' && !($specifiedEnvironment = $this->getEnvironment($specifiedEnvironmentId, $project))) { $this->stdErr->writeln("Environment not found: <error>{$specifiedEnvironmentId}</error>"); return 1; } $specifiedBranch = $input->getArgument('branch'); if ($specifiedBranch) { if (!$gitHelper->branchExists($specifiedBranch)) { $this->stdErr->writeln("Branch not found: <error>{$specifiedBranch}</error>"); return 1; } } else { $specifiedBranch = $gitHelper->getCurrentBranch(); } // Check whether the branch is mapped by default (its name or its Git // upstream is the same as the remote environment ID). $mappedByDefault = isset($specifiedEnvironment) && $specifiedEnvironment->status != 'inactive' && $specifiedEnvironmentId === $specifiedBranch; if ($specifiedEnvironmentId != '0' && !$mappedByDefault) { $upstream = $gitHelper->getUpstream($specifiedBranch); if (strpos($upstream, '/')) { list(, $upstream) = explode('/', $upstream, 2); } if ($upstream === $specifiedEnvironmentId) { $mappedByDefault = true; } if (!$mappedByDefault && $gitHelper->branchExists($specifiedEnvironmentId)) { $this->stdErr->writeln("A local branch already exists named <comment>{$specifiedEnvironmentId}</comment>"); } } // Perform the mapping or unmapping. $config = $this->getProjectConfig($projectRoot); $config += ['mapping' => []]; if ($mappedByDefault || $specifiedEnvironmentId == '0') { unset($config['mapping'][$specifiedBranch]); $this->setProjectConfig('mapping', $config['mapping'], $projectRoot); } else { if (isset($config['mapping']) && ($current = array_search($specifiedEnvironmentId, $config['mapping'])) !== false) { unset($config['mapping'][$current]); } $config['mapping'][$specifiedBranch] = $specifiedEnvironmentId; $this->setProjectConfig('mapping', $config['mapping'], $projectRoot); } // Check the success of the operation. if (isset($config['mapping'][$specifiedBranch])) { $actualRemoteEnvironment = $config['mapping'][$specifiedBranch]; $this->stdErr->writeln("The local branch <info>{$specifiedBranch}</info> is mapped to the remote environment <info>{$actualRemoteEnvironment}</info>"); } elseif ($mappedByDefault) { $actualRemoteEnvironment = $specifiedBranch; $this->stdErr->writeln("The local branch <info>{$specifiedBranch}</info> is mapped to the default remote environment, <info>{$specifiedBranch}</info>"); } else { $this->stdErr->writeln("The local branch <info>{$specifiedBranch}</info> is not mapped to a remote environment"); } $success = !empty($actualRemoteEnvironment) ? $actualRemoteEnvironment == $specifiedEnvironmentId : $specifiedEnvironmentId == '0'; return $success ? 0 : 1; }