diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index af3cb75c9..626676894 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -55,14 +55,12 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface $this->io->writeError('', true, IOInterface::DEBUG); $this->io->writeError(sprintf(' Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG); try { - $cached = $this->gitUtil->fetchRef($url, $cachePath, $ref); + $this->gitUtil->fetchRefOrSyncMirror($url, $cachePath, $ref); if (is_dir($cachePath)) { $command = 'git clone --no-checkout %cachePath% %path% --dissociate --reference %cachePath% ' . '&& cd '.$flag.'%path% ' . '&& git remote set-url origin %url% && git remote add composer %url%'; - if (!$cached) - $command .= ' && git fetch composer'; $msg = "Cloning ".$this->getShortHash($ref).' from cache'; } } catch (\RuntimeException $e) { @@ -120,10 +118,10 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface $ref = $target->getSourceReference(); $this->io->writeError(" Checking out ".$this->getShortHash($ref)); - $command = 'git remote set-url composer %s && git rev-parse --quiet --verify %s^{commit} || (git fetch composer && git fetch --tags composer)'; + $command = 'git remote set-url composer %s && git rev-parse --quiet --verify %s || (git fetch composer && git fetch --tags composer)'; $commandCallable = function ($url) use ($command, $ref) { - return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($ref)); + return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($ref.'^{commit}')); }; $this->gitUtil->runCommand($commandCallable, $url, $path); diff --git a/src/Composer/Util/Git.php b/src/Composer/Util/Git.php index fcc83f9f2..e4d6bd803 100644 --- a/src/Composer/Util/Git.php +++ b/src/Composer/Util/Git.php @@ -228,33 +228,18 @@ class Git return true; } - public function fetchRef($url, $dir, $ref) + public function fetchRefOrSyncMirror($url, $dir, $ref) { if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') { - try { - $isTag = $isRef = $actualCommit = false; - $escapedRef = ProcessExecutor::escape($ref); - $exitCode = $this->process->execute(sprintf('git show-ref --tags %s', $escapedRef), $output, $dir); - if (!$exitCode) - $isTag = true; - $exitCode = $this->process->execute(sprintf('git show-ref %s', $escapedRef), $output, $dir); - if (!$exitCode) - $isRef = true; - $exitCode = $this->process->execute(sprintf('git cat-file -t %s', $escapedRef), $output, $dir); - if (!$exitCode && trim($output) == "commit") - $actualCommit = true; - - if ($isTag){ - return true; - } - if (!$isRef && $actualCommit) { - return true; - } - } catch (\Exception $e) { + $escapedRef = ProcessExecutor::escape($ref.'^{commit}'); + $exitCode = $this->process->execute(sprintf('git rev-parse --quiet --verify %s', $escapedRef), $output, $dir); + if ($exitCode === 0) { + return true; } } $this->syncMirror($url, $dir); + return false; } diff --git a/tests/Composer/Test/Downloader/GitDownloaderTest.php b/tests/Composer/Test/Downloader/GitDownloaderTest.php index f5aa4fe9e..20e609712 100644 --- a/tests/Composer/Test/Downloader/GitDownloaderTest.php +++ b/tests/Composer/Test/Downloader/GitDownloaderTest.php @@ -173,7 +173,7 @@ class GitDownloaderTest extends TestCase return 0; })); - $expectedGitCommand = $this->winCompat(sprintf("git clone --no-checkout '%1\$s' 'composerPath' --dissociate --reference '%1\$s' && cd 'composerPath' && git remote set-url origin 'https://example.com/composer/composer' && git remote add composer 'https://example.com/composer/composer' && git fetch composer", $cachePath)); + $expectedGitCommand = $this->winCompat(sprintf("git clone --no-checkout '%1\$s' 'composerPath' --dissociate --reference '%1\$s' && cd 'composerPath' && git remote set-url origin 'https://example.com/composer/composer' && git remote add composer 'https://example.com/composer/composer'", $cachePath)); $processExecutor->expects($this->at(2)) ->method('execute') ->with($this->equalTo($expectedGitCommand)) @@ -380,7 +380,7 @@ class GitDownloaderTest extends TestCase public function testUpdate() { - $expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git rev-parse --quiet --verify 'ref'^{commit} || (git fetch composer && git fetch --tags composer)"); + $expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git rev-parse --quiet --verify 'ref^{commit}' || (git fetch composer && git fetch --tags composer)"); $packageMock = $this->getMock('Composer\Package\PackageInterface'); $packageMock->expects($this->any()) @@ -429,7 +429,7 @@ class GitDownloaderTest extends TestCase public function testUpdateWithNewRepoUrl() { - $expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git rev-parse --quiet --verify 'ref'^{commit} || (git fetch composer && git fetch --tags composer)"); + $expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git rev-parse --quiet --verify 'ref^{commit}' || (git fetch composer && git fetch --tags composer)"); $packageMock = $this->getMock('Composer\Package\PackageInterface'); $packageMock->expects($this->any()) @@ -501,7 +501,7 @@ composer https://github.com/old/url (push) */ public function testUpdateThrowsRuntimeExceptionIfGitCommandFails() { - $expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git rev-parse --quiet --verify 'ref'^{commit} || (git fetch composer && git fetch --tags composer)"); + $expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git rev-parse --quiet --verify 'ref^{commit}' || (git fetch composer && git fetch --tags composer)"); $packageMock = $this->getMock('Composer\Package\PackageInterface'); $packageMock->expects($this->any()) @@ -539,8 +539,8 @@ composer https://github.com/old/url (push) public function testUpdateDoesntThrowsRuntimeExceptionIfGitCommandFailsAtFirstButIsAbleToRecover() { - $expectedFirstGitUpdateCommand = $this->winCompat("git remote set-url composer '' && git rev-parse --quiet --verify 'ref'^{commit} || (git fetch composer && git fetch --tags composer)"); - $expectedSecondGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git rev-parse --quiet --verify 'ref'^{commit} || (git fetch composer && git fetch --tags composer)"); + $expectedFirstGitUpdateCommand = $this->winCompat("git remote set-url composer '' && git rev-parse --quiet --verify 'ref^{commit}' || (git fetch composer && git fetch --tags composer)"); + $expectedSecondGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git rev-parse --quiet --verify 'ref^{commit}' || (git fetch composer && git fetch --tags composer)"); $packageMock = $this->getMock('Composer\Package\PackageInterface'); $packageMock->expects($this->any())