/**
  * {@inheritdoc}
  *
  * @throws \RuntimeException When invalid mode is specified.
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $mode = $this->io->getOption('mode');
     if (!in_array($mode, $this->getModes())) {
         throw new \RuntimeException('The "' . $mode . '" mode is unknown.');
     }
     $wc_path = $this->getWorkingCopyPath();
     switch ($mode) {
         case self::MODE_SHOW:
             $recorded_conflicts = $this->_workingCopyConflictTracker->getRecordedConflicts($wc_path);
             if (!$recorded_conflicts) {
                 $this->io->writeln('<info>The working copy doesn\'t have any recorded conflicts.</info>');
             } else {
                 $this->io->writeln('<error>Recorded Conflicts (' . count($recorded_conflicts) . ' paths):</error>');
                 foreach ($recorded_conflicts as $conflicted_path) {
                     $this->io->writeln(' * ' . $conflicted_path);
                 }
             }
             break;
         case self::MODE_ADD:
             $this->_workingCopyConflictTracker->add($wc_path);
             $this->io->writeln('<info>Conflicts updated.</info>');
             break;
         case self::MODE_REPLACE:
             $this->_workingCopyConflictTracker->replace($wc_path);
             $this->io->writeln('<info>Conflicts updated.</info>');
             break;
         case self::MODE_ERASE:
             $this->_workingCopyConflictTracker->erase($wc_path);
             $this->io->writeln('<info>Conflicts erased.</info>');
             break;
     }
 }
 /**
  * Returns commit message fragment for recent conflicts.
  *
  * @param string $wc_path Working copy path.
  *
  * @return string
  */
 protected function getFragmentForRecentConflicts($wc_path)
 {
     $recorded_conflicts = $this->workingCopyConflictTracker->getRecordedConflicts($wc_path);
     if (!$recorded_conflicts) {
         return '';
     }
     // Ensure empty line before.
     $ret = PHP_EOL . 'Conflicts:';
     foreach ($recorded_conflicts as $conflict_path) {
         $ret .= PHP_EOL . ' * ' . $conflict_path;
     }
     return $ret;
 }
 /**
  * Ensures, that there are no unresolved conflicts in working copy.
  *
  * @param string  $source_url                 Source url.
  * @param string  $wc_path                    Working copy path.
  * @param integer $largest_suggested_revision Largest revision, that is suggested in error message.
  *
  * @return void
  * @throws CommandException When merge conflicts detected.
  */
 protected function ensureWorkingCopyWithoutConflicts($source_url, $wc_path, $largest_suggested_revision = null)
 {
     $this->io->write(' * Previous Merge Status ... ');
     $conflicts = $this->_workingCopyConflictTracker->getNewConflicts($wc_path);
     if (!$conflicts) {
         $this->io->writeln('<info>Successful</info>');
         return;
     }
     $this->_workingCopyConflictTracker->add($wc_path);
     $this->io->writeln('<error>' . count($conflicts) . ' conflict(-s)</error>');
     $table = new Table($this->io->getOutput());
     if ($largest_suggested_revision) {
         $table->setHeaders(array('Path', 'Associated Revisions (before ' . $largest_suggested_revision . ')'));
     } else {
         $table->setHeaders(array('Path', 'Associated Revisions'));
     }
     $revision_log = $this->getRevisionLog($source_url);
     $source_path = $this->repositoryConnector->getRelativePath($source_url) . '/';
     /** @var OutputHelper $output_helper */
     $output_helper = $this->getHelper('output');
     foreach ($conflicts as $conflict_path) {
         $path_revisions = $revision_log->find('paths', $source_path . $conflict_path);
         $path_revisions = array_intersect($this->_unmergedRevisions, $path_revisions);
         if ($path_revisions && isset($largest_suggested_revision)) {
             $path_revisions = $this->limitRevisions($path_revisions, $largest_suggested_revision);
         }
         $table->addRow(array($conflict_path, $path_revisions ? $output_helper->formatArray($path_revisions, 4) : '-'));
     }
     $table->render();
     throw new CommandException('Working copy contains unresolved merge conflicts.');
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $wc_path = $this->getWorkingCopyPath();
     // Collect added path before "svn revert" because then they won't be shown as added by "svn status".
     $added_paths = $this->getAddedPaths();
     $this->io->writeln('Reverting local changes in working copy ... ');
     $command = $this->repositoryConnector->getCommand('revert', '--depth infinity {' . $wc_path . '}');
     $command->runLive(array($wc_path => '.'));
     $this->deletePaths($added_paths);
     $recorded_conflicts = $this->_workingCopyConflictTracker->getRecordedConflicts($wc_path);
     if ($recorded_conflicts) {
         $this->io->writeln(array('', 'Reverted Recorded Conflicts (' . count($recorded_conflicts) . ' paths):'));
         foreach ($recorded_conflicts as $conflicted_path) {
             $this->io->writeln(' * ' . $conflicted_path);
         }
     }
     $this->_workingCopyConflictTracker->erase($wc_path);
     $this->io->writeln('<info>Done</info>');
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $wc_path = $this->getWorkingCopyPath();
     $revision = $this->io->getOption('revision');
     $ignore_externals = $this->io->getOption('ignore-externals');
     $show_revision = $revision ? $revision : 'HEAD';
     $show_externals = $ignore_externals ? '(excluding externals)' : '(including externals)';
     $this->io->writeln('Updating working copy to <info>' . $show_revision . '</info> revision ' . $show_externals . ' ... ');
     $param_string = '{' . $wc_path . '}';
     if ($revision) {
         $param_string .= ' --revision ' . $revision;
     }
     if ($ignore_externals) {
         $param_string .= ' --ignore-externals';
     }
     $command = $this->repositoryConnector->getCommand('update', $param_string);
     $command->runLive(array($wc_path => '.'));
     if ($this->_workingCopyConflictTracker->getNewConflicts($wc_path)) {
         $this->_workingCopyConflictTracker->add($wc_path);
     }
     $this->io->writeln('<info>Done</info>');
 }
 /**
  * {@inheritdoc}
  *
  * @throws CommandException When conflicts are detected.
  * @throws CommandException Working copy has no changes.
  * @throws CommandException User decides not to perform a commit.
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $wc_path = $this->getWorkingCopyPath();
     $conflicts = $this->_workingCopyConflictTracker->getNewConflicts($wc_path);
     if ($conflicts) {
         throw new CommandException('Conflicts detected. Please resolve them before committing.');
     }
     $changelist = $this->getChangelist($wc_path);
     $compact_working_copy_status = $this->repositoryConnector->getCompactWorkingCopyStatus($wc_path, $changelist);
     if (!$compact_working_copy_status) {
         throw new CommandException('Nothing to commit.');
     }
     $commit_message = $this->_commitMessageBuilder->build($wc_path, $this->getMergeTemplate(), $changelist);
     $commit_message .= PHP_EOL . PHP_EOL . self::STOP_LINE . PHP_EOL . PHP_EOL . $compact_working_copy_status;
     $edited_commit_message = $this->_editor->setDocumentName('commit_message')->setContent($commit_message)->launch();
     $stop_line_pos = strpos($edited_commit_message, self::STOP_LINE);
     if ($stop_line_pos !== false) {
         $edited_commit_message = trim(substr($edited_commit_message, 0, $stop_line_pos));
     }
     $this->io->writeln(array('<fg=white;options=bold>Commit message:</>', $edited_commit_message, ''));
     if (!$this->io->askConfirmation('Run "svn commit"', false)) {
         throw new CommandException('Commit aborted by user.');
     }
     $tmp_file = tempnam(sys_get_temp_dir(), 'commit_message_');
     file_put_contents($tmp_file, $edited_commit_message);
     $arguments = array('-F {' . $tmp_file . '}');
     if (strlen($changelist)) {
         $arguments[] = '--depth empty';
         // Relative path used to make command line shorter.
         foreach (array_keys($this->repositoryConnector->getWorkingCopyStatus($wc_path, $changelist)) as $path) {
             $arguments[] = '{' . $path . '}';
         }
     } else {
         $arguments[] = '{' . $wc_path . '}';
     }
     $this->repositoryConnector->getCommand('commit', implode(' ', $arguments))->runLive();
     $this->_workingCopyConflictTracker->erase($wc_path);
     unlink($tmp_file);
     $this->io->writeln('<info>Done</info>');
 }
 public function testGetRecordedConflicts()
 {
     $wc_path = '/path/to/working-copy';
     $this->expectRecordedConflicts($wc_path, array('old-file.txt'));
     $this->assertEquals(array('old-file.txt'), $this->workingCopyConflictTracker->getRecordedConflicts($wc_path));
 }