Skip to content

Commit

Permalink
Attempt to use shallow clones, fixes composer#3449
Browse files Browse the repository at this point in the history
  • Loading branch information
Seldaek authored and oxyc committed Jun 5, 2016
1 parent a8bb93a commit 60d4e8a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
25 changes: 16 additions & 9 deletions src/Composer/Downloader/GitDownloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ public function doDownload(PackageInterface $package, $path, $url)

$ref = $package->getSourceReference();
$flag = Platform::isWindows() ? '/D ' : '';
$command = 'git clone --no-checkout %s %s && cd '.$flag.'%2$s && git remote add composer %1$s && git fetch composer';
$command = '(git clone --no-checkout --depth 1 --single-branch %s %s --branch %s || git clone --no-checkout %1$s %2$s)'.
' && cd '.$flag.'%2$s && git remote add composer %1$s && (git fetch composer %3$s || git fetch composer)';
$this->io->writeError(" Cloning ".$ref);

$commandCallable = function ($url) use ($ref, $path, $command) {
return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($path), ProcessExecutor::escape($ref));
$branch = $this->guessBranchName($package);
$commandCallable = function ($url) use ($ref, $path, $command, $branch) {
return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($path), ProcessExecutor::escape($branch));
};

$this->gitUtil->runCommand($commandCallable, $url, $path, true);
Expand All @@ -59,7 +61,7 @@ public function doDownload(PackageInterface $package, $path, $url)
$this->setPushUrl($path, $url);
}

