diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index 65936b242..af3cb75c9 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -55,12 +55,14 @@ 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 { - $this->gitUtil->lazySyncMirror($url, $cachePath, $ref); + $cached = $this->gitUtil->fetchRef($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) { diff --git a/src/Composer/Util/Git.php b/src/Composer/Util/Git.php index 93351964b..fcc83f9f2 100644 --- a/src/Composer/Util/Git.php +++ b/src/Composer/Util/Git.php @@ -228,20 +228,34 @@ class Git return true; } - public function lazySyncMirror($url, $dir, $ref) + public function fetchRef($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; + $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) { } } - return $this->syncMirror($url, $dir); + $this->syncMirror($url, $dir); + return false; } private function isAuthenticationFailure($url, &$match)