/**
  * Updates the given path to the given commit ref
  *
  * @param  string      $path
  * @param  string      $reference
  * @param  string      $branch
  * @param  \DateTime   $date
  * @return null|string if a string is returned, it is the commit reference that was checked out if the original could not be found
  *
  * @throws \RuntimeException
  */
 protected function updateToCommit($path, $reference, $branch, $date)
 {
     $template = 'git checkout %s && git reset --hard %1$s';
     $branch = preg_replace('{(?:^dev-|(?:\\.x)?-dev$)}i', '', $branch);
     $branches = null;
     if (0 === $this->process->execute('git branch -r', $output, $path)) {
         $branches = $output;
     }
     // check whether non-commitish are branches or tags, and fetch branches with the remote name
     $gitRef = $reference;
     if (!preg_match('{^[a-f0-9]{40}$}', $reference) && $branches && preg_match('{^\\s+composer/' . preg_quote($reference) . '$}m', $branches)) {
         $command = sprintf('git checkout -B %s %s && git reset --hard %2$s', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/' . $reference));
         if (0 === $this->process->execute($command, $output, $path)) {
             return;
         }
     }
     // try to checkout branch by name and then reset it so it's on the proper branch name
     if (preg_match('{^[a-f0-9]{40}$}', $reference)) {
         // add 'v' in front of the branch if it was stripped when generating the pretty name
         if (!preg_match('{^\\s+composer/' . preg_quote($branch) . '$}m', $branches) && preg_match('{^\\s+composer/v' . preg_quote($branch) . '$}m', $branches)) {
             $branch = 'v' . $branch;
         }
         $command = sprintf('git checkout %s', ProcessExecutor::escape($branch));
         $fallbackCommand = sprintf('git checkout -B %s %s', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/' . $branch));
         if (0 === $this->process->execute($command, $output, $path) || 0 === $this->process->execute($fallbackCommand, $output, $path)) {
             $command = sprintf('git reset --hard %s', ProcessExecutor::escape($reference));
             if (0 === $this->process->execute($command, $output, $path)) {
                 return;
             }
         }
     }
     $command = sprintf($template, ProcessExecutor::escape($gitRef));
     if (0 === $this->process->execute($command, $output, $path)) {
         return;
     }
     // reference was not found (prints "fatal: reference is not a tree: $ref")
     if ($date && false !== strpos($this->process->getErrorOutput(), $reference)) {
         $date = $date->format('U');
         // guess which remote branch to look at first
         $command = 'git branch -r';
         if (0 !== $this->process->execute($command, $output, $path)) {
             throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
         }
         $guessTemplate = 'git log --until=%s --date=raw -n1 --pretty=%%H %s';
         foreach ($this->process->splitLines($output) as $line) {
             if (preg_match('{^composer/' . preg_quote($branch) . '(?:\\.x)?$}i', trim($line))) {
                 // find the previous commit by date in the given branch
                 if (0 === $this->process->execute(sprintf($guessTemplate, $date, ProcessExecutor::escape(trim($line))), $output, $path)) {
                     $newReference = trim($output);
                 }
                 break;
             }
         }
         if (empty($newReference)) {
             // no matching branch found, find the previous commit by date in all commits
             if (0 !== $this->process->execute(sprintf($guessTemplate, $date, '--all'), $output, $path)) {
                 throw new \RuntimeException('Failed to execute ' . GitUtil::sanitizeUrl($command) . "\n\n" . $this->process->getErrorOutput());
             }
             $newReference = trim($output);
         }
         // checkout the new recovered ref
         $command = sprintf($template, ProcessExecutor::escape($newReference));
         if (0 === $this->process->execute($command, $output, $path)) {
             $this->io->write('    ' . $reference . ' is gone (history was rewritten?), recovered by checking out ' . $newReference);
             return $newReference;
         }
     }
     throw new \RuntimeException('Failed to execute ' . GitUtil::sanitizeUrl($command) . "\n\n" . $this->process->getErrorOutput());
 }
 /**
  * Updates the given path to the given commit ref
  *
  * @param  string            $path
  * @param  string            $reference
  * @param  string            $branch
  * @param  \DateTime         $date
  * @throws \RuntimeException
  * @return null|string       if a string is returned, it is the commit reference that was checked out if the original could not be found
  */
 protected function updateToCommit($path, $reference, $branch, $date)
 {
     $force = $this->hasDiscardedChanges || $this->hasStashedChanges ? '-f ' : '';
     // This uses the "--" sequence to separate branch from file parameters.
     //
     // Otherwise git tries the branch name as well as file name.
     // If the non-existent branch is actually the name of a file, the file
     // is checked out.
     $template = 'git checkout ' . $force . '%s -- && git reset --hard %1$s --';
     $branch = preg_replace('{(?:^dev-|(?:\\.x)?-dev$)}i', '', $branch);
     $branches = null;
     if (0 === $this->process->execute('git branch -r', $output, $path)) {
         $branches = $output;
     }
     // check whether non-commitish are branches or tags, and fetch branches with the remote name
     $gitRef = $reference;
     if (!preg_match('{^[a-f0-9]{40}$}', $reference) && $branches && preg_match('{^\\s+composer/' . preg_quote($reference) . '$}m', $branches)) {
         $command = sprintf('git checkout ' . $force . '-B %s %s -- && git reset --hard %2$s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/' . $reference));
         if (0 === $this->process->execute($command, $output, $path)) {
             return;
         }
     }
     // try to checkout branch by name and then reset it so it's on the proper branch name
     if (preg_match('{^[a-f0-9]{40}$}', $reference)) {
         // add 'v' in front of the branch if it was stripped when generating the pretty name
         if (!preg_match('{^\\s+composer/' . preg_quote($branch) . '$}m', $branches) && preg_match('{^\\s+composer/v' . preg_quote($branch) . '$}m', $branches)) {
             $branch = 'v' . $branch;
         }
         $command = sprintf('git checkout %s --', ProcessExecutor::escape($branch));
         $fallbackCommand = sprintf('git checkout ' . $force . '-B %s %s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/' . $branch));
         if (0 === $this->process->execute($command, $output, $path) || 0 === $this->process->execute($fallbackCommand, $output, $path)) {
             $command = sprintf('git reset --hard %s --', ProcessExecutor::escape($reference));
             if (0 === $this->process->execute($command, $output, $path)) {
                 return;
             }
         }
     }
     $command = sprintf($template, ProcessExecutor::escape($gitRef));
     if (0 === $this->process->execute($command, $output, $path)) {
         return;
     }
     // reference was not found (prints "fatal: reference is not a tree: $ref")
     if (false !== strpos($this->process->getErrorOutput(), $reference)) {
         $this->io->writeError('    <warning>' . $reference . ' is gone (history was rewritten?)</warning>');
     }
     throw new \RuntimeException('Failed to execute ' . GitUtil::sanitizeUrl($command) . "\n\n" . $this->process->getErrorOutput());
 }
