From 0ad985122df53b26b72df99ac7437b2721213188 Mon Sep 17 00:00:00 2001 From: Robert Lu Date: Wed, 13 Sep 2017 19:50:02 +0800 Subject: [PATCH] Don't fetch when ref already on local --- src/Composer/Downloader/GitDownloader.php | 29 ++++++++++++++++------- src/Composer/Util/Git.php | 16 +++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index 5cd69d5e4..65936b242 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -12,13 +12,13 @@ namespace Composer\Downloader; +use Composer\Config; +use Composer\IO\IOInterface; use Composer\Package\PackageInterface; +use Composer\Util\Filesystem; use Composer\Util\Git as GitUtil; use Composer\Util\Platform; use Composer\Util\ProcessExecutor; -use Composer\IO\IOInterface; -use Composer\Util\Filesystem; -use Composer\Config; /** * @author Jordi Boggiano @@ -43,30 +43,41 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface GitUtil::cleanEnv(); $path = $this->normalizePath($path); $cachePath = $this->config->get('cache-vcs-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $url).'/'; - $cacheOptions = ''; $ref = $package->getSourceReference(); $flag = Platform::isWindows() ? '/D ' : ''; // --dissociate option is only available since git 2.3.0-rc0 $gitVersion = $this->gitUtil->getVersion(); $msg = "Cloning ".$this->getShortHash($ref); + + $command = 'git clone --no-checkout %url% %path% && cd '.$flag.'%path% && git remote add composer %url% && git fetch composer'; if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=')) { $this->io->writeError('', true, IOInterface::DEBUG); $this->io->writeError(sprintf(' Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG); try { - $this->gitUtil->syncMirror($url, $cachePath); + $this->gitUtil->lazySyncMirror($url, $cachePath, $ref); if (is_dir($cachePath)) { - $cacheOptions = sprintf('--dissociate --reference %s ', ProcessExecutor::escape($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%'; $msg = "Cloning ".$this->getShortHash($ref).' from cache'; } } catch (\RuntimeException $e) { } } - $command = 'git clone --no-checkout %s %s '.$cacheOptions.'&& cd '.$flag.'%2$s && git remote add composer %1$s && git fetch composer'; $this->io->writeError($msg); - $commandCallable = function ($url) use ($ref, $path, $command) { - return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($path), ProcessExecutor::escape($ref)); + $commandCallable = function ($url) use ($path, $command, $cachePath) { + return str_replace( + array('%url%', '%path%', '%cachePath%'), + array( + ProcessExecutor::escape($url), + ProcessExecutor::escape($path), + ProcessExecutor::escape($cachePath), + ), + $command + ); }; $this->gitUtil->runCommand($commandCallable, $url, $path, true); diff --git a/src/Composer/Util/Git.php b/src/Composer/Util/Git.php index a6e199bc9..93351964b 100644 --- a/src/Composer/Util/Git.php +++ b/src/Composer/Util/Git.php @@ -228,6 +228,22 @@ class Git return true; } + public function lazySyncMirror($url, $dir, $ref) + { + if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') { + try { + $commandCallable = function ($ref) { + return sprintf('git cat-file -t %s', ProcessExecutor::escape($ref)); + }; + $this->runCommand($commandCallable, $ref, $dir); + return true; + } catch (\Exception $e) { + } + } + + return $this->syncMirror($url, $dir); + } + private function isAuthenticationFailure($url, &$match) { if (!preg_match('{(https?://)([^/]+)(.*)$}i', $url, $match)) {