if ($newRef = $this->updateToCommit($path, $ref, $package->getPrettyVersion(), $package->getReleaseDate())) {
if ($newRef = $this->updateToCommit($path, $ref, $branch, $package->getReleaseDate())) {
if ($package->getDistReference() === $package->getSourceReference()) {
$package->setDistReference($newRef);
}
Expand Down Expand Up @@ -90,14 +92,15 @@ public function doUpdate(PackageInterface $initial, PackageInterface $target, $p

$ref = $target->getSourceReference();
$this->io->writeError(" Checking out ".$ref);
$command = 'git remote set-url composer %s && git fetch composer && git fetch --tags composer';
$command = 'git remote set-url composer %s && (git fetch composer %s || git fetch composer) && git fetch --tags composer';
$branch = $this->guessBranchName($target);

$commandCallable = function ($url) use ($command) {
return sprintf($command, ProcessExecutor::escape($url));
$commandCallable = function ($url) use ($command, $branch) {
return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($branch));
};

$this->gitUtil->runCommand($commandCallable, $url, $path);
if ($newRef = $this->updateToCommit($path, $ref, $target->getPrettyVersion(), $target->getReleaseDate())) {
if ($newRef = $this->updateToCommit($path, $ref, $branch, $target->getReleaseDate())) {
if ($target->getDistReference() === $target->getSourceReference()) {
$target->setDistReference($newRef);
}
Expand Down Expand Up @@ -318,7 +321,6 @@ protected function updateToCommit($path, $reference, $branch, $date)
// 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)) {
Expand Down Expand Up @@ -476,4 +478,9 @@ protected function hasMetadataRepository($path)

return is_dir($path.'/.git');
}

private function guessBranchName(PackageInterface $package)
{
return preg_replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $package->getPrettyVersion());;
}
}
38 changes: 36 additions & 2 deletions tests/Composer/Test/Downloader/GitDownloaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public function testDownload()
->will($this->returnValue('dev-master'));
$processExecutor = $this->getMock('Composer\Util\ProcessExecutor');

$expectedGitCommand = $this->winCompat("git clone --no-checkout 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'https://example.com/composer/composer' && git fetch composer");
$expectedGitCommand = $this->winCompat("(git clone --no-checkout --depth 1 --single-branch 'https://example.com/composer/composer' 'composerPath' --branch 'master' || git clone --no-checkout 'https://example.com/composer/composer' 'composerPath') && cd 'composerPath' && git remote add composer 'https://example.com/composer/composer' && (git fetch composer 'master' || git fetch composer)");
$processExecutor->expects($this->at(0))
->method('execute')
->with($this->equalTo($expectedGitCommand))
Expand Down Expand Up @@ -123,18 +123,26 @@ public function testDownloadUsesVariousProtocolsAndSetsPushUrlForGithub()
->will($this->returnValue('1.0.0'));
$processExecutor = $this->getMock('Composer\Util\ProcessExecutor');

<<<<<<< a8bb93aa1f632610e1e6b9fbb0865e0a8993fce9
$expectedGitCommand = $this->winCompat("git clone --no-checkout 'https://github.com/mirrors/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'https://github.com/mirrors/composer' && git fetch composer");
=======
$expectedGitCommand = $this->winCompat("(git clone --no-checkout --depth 1 --single-branch 'git://github.com/mirrors/composer' 'composerPath' --branch '1.0.0' || git clone --no-checkout 'git://github.com/mirrors/composer' 'composerPath') && cd 'composerPath' && git remote add composer 'git://github.com/mirrors/composer' && (git fetch composer '1.0.0' || git fetch composer)");
>>>>>>> Attempt to use shallow clones, fixes #3449
$processExecutor->expects($this->at(0))
->method('execute')
->with($this->equalTo($expectedGitCommand))
->will($this->returnValue(1));
<<<<<<< a8bb93aa1f632610e1e6b9fbb0865e0a8993fce9
$processExecutor->expects($this->at(1))
->method('getErrorOutput')
->with()
->will($this->returnValue('Error1'));

$expectedGitCommand = $this->winCompat("git clone --no-checkout 'git@github.com:mirrors/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'git@github.com:mirrors/composer' && git fetch composer");
=======
$expectedGitCommand = $this->winCompat("(git clone --no-checkout --depth 1 --single-branch 'https://github.com/mirrors/composer' 'composerPath' --branch '1.0.0' || git clone --no-checkout 'https://github.com/mirrors/composer' 'composerPath') && cd 'composerPath' && git remote add composer 'https://github.com/mirrors/composer' && (git fetch composer '1.0.0' || git fetch composer)");
>>>>>>> Attempt to use shallow clones, fixes #3449
$processExecutor->expects($this->at(2))
->method('execute')
->with($this->equalTo($expectedGitCommand))
Expand Down Expand Up @@ -198,7 +206,11 @@ public function testDownloadAndSetPushUrlUseCustomVariousProtocolsForGithub($pro
->will($this->returnValue('1.0.0'));
$processExecutor = $this->getMock('Composer\Util\ProcessExecutor');

<<<<<<< a8bb93aa1f632610e1e6b9fbb0865e0a8993fce9
$expectedGitCommand = $this->winCompat("git clone --no-checkout '{$url}' 'composerPath' && cd 'composerPath' && git remote add composer '{$url}' && git fetch composer");
=======
$expectedGitCommand = $this->winCompat("(git clone --no-checkout --depth 1 --single-branch '{$protocol}://github.com/composer/composer' 'composerPath' --branch '1.0.0' || git clone --no-checkout '{$protocol}://github.com/composer/composer' 'composerPath') && cd 'composerPath' && git remote add composer '{$protocol}://github.com/composer/composer' && (git fetch composer '1.0.0' || git fetch composer)");
>>>>>>> Attempt to use shallow clones, fixes #3449
$processExecutor->expects($this->at(0))
->method('execute')
->with($this->equalTo($expectedGitCommand))
Expand Down Expand Up @@ -226,14 +238,17 @@ public function testDownloadAndSetPushUrlUseCustomVariousProtocolsForGithub($pro
*/
public function testDownloadThrowsRuntimeExceptionIfGitCommandFails()
{
$expectedGitCommand = $this->winCompat("git clone --no-checkout 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'https://example.com/composer/composer' && git fetch composer");
$expectedGitCommand = $this->winCompat("(git clone --no-checkout --depth 1 --single-branch 'https://example.com/composer/composer' 'composerPath' --branch '1.0.0' || git clone --no-checkout 'https://example.com/composer/composer' 'composerPath') && cd 'composerPath' && git remote add composer 'https://example.com/composer/composer' && (git fetch composer '1.0.0' || git fetch composer)");
$packageMock = $this->getMock('Composer\Package\PackageInterface');
$packageMock->expects($this->any())
->method('getSourceReference')
->will($this->returnValue('ref'));
$packageMock->expects($this->any())
->method('getSourceUrls')
->will($this->returnValue(array('https://example.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')
Expand Down Expand Up @@ -261,7 +276,11 @@ public function testUpdateforPackageWithoutSourceReference()
public function testUpdate()
{
<<<<<<< a8bb93aa1f632610e1e6b9fbb0865e0a8993fce9
$expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git fetch composer && git fetch --tags composer");
=======
$expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'git://github.com/composer/composer' && (git fetch composer '1.0.0' || git fetch composer) && git fetch --tags composer");
>>>>>>> Attempt to use shallow clones, fixes #3449

$packageMock = $this->getMock('Composer\Package\PackageInterface');
$packageMock->expects($this->any())
Expand Down Expand Up @@ -381,7 +400,11 @@ public function testUpdateWithNewRepoUrl()
*/
public function testUpdateThrowsRuntimeExceptionIfGitCommandFails()
{
<<<<<<< a8bb93aa1f632610e1e6b9fbb0865e0a8993fce9
$expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git fetch composer && git fetch --tags composer");
=======
$expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'git://github.com/composer/composer' && (git fetch composer '1.0.0' || git fetch composer) && git fetch --tags composer");
>>>>>>> Attempt to use shallow clones, fixes #3449
$packageMock = $this->getMock('Composer\Package\PackageInterface');
$packageMock->expects($this->any())
Expand All @@ -390,6 +413,9 @@ public function testUpdateThrowsRuntimeExceptionIfGitCommandFails()
$packageMock->expects($this->any())
->method('getSourceUrls')
->will($this->returnValue(array('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')
Expand Down Expand Up @@ -419,8 +445,13 @@ public function testUpdateThrowsRuntimeExceptionIfGitCommandFails()
public function testUpdateDoesntThrowsRuntimeExceptionIfGitCommandFailsAtFirstButIsAbleToRecover()
{
<<<<<<< a8bb93aa1f632610e1e6b9fbb0865e0a8993fce9
$expectedFirstGitUpdateCommand = $this->winCompat("git remote set-url composer '' && git fetch composer && git fetch --tags composer");
$expectedSecondGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git fetch composer && git fetch --tags composer");
=======
$expectedFirstGitUpdateCommand = $this->winCompat("git remote set-url composer '' && (git fetch composer '1.0.0' || git fetch composer) && git fetch --tags composer");
$expectedSecondGitUpdateCommand = $this->winCompat("git remote set-url composer 'git://github.com/composer/composer' && (git fetch composer '1.0.0' || git fetch composer) && git fetch --tags composer");
>>>>>>> Attempt to use shallow clones, fixes #3449

$packageMock = $this->getMock('Composer\Package\PackageInterface');
$packageMock->expects($this->any())
Expand All @@ -429,6 +460,9 @@ public function testUpdateDoesntThrowsRuntimeExceptionIfGitCommandFailsAtFirstBu
$packageMock->expects($this->any())
->method('getSourceUrls')
->will($this->returnValue(array('/foo/bar', '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')
Expand Down

0 comments on commit 60d4e8a

Please sign in to comment.