diff --git a/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md b/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md index c2c5d9ba3..8e50f7264 100644 --- a/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md +++ b/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md @@ -16,14 +16,16 @@ problems: submodules. This is problematic because they are not real submodules, and you will run into issues. -If you really feel like you must do this, you have three options: +If you really feel like you must do this, you have a few options: 1. Limit yourself to installing tagged releases (no dev versions), so that you - only get zipped installs, and avoid problems with the git "submodules". -2. Remove the `.git` directory of every dependency after the installation, then - you can add them to your git repo. You can do that with `rm -rf vendor/**/.git` - but this means you will have to delete those dependencies from disk before - running composer update. -3. Add a .gitignore rule (`vendor/.git`) to ignore all the vendor `.git` folders. - This approach does not require that you delete dependencies from disk prior to - running a composer update. + only get zipped installs, and avoid problems with the git "submodules". +2. Use --prefer-dist or set `preferred-install` to `dist` in your + [config](../04-schema.md#config). +3. Remove the `.git` directory of every dependency after the installation, then + you can add them to your git repo. You can do that with `rm -rf vendor/**/.git` + but this means you will have to delete those dependencies from disk before + running composer update. +4. Add a .gitignore rule (`vendor/.git`) to ignore all the vendor `.git` folders. + This approach does not require that you delete dependencies from disk prior to + running a composer update. diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index f59c6a68b..edc55bc3b 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -53,6 +53,9 @@ class GitDownloader extends VcsDownloader { $this->cleanEnv(); $path = $this->normalizePath($path); + if (!is_dir($path.'/.git')) { + throw new \RuntimeException('The .git directory is missing from '.$path.', see http://getcomposer.org/commit-deps for more information'); + } $ref = $target->getSourceReference(); $this->io->write(" Checking out ".$ref); diff --git a/src/Composer/Downloader/HgDownloader.php b/src/Composer/Downloader/HgDownloader.php index b3d0dd5ea..a3fc7da76 100644 --- a/src/Composer/Downloader/HgDownloader.php +++ b/src/Composer/Downloader/HgDownloader.php @@ -45,6 +45,11 @@ class HgDownloader extends VcsDownloader $url = escapeshellarg($target->getSourceUrl()); $ref = escapeshellarg($target->getSourceReference()); $this->io->write(" Updating to ".$target->getSourceReference()); + + if (!is_dir($path.'/.hg')) { + throw new \RuntimeException('The .hg directory is missing from '.$path.', see http://getcomposer.org/commit-deps for more information'); + } + $command = sprintf('hg pull %s && hg up %s', $url, $ref); if (0 !== $this->process->execute($command, $ignoredOutput, $path)) { throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); diff --git a/src/Composer/Downloader/SvnDownloader.php b/src/Composer/Downloader/SvnDownloader.php index 5f47c7b5f..2e894908a 100644 --- a/src/Composer/Downloader/SvnDownloader.php +++ b/src/Composer/Downloader/SvnDownloader.php @@ -41,6 +41,10 @@ class SvnDownloader extends VcsDownloader $url = $target->getSourceUrl(); $ref = $target->getSourceReference(); + if (!is_dir($path.'/.svn')) { + throw new \RuntimeException('The .svn directory is missing from '.$path.', see http://getcomposer.org/commit-deps for more information'); + } + $this->io->write(" Checking out " . $ref); $this->execute($url, "svn switch", sprintf("%s/%s", $url, $ref), $path); } diff --git a/tests/Composer/Test/Downloader/GitDownloaderTest.php b/tests/Composer/Test/Downloader/GitDownloaderTest.php index 57e823223..f3a31ba74 100644 --- a/tests/Composer/Test/Downloader/GitDownloaderTest.php +++ b/tests/Composer/Test/Downloader/GitDownloaderTest.php @@ -221,6 +221,10 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase { $expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'git://github.com/composer/composer' && git fetch composer && git fetch --tags composer"); + $tmpDir = sys_get_temp_dir().DIRECTORY_SEPARATOR.'test-git-update'; + if (!is_dir($tmpDir.'/.git')) { + mkdir($tmpDir.'/.git', true, 0777); + } $packageMock = $this->getMock('Composer\Package\PackageInterface'); $packageMock->expects($this->any()) ->method('getSourceReference') @@ -234,23 +238,27 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase $processExecutor = $this->getMock('Composer\Util\ProcessExecutor'); $processExecutor->expects($this->at(0)) ->method('execute') - ->with($this->equalTo($this->winCompat("git remote -v"))) + ->with($this->equalTo($this->winCompat("git status --porcelain --untracked-files=no"))) ->will($this->returnValue(0)); $processExecutor->expects($this->at(1)) ->method('execute') - ->with($this->equalTo($expectedGitUpdateCommand)) + ->with($this->equalTo($this->winCompat("git remote -v"))) ->will($this->returnValue(0)); $processExecutor->expects($this->at(2)) ->method('execute') - ->with($this->equalTo('git branch -r')) + ->with($this->equalTo($expectedGitUpdateCommand)) ->will($this->returnValue(0)); $processExecutor->expects($this->at(3)) ->method('execute') - ->with($this->equalTo($this->winCompat("git checkout 'ref' && git reset --hard 'ref'")), $this->equalTo(null), $this->equalTo($this->winCompat('composerPath'))) + ->with($this->equalTo('git branch -r')) + ->will($this->returnValue(0)); + $processExecutor->expects($this->at(4)) + ->method('execute') + ->with($this->equalTo($this->winCompat("git checkout 'ref' && git reset --hard 'ref'")), $this->equalTo(null), $this->equalTo($this->winCompat($tmpDir))) ->will($this->returnValue(0)); $downloader = $this->getDownloaderMock(null, new Config(), $processExecutor); - $downloader->update($packageMock, $packageMock, 'composerPath'); + $downloader->update($packageMock, $packageMock, $tmpDir); } /** @@ -260,6 +268,10 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase { $expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'git://github.com/composer/composer' && git fetch composer && git fetch --tags composer"); + $tmpDir = sys_get_temp_dir().DIRECTORY_SEPARATOR.'test-git-update'; + if (!is_dir($tmpDir.'/.git')) { + mkdir($tmpDir.'/.git', true, 0777); + } $packageMock = $this->getMock('Composer\Package\PackageInterface'); $packageMock->expects($this->any()) ->method('getSourceReference') @@ -270,15 +282,19 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase $processExecutor = $this->getMock('Composer\Util\ProcessExecutor'); $processExecutor->expects($this->at(0)) ->method('execute') - ->with($this->equalTo($this->winCompat("git remote -v"))) + ->with($this->equalTo($this->winCompat("git status --porcelain --untracked-files=no"))) ->will($this->returnValue(0)); $processExecutor->expects($this->at(1)) + ->method('execute') + ->with($this->equalTo($this->winCompat("git remote -v"))) + ->will($this->returnValue(0)); + $processExecutor->expects($this->at(2)) ->method('execute') ->with($this->equalTo($expectedGitUpdateCommand)) ->will($this->returnValue(1)); $downloader = $this->getDownloaderMock(null, new Config(), $processExecutor); - $downloader->update($packageMock, $packageMock, 'composerPath'); + $downloader->update($packageMock, $packageMock, $tmpDir); } public function testRemove() diff --git a/tests/Composer/Test/Downloader/HgDownloaderTest.php b/tests/Composer/Test/Downloader/HgDownloaderTest.php index b4e826999..69a65c2e3 100644 --- a/tests/Composer/Test/Downloader/HgDownloaderTest.php +++ b/tests/Composer/Test/Downloader/HgDownloaderTest.php @@ -84,6 +84,11 @@ class HgDownloaderTest extends \PHPUnit_Framework_TestCase public function testUpdate() { + $tmpDir = sys_get_temp_dir().'/test-hg-update'; + if (!is_dir($tmpDir.'/.hg')) { + mkdir($tmpDir.'/.hg', true, 0777); + } + $packageMock = $this->getMock('Composer\Package\PackageInterface'); $packageMock->expects($this->any()) ->method('getSourceReference') @@ -93,14 +98,19 @@ class HgDownloaderTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue('https://github.com/l3l0/composer')); $processExecutor = $this->getMock('Composer\Util\ProcessExecutor'); - $expectedGitCommand = $this->getCmd("hg pull 'https://github.com/l3l0/composer' && hg up 'ref'"); + $expectedHgCommand = $this->getCmd("hg st"); $processExecutor->expects($this->at(0)) ->method('execute') - ->with($this->equalTo($expectedGitCommand)) + ->with($this->equalTo($expectedHgCommand)) + ->will($this->returnValue(0)); + $expectedHgCommand = $this->getCmd("hg pull 'https://github.com/l3l0/composer' && hg up 'ref'"); + $processExecutor->expects($this->at(1)) + ->method('execute') + ->with($this->equalTo($expectedHgCommand)) ->will($this->returnValue(0)); $downloader = $this->getDownloaderMock(null, null, $processExecutor); - $downloader->update($packageMock, $packageMock, 'composerPath'); + $downloader->update($packageMock, $packageMock, $tmpDir); } public function testRemove()