Beispiel #3
0
 protected function updateToCommit($path, $reference, $branch, $date)
 {
     $template = 'git checkout %s && git reset --hard %1$s';
     $branch = preg_replace('{(?:^dev-|(?:\\.x)?-dev$)}i', '', $branch);
     $branches = null;
     if (0 === $this->process->execute('git branch -r', $output, $path)) {
         $branches = $output;
     }
     $gitRef = $reference;
     if (!preg_match('{^[a-f0-9]{40}$}', $reference) && $branches && preg_match('{^\\s+composer/' . preg_quote($reference) . '$}m', $branches)) {
         $command = sprintf('git checkout -B %s %s && git reset --hard %2$s', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/' . $reference));
         if (0 === $this->process->execute($command, $output, $path)) {
             return;
         }
     }
     if (preg_match('{^[a-f0-9]{40}$}', $reference)) {
         if (!preg_match('{^\\s+composer/' . preg_quote($branch) . '$}m', $branches) && preg_match('{^\\s+composer/v' . preg_quote($branch) . '$}m', $branches)) {
             $branch = 'v' . $branch;
         }
         $command = sprintf('git checkout %s', ProcessExecutor::escape($branch));
         $fallbackCommand = sprintf('git checkout -B %s %s', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/' . $branch));
         if (0 === $this->process->execute($command, $output, $path) || 0 === $this->process->execute($fallbackCommand, $output, $path)) {
             $command = sprintf('git reset --hard %s', ProcessExecutor::escape($reference));
             if (0 === $this->process->execute($command, $output, $path)) {
                 return;
             }
         }
     }
     $command = sprintf($template, ProcessExecutor::escape($gitRef));
     if (0 === $this->process->execute($command, $output, $path)) {
         return;
     }
     if (false !== strpos($this->process->getErrorOutput(), $reference)) {
         $this->io->writeError('    <warning>' . $reference . ' is gone (history was rewritten?)</warning>');
     }
     throw new \RuntimeException('Failed to execute ' . GitUtil::sanitizeUrl($command) . "\n\n" . $this->process->getErrorOutput());
 }