From 354b82bb8c74e6c32f304fb1eb21638ea9bcb5b3 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 10 Jul 2012 19:02:06 +0200 Subject: [PATCH] Fix git checkouts of custom branches, fixes #889 --- src/Composer/Downloader/GitDownloader.php | 13 +++++++++-- .../Test/Downloader/GitDownloaderTest.php | 22 +++++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index 0bf8e65ac..06cf6fcd1 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -67,7 +67,16 @@ class GitDownloader extends VcsDownloader { $template = 'git checkout %s && git reset --hard %1$s'; - $command = sprintf($template, escapeshellarg($reference)); + // 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) + && 0 === $this->process->execute('git branch -r', $output, $path) + && preg_match('{^\s+composer/'.preg_quote($reference).'$}m', $output) + ) { + $gitRef = 'composer/'.$reference; + } + + $command = sprintf($template, escapeshellarg($gitRef)); if (0 === $this->process->execute($command, $output, $path)) { return; } @@ -104,7 +113,7 @@ class GitDownloader extends VcsDownloader } // checkout the new recovered ref - $command = sprintf($template, escapeshellarg($newReference)); + $command = sprintf($template, escapeshellarg($reference)); if (0 === $this->process->execute($command, $output, $path)) { $this->io->write(' '.$reference.' is gone (history was rewritten?), recovered by checking out '.$newReference); diff --git a/tests/Composer/Test/Downloader/GitDownloaderTest.php b/tests/Composer/Test/Downloader/GitDownloaderTest.php index 639913498..fb5a5f388 100644 --- a/tests/Composer/Test/Downloader/GitDownloaderTest.php +++ b/tests/Composer/Test/Downloader/GitDownloaderTest.php @@ -44,10 +44,13 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase $packageMock = $this->getMock('Composer\Package\PackageInterface'); $packageMock->expects($this->any()) ->method('getSourceReference') - ->will($this->returnValue('ref')); + ->will($this->returnValue('1234567890123456789012345678901234567890')); $packageMock->expects($this->any()) ->method('getSourceUrl') ->will($this->returnValue('https://example.com/composer/composer')); + $packageMock->expects($this->any()) + ->method('getPrettyVersion') + ->will($this->returnValue('dev-master')); $processExecutor = $this->getMock('Composer\Util\ProcessExecutor'); $expectedGitCommand = $this->getCmd("git clone 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'https://example.com/composer/composer' && git fetch composer"); @@ -58,7 +61,7 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase $processExecutor->expects($this->at(1)) ->method('execute') - ->with($this->equalTo($this->getCmd("git checkout 'ref' && git reset --hard 'ref'")), $this->equalTo(null), $this->equalTo('composerPath')) + ->with($this->equalTo($this->getCmd("git checkout '1234567890123456789012345678901234567890' && git reset --hard '1234567890123456789012345678901234567890'")), $this->equalTo(null), $this->equalTo('composerPath')) ->will($this->returnValue(0)); $downloader = $this->getDownloaderMock(null, $processExecutor); @@ -74,6 +77,9 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase $packageMock->expects($this->any()) ->method('getSourceUrl') ->will($this->returnValue('https://github.com/composer/composer')); + $packageMock->expects($this->any()) + ->method('getPrettyVersion') + ->will($this->returnValue('1.0.0')); $processExecutor = $this->getMock('Composer\Util\ProcessExecutor'); $expectedGitCommand = $this->getCmd("git clone 'git://github.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'git://github.com/composer/composer' && git fetch composer"); @@ -101,6 +107,11 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(0)); $processExecutor->expects($this->at(6)) + ->method('execute') + ->with($this->equalTo('git branch -r')) + ->will($this->returnValue(0)); + + $processExecutor->expects($this->at(7)) ->method('execute') ->with($this->equalTo($this->getCmd("git checkout 'ref' && git reset --hard 'ref'")), $this->equalTo(null), $this->equalTo('composerPath')) ->will($this->returnValue(0)); @@ -159,6 +170,9 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase $packageMock->expects($this->any()) ->method('getSourceUrl') ->will($this->returnValue('https://github.com/composer/composer')); + $packageMock->expects($this->any()) + ->method('getPrettyVersion') + ->will($this->returnValue('1.0.0')); $processExecutor = $this->getMock('Composer\Util\ProcessExecutor'); $processExecutor->expects($this->at(0)) ->method('execute') @@ -173,6 +187,10 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase ->with($this->equalTo($expectedGitUpdateCommand)) ->will($this->returnValue(0)); $processExecutor->expects($this->at(3)) + ->method('execute') + ->with($this->equalTo('git branch -r')) + ->will($this->returnValue(0)); + $processExecutor->expects($this->at(4)) ->method('execute') ->with($this->equalTo($this->getCmd("git checkout 'ref' && git reset --hard 'ref'")), $this->equalTo(null), $this->equalTo('composerPath')) ->will($this->returnValue(0));