diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index c6cf53c28..750ff73bf 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -170,6 +170,19 @@ class GitDownloader extends VcsDownloader $gitRef = 'composer/'.$reference; } + $branch = preg_replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $branch); + + // checkout branch by name if the current reference matches the tip of the branch + if (preg_match('{^[a-f0-9]{40}$}', $reference) + && 0 === $this->process->execute('git log '.escapeshellarg($branch).' -1 --format=format:%H', $output, $path) + && $reference === trim($output) + ) { + $command = sprintf('git checkout -B %s %s && git reset --hard %2$s', escapeshellarg($branch), escapeshellarg('composer/'.$branch)); + if (0 === $this->process->execute($command, $output, $path)) { + return; + } + } + $command = sprintf($template, escapeshellarg($gitRef)); if (0 === $this->process->execute($command, $output, $path)) { return; @@ -177,7 +190,6 @@ class GitDownloader extends VcsDownloader // reference was not found (prints "fatal: reference is not a tree: $ref") if ($date && false !== strpos($this->process->getErrorOutput(), $reference)) { - $branch = preg_replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $branch); $date = $date->format('U'); // guess which remote branch to look at first diff --git a/tests/Composer/Test/Downloader/GitDownloaderTest.php b/tests/Composer/Test/Downloader/GitDownloaderTest.php index d9e2c4f29..20305a5fe 100644 --- a/tests/Composer/Test/Downloader/GitDownloaderTest.php +++ b/tests/Composer/Test/Downloader/GitDownloaderTest.php @@ -67,6 +67,11 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(0)); $processExecutor->expects($this->at(1)) + ->method('execute') + ->with($this->equalTo($this->getCmd("git log 'master' -1 --format=format:%H")), $this->equalTo(null), $this->equalTo('composerPath')) + ->will($this->returnValue(0)); + + $processExecutor->expects($this->at(2)) ->method('execute') ->with($this->equalTo($this->getCmd("git checkout '1234567890123456789012345678901234567890' && git reset --hard '1234567890123456789012345678901234567890'")), $this->equalTo(null), $this->equalTo('composerPath')) ->will($this->returnValue(0));